mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Blind update of zip code to newest RVWorld version
This commit is contained in:
152
SabreTools.Library/External/Compress/SevenZip/Common/ICoder.cs
vendored
Normal file
152
SabreTools.Library/External/Compress/SevenZip/Common/ICoder.cs
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
|
||||
namespace Compress.SevenZip.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// The exception that is thrown when an error in input stream occurs during decoding.
|
||||
/// </summary>
|
||||
public class DataErrorException : Exception
|
||||
{
|
||||
public DataErrorException() : base("Data Error") { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exception that is thrown when the value of an argument is outside the allowable range.
|
||||
/// </summary>
|
||||
internal class InvalidParamException : Exception
|
||||
{
|
||||
public InvalidParamException() : base("Invalid Parameter") { }
|
||||
}
|
||||
|
||||
public interface ICodeProgress
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback progress.
|
||||
/// </summary>
|
||||
/// <param name="inSize">
|
||||
/// input size. -1 if unknown.
|
||||
/// </param>
|
||||
/// <param name="outSize">
|
||||
/// output size. -1 if unknown.
|
||||
/// </param>
|
||||
void SetProgress(Int64 inSize, Int64 outSize);
|
||||
};
|
||||
|
||||
internal interface ICoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Codes streams.
|
||||
/// </summary>
|
||||
/// <param name="inStream">
|
||||
/// input Stream.
|
||||
/// </param>
|
||||
/// <param name="outStream">
|
||||
/// output Stream.
|
||||
/// </param>
|
||||
/// <param name="inSize">
|
||||
/// input Size. -1 if unknown.
|
||||
/// </param>
|
||||
/// <param name="outSize">
|
||||
/// output Size. -1 if unknown.
|
||||
/// </param>
|
||||
/// <param name="progress">
|
||||
/// callback progress reference.
|
||||
/// </param>
|
||||
void Code(System.IO.Stream inStream, System.IO.Stream outStream,
|
||||
Int64 inSize, Int64 outSize, ICodeProgress progress);
|
||||
};
|
||||
|
||||
/*
|
||||
public interface ICoder2
|
||||
{
|
||||
void Code(ISequentialInStream []inStreams,
|
||||
const UInt64 []inSizes,
|
||||
ISequentialOutStream []outStreams,
|
||||
UInt64 []outSizes,
|
||||
ICodeProgress progress);
|
||||
};
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Provides the fields that represent properties idenitifiers for compressing.
|
||||
/// </summary>
|
||||
internal enum CoderPropID
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies default property.
|
||||
/// </summary>
|
||||
DefaultProp = 0,
|
||||
/// <summary>
|
||||
/// Specifies size of dictionary.
|
||||
/// </summary>
|
||||
DictionarySize,
|
||||
/// <summary>
|
||||
/// Specifies size of memory for PPM*.
|
||||
/// </summary>
|
||||
UsedMemorySize,
|
||||
/// <summary>
|
||||
/// Specifies order for PPM methods.
|
||||
/// </summary>
|
||||
Order,
|
||||
/// <summary>
|
||||
/// Specifies Block Size.
|
||||
/// </summary>
|
||||
BlockSize,
|
||||
/// <summary>
|
||||
/// Specifies number of postion state bits for LZMA (0 - x - 4).
|
||||
/// </summary>
|
||||
PosStateBits,
|
||||
/// <summary>
|
||||
/// Specifies number of literal context bits for LZMA (0 - x - 8).
|
||||
/// </summary>
|
||||
LitContextBits,
|
||||
/// <summary>
|
||||
/// Specifies number of literal position bits for LZMA (0 - x - 4).
|
||||
/// </summary>
|
||||
LitPosBits,
|
||||
/// <summary>
|
||||
/// Specifies number of fast bytes for LZ*.
|
||||
/// </summary>
|
||||
NumFastBytes,
|
||||
/// <summary>
|
||||
/// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
|
||||
/// </summary>
|
||||
MatchFinder,
|
||||
/// <summary>
|
||||
/// Specifies the number of match finder cyckes.
|
||||
/// </summary>
|
||||
MatchFinderCycles,
|
||||
/// <summary>
|
||||
/// Specifies number of passes.
|
||||
/// </summary>
|
||||
NumPasses,
|
||||
/// <summary>
|
||||
/// Specifies number of algorithm.
|
||||
/// </summary>
|
||||
Algorithm,
|
||||
/// <summary>
|
||||
/// Specifies the number of threads.
|
||||
/// </summary>
|
||||
NumThreads,
|
||||
/// <summary>
|
||||
/// Specifies mode with end marker.
|
||||
/// </summary>
|
||||
EndMarker
|
||||
};
|
||||
|
||||
|
||||
internal interface ISetCoderProperties
|
||||
{
|
||||
void SetCoderProperties(CoderPropID[] propIDs, object[] properties);
|
||||
};
|
||||
|
||||
internal interface IWriteCoderProperties
|
||||
{
|
||||
void WriteCoderProperties(System.IO.Stream outStream);
|
||||
}
|
||||
|
||||
internal interface ISetDecoderProperties
|
||||
{
|
||||
void SetDecoderProperties(byte[] properties);
|
||||
}
|
||||
}
|
||||
100
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/BZip2Constants.cs
vendored
Normal file
100
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/BZip2Constants.cs
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2001,2004-2005 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This package is based on the work done by Keiron Liddle, Aftex Software
|
||||
* <keiron@aftexsw.com> to whom the Ant project is very grateful for his
|
||||
* great code.
|
||||
*/
|
||||
|
||||
namespace Compress.SevenZip.Compress.BZip2
|
||||
{
|
||||
/**
|
||||
* Base class for both the compress and decompress classes.
|
||||
* Holds common arrays, and static data.
|
||||
*
|
||||
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
|
||||
*/
|
||||
internal class BZip2Constants
|
||||
{
|
||||
|
||||
public const int baseBlockSize = 100000;
|
||||
public const int MAX_ALPHA_SIZE = 258;
|
||||
public const int MAX_CODE_LEN = 23;
|
||||
public const int RUNA = 0;
|
||||
public const int RUNB = 1;
|
||||
public const int N_GROUPS = 6;
|
||||
public const int G_SIZE = 50;
|
||||
public const int N_ITERS = 4;
|
||||
public const int MAX_SELECTORS = (2 + (900000 / G_SIZE));
|
||||
public const int NUM_OVERSHOOT_BYTES = 20;
|
||||
|
||||
public static int[] rNums = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
}
|
||||
}
|
||||
1133
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/CBZip2InputStream.cs
vendored
Normal file
1133
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/CBZip2InputStream.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1985
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/CBZip2OutputStream.cs
vendored
Normal file
1985
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/CBZip2OutputStream.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
138
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/CRC.cs
vendored
Normal file
138
SabreTools.Library/External/Compress/SevenZip/Compress/BZip2/CRC.cs
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
|
||||
/*
|
||||
* Copyright 2001,2004-2005 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This package is based on the work done by Keiron Liddle), Aftex Software
|
||||
* <keiron@aftexsw.com> to whom the Ant project is very grateful for his
|
||||
* great code.
|
||||
*/
|
||||
|
||||
namespace Compress.SevenZip.Compress.BZip2
|
||||
{
|
||||
/**
|
||||
* A simple class the hold and calculate the CRC for sanity checking
|
||||
* of the data.
|
||||
*
|
||||
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
|
||||
*/
|
||||
internal class CRC
|
||||
{
|
||||
private static readonly int[] crc32Table = {
|
||||
unchecked((int)0x00000000), unchecked((int)0x04c11db7), unchecked((int)0x09823b6e), unchecked((int)0x0d4326d9),
|
||||
unchecked((int)0x130476dc), unchecked((int)0x17c56b6b), unchecked((int)0x1a864db2), unchecked((int)0x1e475005),
|
||||
unchecked((int)0x2608edb8), unchecked((int)0x22c9f00f), unchecked((int)0x2f8ad6d6), unchecked((int)0x2b4bcb61),
|
||||
unchecked((int)0x350c9b64), unchecked((int)0x31cd86d3), unchecked((int)0x3c8ea00a), unchecked((int)0x384fbdbd),
|
||||
unchecked((int)0x4c11db70), unchecked((int)0x48d0c6c7), unchecked((int)0x4593e01e), unchecked((int)0x4152fda9),
|
||||
unchecked((int)0x5f15adac), unchecked((int)0x5bd4b01b), unchecked((int)0x569796c2), unchecked((int)0x52568b75),
|
||||
unchecked((int)0x6a1936c8), unchecked((int)0x6ed82b7f), unchecked((int)0x639b0da6), unchecked((int)0x675a1011),
|
||||
unchecked((int)0x791d4014), unchecked((int)0x7ddc5da3), unchecked((int)0x709f7b7a), unchecked((int)0x745e66cd),
|
||||
unchecked((int)0x9823b6e0), unchecked((int)0x9ce2ab57), unchecked((int)0x91a18d8e), unchecked((int)0x95609039),
|
||||
unchecked((int)0x8b27c03c), unchecked((int)0x8fe6dd8b), unchecked((int)0x82a5fb52), unchecked((int)0x8664e6e5),
|
||||
unchecked((int)0xbe2b5b58), unchecked((int)0xbaea46ef), unchecked((int)0xb7a96036), unchecked((int)0xb3687d81),
|
||||
unchecked((int)0xad2f2d84), unchecked((int)0xa9ee3033), unchecked((int)0xa4ad16ea), unchecked((int)0xa06c0b5d),
|
||||
unchecked((int)0xd4326d90), unchecked((int)0xd0f37027), unchecked((int)0xddb056fe), unchecked((int)0xd9714b49),
|
||||
unchecked((int)0xc7361b4c), unchecked((int)0xc3f706fb), unchecked((int)0xceb42022), unchecked((int)0xca753d95),
|
||||
unchecked((int)0xf23a8028), unchecked((int)0xf6fb9d9f), unchecked((int)0xfbb8bb46), unchecked((int)0xff79a6f1),
|
||||
unchecked((int)0xe13ef6f4), unchecked((int)0xe5ffeb43), unchecked((int)0xe8bccd9a), unchecked((int)0xec7dd02d),
|
||||
unchecked((int)0x34867077), unchecked((int)0x30476dc0), unchecked((int)0x3d044b19), unchecked((int)0x39c556ae),
|
||||
unchecked((int)0x278206ab), unchecked((int)0x23431b1c), unchecked((int)0x2e003dc5), unchecked((int)0x2ac12072),
|
||||
unchecked((int)0x128e9dcf), unchecked((int)0x164f8078), unchecked((int)0x1b0ca6a1), unchecked((int)0x1fcdbb16),
|
||||
unchecked((int)0x018aeb13), unchecked((int)0x054bf6a4), unchecked((int)0x0808d07d), unchecked((int)0x0cc9cdca),
|
||||
unchecked((int)0x7897ab07), unchecked((int)0x7c56b6b0), unchecked((int)0x71159069), unchecked((int)0x75d48dde),
|
||||
unchecked((int)0x6b93dddb), unchecked((int)0x6f52c06c), unchecked((int)0x6211e6b5), unchecked((int)0x66d0fb02),
|
||||
unchecked((int)0x5e9f46bf), unchecked((int)0x5a5e5b08), unchecked((int)0x571d7dd1), unchecked((int)0x53dc6066),
|
||||
unchecked((int)0x4d9b3063), unchecked((int)0x495a2dd4), unchecked((int)0x44190b0d), unchecked((int)0x40d816ba),
|
||||
unchecked((int)0xaca5c697), unchecked((int)0xa864db20), unchecked((int)0xa527fdf9), unchecked((int)0xa1e6e04e),
|
||||
unchecked((int)0xbfa1b04b), unchecked((int)0xbb60adfc), unchecked((int)0xb6238b25), unchecked((int)0xb2e29692),
|
||||
unchecked((int)0x8aad2b2f), unchecked((int)0x8e6c3698), unchecked((int)0x832f1041), unchecked((int)0x87ee0df6),
|
||||
unchecked((int)0x99a95df3), unchecked((int)0x9d684044), unchecked((int)0x902b669d), unchecked((int)0x94ea7b2a),
|
||||
unchecked((int)0xe0b41de7), unchecked((int)0xe4750050), unchecked((int)0xe9362689), unchecked((int)0xedf73b3e),
|
||||
unchecked((int)0xf3b06b3b), unchecked((int)0xf771768c), unchecked((int)0xfa325055), unchecked((int)0xfef34de2),
|
||||
unchecked((int)0xc6bcf05f), unchecked((int)0xc27dede8), unchecked((int)0xcf3ecb31), unchecked((int)0xcbffd686),
|
||||
unchecked((int)0xd5b88683), unchecked((int)0xd1799b34), unchecked((int)0xdc3abded), unchecked((int)0xd8fba05a),
|
||||
unchecked((int)0x690ce0ee), unchecked((int)0x6dcdfd59), unchecked((int)0x608edb80), unchecked((int)0x644fc637),
|
||||
unchecked((int)0x7a089632), unchecked((int)0x7ec98b85), unchecked((int)0x738aad5c), unchecked((int)0x774bb0eb),
|
||||
unchecked((int)0x4f040d56), unchecked((int)0x4bc510e1), unchecked((int)0x46863638), unchecked((int)0x42472b8f),
|
||||
unchecked((int)0x5c007b8a), unchecked((int)0x58c1663d), unchecked((int)0x558240e4), unchecked((int)0x51435d53),
|
||||
unchecked((int)0x251d3b9e), unchecked((int)0x21dc2629), unchecked((int)0x2c9f00f0), unchecked((int)0x285e1d47),
|
||||
unchecked((int)0x36194d42), unchecked((int)0x32d850f5), unchecked((int)0x3f9b762c), unchecked((int)0x3b5a6b9b),
|
||||
unchecked((int)0x0315d626), unchecked((int)0x07d4cb91), unchecked((int)0x0a97ed48), unchecked((int)0x0e56f0ff),
|
||||
unchecked((int)0x1011a0fa), unchecked((int)0x14d0bd4d), unchecked((int)0x19939b94), unchecked((int)0x1d528623),
|
||||
unchecked((int)0xf12f560e), unchecked((int)0xf5ee4bb9), unchecked((int)0xf8ad6d60), unchecked((int)0xfc6c70d7),
|
||||
unchecked((int)0xe22b20d2), unchecked((int)0xe6ea3d65), unchecked((int)0xeba91bbc), unchecked((int)0xef68060b),
|
||||
unchecked((int)0xd727bbb6), unchecked((int)0xd3e6a601), unchecked((int)0xdea580d8), unchecked((int)0xda649d6f),
|
||||
unchecked((int)0xc423cd6a), unchecked((int)0xc0e2d0dd), unchecked((int)0xcda1f604), unchecked((int)0xc960ebb3),
|
||||
unchecked((int)0xbd3e8d7e), unchecked((int)0xb9ff90c9), unchecked((int)0xb4bcb610), unchecked((int)0xb07daba7),
|
||||
unchecked((int)0xae3afba2), unchecked((int)0xaafbe615), unchecked((int)0xa7b8c0cc), unchecked((int)0xa379dd7b),
|
||||
unchecked((int)0x9b3660c6), unchecked((int)0x9ff77d71), unchecked((int)0x92b45ba8), unchecked((int)0x9675461f),
|
||||
unchecked((int)0x8832161a), unchecked((int)0x8cf30bad), unchecked((int)0x81b02d74), unchecked((int)0x857130c3),
|
||||
unchecked((int)0x5d8a9099), unchecked((int)0x594b8d2e), unchecked((int)0x5408abf7), unchecked((int)0x50c9b640),
|
||||
unchecked((int)0x4e8ee645), unchecked((int)0x4a4ffbf2), unchecked((int)0x470cdd2b), unchecked((int)0x43cdc09c),
|
||||
unchecked((int)0x7b827d21), unchecked((int)0x7f436096), unchecked((int)0x7200464f), unchecked((int)0x76c15bf8),
|
||||
unchecked((int)0x68860bfd), unchecked((int)0x6c47164a), unchecked((int)0x61043093), unchecked((int)0x65c52d24),
|
||||
unchecked((int)0x119b4be9), unchecked((int)0x155a565e), unchecked((int)0x18197087), unchecked((int)0x1cd86d30),
|
||||
unchecked((int)0x029f3d35), unchecked((int)0x065e2082), unchecked((int)0x0b1d065b), unchecked((int)0x0fdc1bec),
|
||||
unchecked((int)0x3793a651), unchecked((int)0x3352bbe6), unchecked((int)0x3e119d3f), unchecked((int)0x3ad08088),
|
||||
unchecked((int)0x2497d08d), unchecked((int)0x2056cd3a), unchecked((int)0x2d15ebe3), unchecked((int)0x29d4f654),
|
||||
unchecked((int)0xc5a92679), unchecked((int)0xc1683bce), unchecked((int)0xcc2b1d17), unchecked((int)0xc8ea00a0),
|
||||
unchecked((int)0xd6ad50a5), unchecked((int)0xd26c4d12), unchecked((int)0xdf2f6bcb), unchecked((int)0xdbee767c),
|
||||
unchecked((int)0xe3a1cbc1), unchecked((int)0xe760d676), unchecked((int)0xea23f0af), unchecked((int)0xeee2ed18),
|
||||
unchecked((int)0xf0a5bd1d), unchecked((int)0xf464a0aa), unchecked((int)0xf9278673), unchecked((int)0xfde69bc4),
|
||||
unchecked((int)0x89b8fd09), unchecked((int)0x8d79e0be), unchecked((int)0x803ac667), unchecked((int)0x84fbdbd0),
|
||||
unchecked((int)0x9abc8bd5), unchecked((int)0x9e7d9662), unchecked((int)0x933eb0bb), unchecked((int)0x97ffad0c),
|
||||
unchecked((int)0xafb010b1), unchecked((int)0xab710d06), unchecked((int)0xa6322bdf), unchecked((int)0xa2f33668),
|
||||
unchecked((int)0xbcb4666d), unchecked((int)0xb8757bda), unchecked((int)0xb5365d03), unchecked((int)0xb1f740b4)
|
||||
};
|
||||
|
||||
public CRC()
|
||||
{
|
||||
InitialiseCRC();
|
||||
}
|
||||
|
||||
internal void InitialiseCRC()
|
||||
{
|
||||
globalCrc = unchecked((int)0xffffffff);
|
||||
}
|
||||
|
||||
internal int GetFinalCRC()
|
||||
{
|
||||
return ~globalCrc;
|
||||
}
|
||||
|
||||
internal int GetGlobalCRC()
|
||||
{
|
||||
return globalCrc;
|
||||
}
|
||||
|
||||
internal void SetGlobalCRC(int newCrc)
|
||||
{
|
||||
globalCrc = newCrc;
|
||||
}
|
||||
|
||||
internal void UpdateCRC(int inCh)
|
||||
{
|
||||
int temp = (globalCrc >> 24) ^ inCh;
|
||||
if (temp < 0)
|
||||
{
|
||||
temp = 256 + temp;
|
||||
}
|
||||
globalCrc = (globalCrc << 8) ^ CRC.crc32Table[temp];
|
||||
}
|
||||
|
||||
internal int globalCrc;
|
||||
}
|
||||
}
|
||||
366
SabreTools.Library/External/Compress/SevenZip/Compress/LZ/LzBinTree.cs
vendored
Normal file
366
SabreTools.Library/External/Compress/SevenZip/Compress/LZ/LzBinTree.cs
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
using System;
|
||||
using Compress.SevenZip.Common;
|
||||
|
||||
namespace Compress.SevenZip.Compress.LZ
|
||||
{
|
||||
internal class BinTree : InWindow
|
||||
{
|
||||
UInt32 _cyclicBufferPos;
|
||||
UInt32 _cyclicBufferSize = 0;
|
||||
UInt32 _matchMaxLen;
|
||||
|
||||
UInt32[] _son;
|
||||
UInt32[] _hash;
|
||||
|
||||
UInt32 _cutValue = 0xFF;
|
||||
UInt32 _hashMask;
|
||||
UInt32 _hashSizeSum = 0;
|
||||
|
||||
bool HASH_ARRAY = true;
|
||||
|
||||
const UInt32 kHash2Size = 1 << 10;
|
||||
const UInt32 kHash3Size = 1 << 16;
|
||||
const UInt32 kBT2HashSize = 1 << 16;
|
||||
const UInt32 kStartMaxLen = 1;
|
||||
const UInt32 kHash3Offset = kHash2Size;
|
||||
const UInt32 kEmptyHashValue = 0;
|
||||
const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1;
|
||||
|
||||
UInt32 kNumHashDirectBytes = 0;
|
||||
UInt32 kMinMatchCheck = 4;
|
||||
UInt32 kFixHashSize = kHash2Size + kHash3Size;
|
||||
|
||||
public void SetType(int numHashBytes)
|
||||
{
|
||||
HASH_ARRAY = (numHashBytes > 2);
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
kNumHashDirectBytes = 0;
|
||||
kMinMatchCheck = 4;
|
||||
kFixHashSize = kHash2Size + kHash3Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
kNumHashDirectBytes = 2;
|
||||
kMinMatchCheck = 2 + 1;
|
||||
kFixHashSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); }
|
||||
public new void ReleaseStream() { base.ReleaseStream(); }
|
||||
|
||||
public new void Init()
|
||||
{
|
||||
base.Init();
|
||||
for (UInt32 i = 0; i < _hashSizeSum; i++)
|
||||
_hash[i] = kEmptyHashValue;
|
||||
_cyclicBufferPos = 0;
|
||||
ReduceOffsets(-1);
|
||||
}
|
||||
|
||||
public new void MovePos()
|
||||
{
|
||||
if (++_cyclicBufferPos >= _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
base.MovePos();
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
}
|
||||
|
||||
public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); }
|
||||
|
||||
public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
|
||||
{ return base.GetMatchLen(index, distance, limit); }
|
||||
|
||||
public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); }
|
||||
|
||||
public void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
|
||||
{
|
||||
if (historySize > kMaxValForNormalize - 256)
|
||||
throw new Exception();
|
||||
_cutValue = 16 + (matchMaxLen >> 1);
|
||||
|
||||
UInt32 windowReservSize = (historySize + keepAddBufferBefore +
|
||||
matchMaxLen + keepAddBufferAfter) / 2 + 256;
|
||||
|
||||
base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
|
||||
|
||||
_matchMaxLen = matchMaxLen;
|
||||
|
||||
UInt32 cyclicBufferSize = historySize + 1;
|
||||
if (_cyclicBufferSize != cyclicBufferSize)
|
||||
_son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2];
|
||||
|
||||
UInt32 hs = kBT2HashSize;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
hs = historySize - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
hs |= 0xFFFF;
|
||||
if (hs > (1 << 24))
|
||||
hs >>= 1;
|
||||
_hashMask = hs;
|
||||
hs++;
|
||||
hs += kFixHashSize;
|
||||
}
|
||||
if (hs != _hashSizeSum)
|
||||
_hash = new UInt32[_hashSizeSum = hs];
|
||||
}
|
||||
|
||||
public UInt32 GetMatches(UInt32[] distances)
|
||||
{
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if (lenLimit < kMinMatchCheck)
|
||||
{
|
||||
MovePos();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 offset = 0;
|
||||
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
UInt32 cur = _bufferOffset + _pos;
|
||||
UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
|
||||
UInt32 hashValue, hash2Value = 0, hash3Value = 0;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
UInt32 temp = Utils.CRC.CRC32Lookup[_bufferBase[cur]] ^ _bufferBase[cur + 1];
|
||||
hash2Value = temp & (kHash2Size - 1);
|
||||
temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
|
||||
hash3Value = temp & (kHash3Size - 1);
|
||||
hashValue = (temp ^ (Utils.CRC.CRC32Lookup[_bufferBase[cur + 3]] << 5)) & _hashMask;
|
||||
}
|
||||
else
|
||||
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
|
||||
|
||||
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
UInt32 curMatch2 = _hash[hash2Value];
|
||||
UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
|
||||
_hash[hash2Value] = _pos;
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
if (curMatch2 > matchMinPos)
|
||||
if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
|
||||
{
|
||||
distances[offset++] = maxLen = 2;
|
||||
distances[offset++] = _pos - curMatch2 - 1;
|
||||
}
|
||||
if (curMatch3 > matchMinPos)
|
||||
if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
|
||||
{
|
||||
if (curMatch3 == curMatch2)
|
||||
offset -= 2;
|
||||
distances[offset++] = maxLen = 3;
|
||||
distances[offset++] = _pos - curMatch3 - 1;
|
||||
curMatch2 = curMatch3;
|
||||
}
|
||||
if (offset != 0 && curMatch2 == curMatch)
|
||||
{
|
||||
offset -= 2;
|
||||
maxLen = kStartMaxLen;
|
||||
}
|
||||
}
|
||||
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
|
||||
UInt32 ptr1 = (_cyclicBufferPos << 1);
|
||||
|
||||
UInt32 len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
|
||||
if (kNumHashDirectBytes != 0)
|
||||
{
|
||||
if (curMatch > matchMinPos)
|
||||
{
|
||||
if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
|
||||
_bufferBase[cur + kNumHashDirectBytes])
|
||||
{
|
||||
distances[offset++] = maxLen = kNumHashDirectBytes;
|
||||
distances[offset++] = _pos - curMatch - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 count = _cutValue;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta) :
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
||||
|
||||
UInt32 pby1 = _bufferOffset + curMatch;
|
||||
UInt32 len = Math.Min(len0, len1);
|
||||
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
distances[offset++] = maxLen = len;
|
||||
distances[offset++] = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
_son[ptr1] = _son[cyclicPos];
|
||||
_son[ptr0] = _son[cyclicPos + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
|
||||
{
|
||||
_son[ptr1] = curMatch;
|
||||
ptr1 = cyclicPos + 1;
|
||||
curMatch = _son[ptr1];
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_son[ptr0] = curMatch;
|
||||
ptr0 = cyclicPos;
|
||||
curMatch = _son[ptr0];
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
MovePos();
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void Skip(UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if (lenLimit < kMinMatchCheck)
|
||||
{
|
||||
MovePos();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
UInt32 cur = _bufferOffset + _pos;
|
||||
|
||||
UInt32 hashValue;
|
||||
|
||||
if (HASH_ARRAY)
|
||||
{
|
||||
UInt32 temp = Utils.CRC.CRC32Lookup[_bufferBase[cur]] ^ _bufferBase[cur + 1];
|
||||
UInt32 hash2Value = temp & (kHash2Size - 1);
|
||||
_hash[hash2Value] = _pos;
|
||||
temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
|
||||
UInt32 hash3Value = temp & (kHash3Size - 1);
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
hashValue = (temp ^ (Utils.CRC.CRC32Lookup[_bufferBase[cur + 3]] << 5)) & _hashMask;
|
||||
}
|
||||
else
|
||||
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
|
||||
|
||||
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
|
||||
UInt32 ptr1 = (_cyclicBufferPos << 1);
|
||||
|
||||
UInt32 len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
|
||||
UInt32 count = _cutValue;
|
||||
while (true)
|
||||
{
|
||||
if (curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta) :
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
||||
|
||||
UInt32 pby1 = _bufferOffset + curMatch;
|
||||
UInt32 len = Math.Min(len0, len1);
|
||||
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
||||
break;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
_son[ptr1] = _son[cyclicPos];
|
||||
_son[ptr0] = _son[cyclicPos + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
|
||||
{
|
||||
_son[ptr1] = curMatch;
|
||||
ptr1 = cyclicPos + 1;
|
||||
curMatch = _son[ptr1];
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_son[ptr0] = curMatch;
|
||||
ptr0 = cyclicPos;
|
||||
curMatch = _son[ptr0];
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
MovePos();
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue)
|
||||
{
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 value = items[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
UInt32 subValue = _pos - _cyclicBufferSize;
|
||||
NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
|
||||
NormalizeLinks(_hash, _hashSizeSum, subValue);
|
||||
ReduceOffsets((Int32)subValue);
|
||||
}
|
||||
|
||||
public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
|
||||
}
|
||||
}
|
||||
148
SabreTools.Library/External/Compress/SevenZip/Compress/LZ/LzInWindow.cs
vendored
Normal file
148
SabreTools.Library/External/Compress/SevenZip/Compress/LZ/LzInWindow.cs
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
|
||||
namespace Compress.SevenZip.Compress.LZ
|
||||
{
|
||||
internal class InWindow
|
||||
{
|
||||
public Byte[] _bufferBase = null; // pointer to buffer with data
|
||||
System.IO.Stream _stream;
|
||||
UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
||||
bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
|
||||
|
||||
UInt32 _pointerToLastSafePosition;
|
||||
|
||||
public UInt32 _bufferOffset;
|
||||
|
||||
public UInt32 _blockSize; // Size of Allocated memory block
|
||||
public UInt32 _pos; // offset (from _buffer) of curent byte
|
||||
UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
|
||||
UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
|
||||
public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
|
||||
|
||||
public void MoveBlock()
|
||||
{
|
||||
UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;
|
||||
// we need one additional byte, since MovePos moves on 1 byte.
|
||||
if (offset > 0)
|
||||
offset--;
|
||||
|
||||
UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset;
|
||||
|
||||
// check negative offset ????
|
||||
for (UInt32 i = 0; i < numBytes; i++)
|
||||
_bufferBase[i] = _bufferBase[offset + i];
|
||||
_bufferOffset -= offset;
|
||||
}
|
||||
|
||||
public virtual void ReadBlock()
|
||||
{
|
||||
if (_streamEndWasReached)
|
||||
return;
|
||||
while (true)
|
||||
{
|
||||
int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);
|
||||
if (size == 0)
|
||||
return;
|
||||
int numReadBytes = _stream != null ? _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size) : 0;
|
||||
if (numReadBytes == 0)
|
||||
{
|
||||
_posLimit = _streamPos;
|
||||
UInt32 pointerToPostion = _bufferOffset + _posLimit;
|
||||
if (pointerToPostion > _pointerToLastSafePosition)
|
||||
_posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);
|
||||
|
||||
_streamEndWasReached = true;
|
||||
return;
|
||||
}
|
||||
_streamPos += (UInt32)numReadBytes;
|
||||
if (_streamPos >= _pos + _keepSizeAfter)
|
||||
_posLimit = _streamPos - _keepSizeAfter;
|
||||
}
|
||||
}
|
||||
|
||||
void Free() { _bufferBase = null; }
|
||||
|
||||
public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
|
||||
{
|
||||
_keepSizeBefore = keepSizeBefore;
|
||||
_keepSizeAfter = keepSizeAfter;
|
||||
UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
||||
if (_bufferBase == null || _blockSize != blockSize)
|
||||
{
|
||||
Free();
|
||||
_blockSize = blockSize;
|
||||
_bufferBase = new Byte[_blockSize];
|
||||
}
|
||||
_pointerToLastSafePosition = _blockSize - keepSizeAfter;
|
||||
_streamEndWasReached = false;
|
||||
}
|
||||
|
||||
public void SetStream(System.IO.Stream stream)
|
||||
{
|
||||
_stream = stream;
|
||||
if (_streamEndWasReached)
|
||||
{
|
||||
_streamEndWasReached = false;
|
||||
if (IsDataStarved)
|
||||
ReadBlock();
|
||||
}
|
||||
}
|
||||
public void ReleaseStream() { _stream = null; }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_bufferOffset = 0;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
_streamEndWasReached = false;
|
||||
ReadBlock();
|
||||
}
|
||||
|
||||
public void MovePos()
|
||||
{
|
||||
_pos++;
|
||||
if (_pos > _posLimit)
|
||||
{
|
||||
UInt32 pointerToPostion = _bufferOffset + _pos;
|
||||
if (pointerToPostion > _pointerToLastSafePosition)
|
||||
MoveBlock();
|
||||
ReadBlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; }
|
||||
|
||||
// index + limit have not to exceed _keepSizeAfter;
|
||||
public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
|
||||
{
|
||||
if (_streamEndWasReached)
|
||||
if ((_pos + index) + limit > _streamPos)
|
||||
limit = _streamPos - (UInt32)(_pos + index);
|
||||
distance++;
|
||||
// Byte *pby = _buffer + (size_t)_pos + index;
|
||||
UInt32 pby = _bufferOffset + _pos + (UInt32)index;
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++) ;
|
||||
return i;
|
||||
}
|
||||
|
||||
public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; }
|
||||
|
||||
public void ReduceOffsets(Int32 subValue)
|
||||
{
|
||||
_bufferOffset += (UInt32)subValue;
|
||||
_posLimit -= (UInt32)subValue;
|
||||
_pos -= (UInt32)subValue;
|
||||
_streamPos -= (UInt32)subValue;
|
||||
}
|
||||
|
||||
public bool IsDataStarved
|
||||
{
|
||||
get
|
||||
{
|
||||
return _streamPos - _pos < _keepSizeAfter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
186
SabreTools.Library/External/Compress/SevenZip/Compress/LZ/LzOutWindow.cs
vendored
Normal file
186
SabreTools.Library/External/Compress/SevenZip/Compress/LZ/LzOutWindow.cs
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
using Compress.SevenZip.Common;
|
||||
|
||||
namespace Compress.SevenZip.Compress.LZ
|
||||
{
|
||||
internal class OutWindow
|
||||
{
|
||||
byte[] _buffer = null;
|
||||
int _windowSize = 0;
|
||||
int _pos;
|
||||
int _streamPos;
|
||||
int _pendingLen;
|
||||
int _pendingDist;
|
||||
System.IO.Stream _stream;
|
||||
|
||||
public long Total;
|
||||
public long Limit;
|
||||
|
||||
public void Create(int windowSize)
|
||||
{
|
||||
if (_windowSize != windowSize)
|
||||
_buffer = new byte[windowSize];
|
||||
else
|
||||
_buffer[windowSize - 1] = 0;
|
||||
_windowSize = windowSize;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
_pendingLen = 0;
|
||||
Total = 0;
|
||||
Limit = 0;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Create(_windowSize);
|
||||
}
|
||||
|
||||
public void Init(System.IO.Stream stream)
|
||||
{
|
||||
ReleaseStream();
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
public void Train(System.IO.Stream stream)
|
||||
{
|
||||
long len = stream.Length;
|
||||
int size = (len < _windowSize) ? (int)len : _windowSize;
|
||||
stream.Position = len - size;
|
||||
Total = 0;
|
||||
Limit = size;
|
||||
_pos = _windowSize - size;
|
||||
CopyStream(stream, size);
|
||||
if (_pos == _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
Flush();
|
||||
_stream = null;
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
if (_stream == null)
|
||||
return;
|
||||
int size = _pos - _streamPos;
|
||||
if (size == 0)
|
||||
return;
|
||||
_stream.Write(_buffer, _streamPos, size);
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
}
|
||||
|
||||
public void CopyBlock(int distance, int len)
|
||||
{
|
||||
int size = len;
|
||||
int pos = _pos - distance - 1;
|
||||
if (pos < 0)
|
||||
pos += _windowSize;
|
||||
for (; size > 0 && _pos < _windowSize && Total < Limit; size--)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
Total++;
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
_pendingLen = size;
|
||||
_pendingDist = distance;
|
||||
}
|
||||
|
||||
public void PutByte(byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
Total++;
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
|
||||
public byte GetByte(int distance)
|
||||
{
|
||||
int pos = _pos - distance - 1;
|
||||
if (pos < 0)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
|
||||
public int CopyStream(System.IO.Stream stream, int len)
|
||||
{
|
||||
int size = len;
|
||||
while (size > 0 && _pos < _windowSize && Total < Limit)
|
||||
{
|
||||
int curSize = _windowSize - _pos;
|
||||
if (curSize > Limit - Total)
|
||||
curSize = (int)(Limit - Total);
|
||||
if (curSize > size)
|
||||
curSize = size;
|
||||
int numReadBytes = stream.Read(_buffer, _pos, curSize);
|
||||
if (numReadBytes == 0)
|
||||
throw new DataErrorException();
|
||||
size -= numReadBytes;
|
||||
_pos += numReadBytes;
|
||||
Total += numReadBytes;
|
||||
if (_pos >= _windowSize)
|
||||
Flush();
|
||||
}
|
||||
return len - size;
|
||||
}
|
||||
|
||||
public void SetLimit(long size)
|
||||
{
|
||||
Limit = Total + size;
|
||||
}
|
||||
|
||||
public bool HasSpace
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pos < _windowSize && Total < Limit;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasPending
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pendingLen > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (_streamPos >= _pos)
|
||||
return 0;
|
||||
|
||||
int size = _pos - _streamPos;
|
||||
if (size > count)
|
||||
size = count;
|
||||
System.Buffer.BlockCopy(_buffer, _streamPos, buffer, offset, size);
|
||||
_streamPos += size;
|
||||
if (_streamPos >= _windowSize)
|
||||
{
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public void CopyPending()
|
||||
{
|
||||
if (_pendingLen > 0)
|
||||
CopyBlock(_pendingDist, _pendingLen);
|
||||
}
|
||||
|
||||
public int AvailableBytes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pos - _streamPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaBase.cs
vendored
Normal file
74
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaBase.cs
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
namespace Compress.SevenZip.Compress.LZMA
|
||||
{
|
||||
internal abstract class Base
|
||||
{
|
||||
public const uint kNumRepDistances = 4;
|
||||
public const uint kNumStates = 12;
|
||||
|
||||
// static byte []kLiteralNextStates = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
||||
// static byte []kMatchNextStates = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
||||
// static byte []kRepNextStates = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
||||
// static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
||||
|
||||
public struct State
|
||||
{
|
||||
public uint Index;
|
||||
public void Init() { Index = 0; }
|
||||
public void UpdateChar()
|
||||
{
|
||||
if (Index < 4) Index = 0;
|
||||
else if (Index < 10) Index -= 3;
|
||||
else Index -= 6;
|
||||
}
|
||||
public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }
|
||||
public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }
|
||||
public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }
|
||||
public bool IsCharState() { return Index < 7; }
|
||||
}
|
||||
|
||||
public const int kNumPosSlotBits = 6;
|
||||
public const int kDicLogSizeMin = 0;
|
||||
// public const int kDicLogSizeMax = 30;
|
||||
// public const uint kDistTableSizeMax = kDicLogSizeMax * 2;
|
||||
|
||||
public const int kNumLenToPosStatesBits = 2; // it's for speed optimization
|
||||
public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
|
||||
|
||||
public const uint kMatchMinLen = 2;
|
||||
|
||||
public static uint GetLenToPosState(uint len)
|
||||
{
|
||||
len -= kMatchMinLen;
|
||||
if (len < kNumLenToPosStates)
|
||||
return len;
|
||||
return (uint)(kNumLenToPosStates - 1);
|
||||
}
|
||||
|
||||
public const int kNumAlignBits = 4;
|
||||
public const uint kAlignTableSize = 1 << kNumAlignBits;
|
||||
public const uint kAlignMask = (kAlignTableSize - 1);
|
||||
|
||||
public const uint kStartPosModelIndex = 4;
|
||||
public const uint kEndPosModelIndex = 14;
|
||||
public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
|
||||
public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2);
|
||||
|
||||
public const uint kNumLitPosStatesBitsEncodingMax = 4;
|
||||
public const uint kNumLitContextBitsMax = 8;
|
||||
|
||||
public const int kNumPosStatesBitsMax = 4;
|
||||
public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
|
||||
public const int kNumPosStatesBitsEncodingMax = 4;
|
||||
public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
|
||||
|
||||
public const int kNumLowLenBits = 3;
|
||||
public const int kNumMidLenBits = 3;
|
||||
public const int kNumHighLenBits = 8;
|
||||
public const uint kNumLowLenSymbols = 1 << kNumLowLenBits;
|
||||
public const uint kNumMidLenSymbols = 1 << kNumMidLenBits;
|
||||
public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
|
||||
(1 << kNumHighLenBits);
|
||||
public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
|
||||
}
|
||||
}
|
||||
404
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaDecoder.cs
vendored
Normal file
404
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaDecoder.cs
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
using System;
|
||||
using Compress.SevenZip.Common;
|
||||
using Compress.SevenZip.Compress.RangeCoder;
|
||||
|
||||
namespace Compress.SevenZip.Compress.LZMA
|
||||
{
|
||||
internal class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
|
||||
{
|
||||
class LenDecoder
|
||||
{
|
||||
BitDecoder m_Choice = new BitDecoder();
|
||||
BitDecoder m_Choice2 = new BitDecoder();
|
||||
BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
||||
BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
||||
BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
|
||||
uint m_NumPosStates = 0;
|
||||
|
||||
public void Create(uint numPosStates)
|
||||
{
|
||||
for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
|
||||
{
|
||||
m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
|
||||
m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
|
||||
}
|
||||
m_NumPosStates = numPosStates;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
m_Choice.Init();
|
||||
for (uint posState = 0; posState < m_NumPosStates; posState++)
|
||||
{
|
||||
m_LowCoder[posState].Init();
|
||||
m_MidCoder[posState].Init();
|
||||
}
|
||||
m_Choice2.Init();
|
||||
m_HighCoder.Init();
|
||||
}
|
||||
|
||||
public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
|
||||
{
|
||||
if (m_Choice.Decode(rangeDecoder) == 0)
|
||||
return m_LowCoder[posState].Decode(rangeDecoder);
|
||||
else
|
||||
{
|
||||
uint symbol = Base.kNumLowLenSymbols;
|
||||
if (m_Choice2.Decode(rangeDecoder) == 0)
|
||||
symbol += m_MidCoder[posState].Decode(rangeDecoder);
|
||||
else
|
||||
{
|
||||
symbol += Base.kNumMidLenSymbols;
|
||||
symbol += m_HighCoder.Decode(rangeDecoder);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LiteralDecoder
|
||||
{
|
||||
struct Decoder2
|
||||
{
|
||||
BitDecoder[] m_Decoders;
|
||||
public void Create() { m_Decoders = new BitDecoder[0x300]; }
|
||||
public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
|
||||
|
||||
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
|
||||
{
|
||||
uint symbol = 1;
|
||||
do
|
||||
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
|
||||
while (symbol < 0x100);
|
||||
return (byte)symbol;
|
||||
}
|
||||
|
||||
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
|
||||
{
|
||||
uint symbol = 1;
|
||||
do
|
||||
{
|
||||
uint matchBit = (uint)(matchByte >> 7) & 1;
|
||||
matchByte <<= 1;
|
||||
uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
|
||||
symbol = (symbol << 1) | bit;
|
||||
if (matchBit != bit)
|
||||
{
|
||||
while (symbol < 0x100)
|
||||
symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
return (byte)symbol;
|
||||
}
|
||||
}
|
||||
|
||||
Decoder2[] m_Coders;
|
||||
int m_NumPrevBits;
|
||||
int m_NumPosBits;
|
||||
uint m_PosMask;
|
||||
|
||||
public void Create(int numPosBits, int numPrevBits)
|
||||
{
|
||||
if (m_Coders != null && m_NumPrevBits == numPrevBits &&
|
||||
m_NumPosBits == numPosBits)
|
||||
return;
|
||||
m_NumPosBits = numPosBits;
|
||||
m_PosMask = ((uint)1 << numPosBits) - 1;
|
||||
m_NumPrevBits = numPrevBits;
|
||||
uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
|
||||
m_Coders = new Decoder2[numStates];
|
||||
for (uint i = 0; i < numStates; i++)
|
||||
m_Coders[i].Create();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
|
||||
for (uint i = 0; i < numStates; i++)
|
||||
m_Coders[i].Init();
|
||||
}
|
||||
|
||||
uint GetState(uint pos, byte prevByte)
|
||||
{ return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
|
||||
|
||||
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
|
||||
{ return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
|
||||
|
||||
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
|
||||
{ return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
|
||||
};
|
||||
|
||||
LZ.OutWindow m_OutWindow;
|
||||
|
||||
BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
||||
BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
|
||||
BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
|
||||
BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
|
||||
BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
|
||||
BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
||||
|
||||
BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
|
||||
BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
|
||||
|
||||
BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
|
||||
|
||||
LenDecoder m_LenDecoder = new LenDecoder();
|
||||
LenDecoder m_RepLenDecoder = new LenDecoder();
|
||||
|
||||
LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
|
||||
|
||||
int m_DictionarySize;
|
||||
|
||||
uint m_PosStateMask;
|
||||
|
||||
Base.State state = new Base.State();
|
||||
uint rep0, rep1, rep2, rep3;
|
||||
|
||||
public Decoder()
|
||||
{
|
||||
m_DictionarySize = -1;
|
||||
for (int i = 0; i < Base.kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
|
||||
}
|
||||
|
||||
void CreateDictionary()
|
||||
{
|
||||
if (m_DictionarySize < 0)
|
||||
throw new InvalidParamException();
|
||||
m_OutWindow = new LZ.OutWindow();
|
||||
int blockSize = Math.Max(m_DictionarySize, (1 << 12));
|
||||
m_OutWindow.Create(blockSize);
|
||||
}
|
||||
|
||||
void SetLiteralProperties(int lp, int lc)
|
||||
{
|
||||
if (lp > 8)
|
||||
throw new InvalidParamException();
|
||||
if (lc > 8)
|
||||
throw new InvalidParamException();
|
||||
m_LiteralDecoder.Create(lp, lc);
|
||||
}
|
||||
|
||||
void SetPosBitsProperties(int pb)
|
||||
{
|
||||
if (pb > Base.kNumPosStatesBitsMax)
|
||||
throw new InvalidParamException();
|
||||
uint numPosStates = (uint)1 << pb;
|
||||
m_LenDecoder.Create(numPosStates);
|
||||
m_RepLenDecoder.Create(numPosStates);
|
||||
m_PosStateMask = numPosStates - 1;
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < Base.kNumStates; i++)
|
||||
{
|
||||
for (uint j = 0; j <= m_PosStateMask; j++)
|
||||
{
|
||||
uint index = (i << Base.kNumPosStatesBitsMax) + j;
|
||||
m_IsMatchDecoders[index].Init();
|
||||
m_IsRep0LongDecoders[index].Init();
|
||||
}
|
||||
m_IsRepDecoders[i].Init();
|
||||
m_IsRepG0Decoders[i].Init();
|
||||
m_IsRepG1Decoders[i].Init();
|
||||
m_IsRepG2Decoders[i].Init();
|
||||
}
|
||||
|
||||
m_LiteralDecoder.Init();
|
||||
for (i = 0; i < Base.kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i].Init();
|
||||
// m_PosSpecDecoder.Init();
|
||||
for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
|
||||
m_PosDecoders[i].Init();
|
||||
|
||||
m_LenDecoder.Init();
|
||||
m_RepLenDecoder.Init();
|
||||
m_PosAlignDecoder.Init();
|
||||
|
||||
state.Init();
|
||||
rep0 = 0;
|
||||
rep1 = 0;
|
||||
rep2 = 0;
|
||||
rep3 = 0;
|
||||
}
|
||||
|
||||
public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
|
||||
Int64 inSize, Int64 outSize, ICodeProgress progress)
|
||||
{
|
||||
if (m_OutWindow == null)
|
||||
CreateDictionary();
|
||||
m_OutWindow.Init(outStream);
|
||||
if (outSize > 0)
|
||||
m_OutWindow.SetLimit(outSize);
|
||||
else
|
||||
m_OutWindow.SetLimit(Int64.MaxValue - m_OutWindow.Total);
|
||||
|
||||
RangeCoder.Decoder rangeDecoder = new RangeCoder.Decoder();
|
||||
rangeDecoder.Init(inStream);
|
||||
|
||||
Code(m_DictionarySize, m_OutWindow, rangeDecoder);
|
||||
|
||||
m_OutWindow.ReleaseStream();
|
||||
rangeDecoder.ReleaseStream();
|
||||
|
||||
if (!rangeDecoder.IsFinished || (inSize > 0 && rangeDecoder.Total != inSize))
|
||||
throw new DataErrorException();
|
||||
if (m_OutWindow.HasPending)
|
||||
throw new DataErrorException();
|
||||
m_OutWindow = null;
|
||||
}
|
||||
|
||||
internal bool Code(int dictionarySize, LZ.OutWindow outWindow, RangeCoder.Decoder rangeDecoder)
|
||||
{
|
||||
int dictionarySizeCheck = Math.Max(dictionarySize, 1);
|
||||
|
||||
outWindow.CopyPending();
|
||||
|
||||
while (outWindow.HasSpace)
|
||||
{
|
||||
uint posState = (uint)outWindow.Total & m_PosStateMask;
|
||||
if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(rangeDecoder) == 0)
|
||||
{
|
||||
byte b;
|
||||
byte prevByte = outWindow.GetByte(0);
|
||||
if (!state.IsCharState())
|
||||
b = m_LiteralDecoder.DecodeWithMatchByte(rangeDecoder,
|
||||
(uint)outWindow.Total, prevByte, outWindow.GetByte((int)rep0));
|
||||
else
|
||||
b = m_LiteralDecoder.DecodeNormal(rangeDecoder, (uint)outWindow.Total, prevByte);
|
||||
outWindow.PutByte(b);
|
||||
state.UpdateChar();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint len;
|
||||
if (m_IsRepDecoders[state.Index].Decode(rangeDecoder) == 1)
|
||||
{
|
||||
if (m_IsRepG0Decoders[state.Index].Decode(rangeDecoder) == 0)
|
||||
{
|
||||
if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(rangeDecoder) == 0)
|
||||
{
|
||||
state.UpdateShortRep();
|
||||
outWindow.PutByte(outWindow.GetByte((int)rep0));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 distance;
|
||||
if (m_IsRepG1Decoders[state.Index].Decode(rangeDecoder) == 0)
|
||||
{
|
||||
distance = rep1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_IsRepG2Decoders[state.Index].Decode(rangeDecoder) == 0)
|
||||
distance = rep2;
|
||||
else
|
||||
{
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
len = m_RepLenDecoder.Decode(rangeDecoder, posState) + Base.kMatchMinLen;
|
||||
state.UpdateRep();
|
||||
}
|
||||
else
|
||||
{
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
len = Base.kMatchMinLen + m_LenDecoder.Decode(rangeDecoder, posState);
|
||||
state.UpdateMatch();
|
||||
uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(rangeDecoder);
|
||||
if (posSlot >= Base.kStartPosModelIndex)
|
||||
{
|
||||
int numDirectBits = (int)((posSlot >> 1) - 1);
|
||||
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
if (posSlot < Base.kEndPosModelIndex)
|
||||
rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
|
||||
rep0 - posSlot - 1, rangeDecoder, numDirectBits);
|
||||
else
|
||||
{
|
||||
rep0 += (rangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
|
||||
rep0 += m_PosAlignDecoder.ReverseDecode(rangeDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
rep0 = posSlot;
|
||||
}
|
||||
if (rep0 >= outWindow.Total || rep0 >= dictionarySizeCheck)
|
||||
{
|
||||
if (rep0 == 0xFFFFFFFF)
|
||||
return true;
|
||||
throw new DataErrorException();
|
||||
}
|
||||
outWindow.CopyBlock((int)rep0, (int)len);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetDecoderProperties(byte[] properties)
|
||||
{
|
||||
if (properties.Length < 1)
|
||||
throw new InvalidParamException();
|
||||
int lc = properties[0] % 9;
|
||||
int remainder = properties[0] / 9;
|
||||
int lp = remainder % 5;
|
||||
int pb = remainder / 5;
|
||||
if (pb > Base.kNumPosStatesBitsMax)
|
||||
throw new InvalidParamException();
|
||||
SetLiteralProperties(lp, lc);
|
||||
SetPosBitsProperties(pb);
|
||||
Init();
|
||||
if (properties.Length >= 5)
|
||||
{
|
||||
m_DictionarySize = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_DictionarySize += properties[1 + i] << (i * 8);
|
||||
}
|
||||
}
|
||||
|
||||
public void Train(System.IO.Stream stream)
|
||||
{
|
||||
if (m_OutWindow == null)
|
||||
CreateDictionary();
|
||||
m_OutWindow.Train(stream);
|
||||
}
|
||||
|
||||
/*
|
||||
public override bool CanRead { get { return true; }}
|
||||
public override bool CanWrite { get { return true; }}
|
||||
public override bool CanSeek { get { return true; }}
|
||||
public override long Length { get { return 0; }}
|
||||
public override long Position
|
||||
{
|
||||
get { return 0; }
|
||||
set { }
|
||||
}
|
||||
public override void Flush() { }
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
}
|
||||
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override void SetLength(long value) {}
|
||||
*/
|
||||
}
|
||||
}
|
||||
1547
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaEncoder.cs
vendored
Normal file
1547
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaEncoder.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
57
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaEncoderProperties.cs
vendored
Normal file
57
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaEncoderProperties.cs
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
using Compress.SevenZip.Common;
|
||||
|
||||
namespace Compress.SevenZip.Compress.LZMA
|
||||
{
|
||||
public class LzmaEncoderProperties
|
||||
{
|
||||
internal CoderPropID[] propIDs;
|
||||
internal object[] properties;
|
||||
|
||||
public LzmaEncoderProperties()
|
||||
: this(false)
|
||||
{
|
||||
}
|
||||
|
||||
public LzmaEncoderProperties(bool eos)
|
||||
: this(eos, 1 << 20)
|
||||
{
|
||||
}
|
||||
|
||||
public LzmaEncoderProperties(bool eos, int dictionary)
|
||||
: this(eos, dictionary, 32)
|
||||
{
|
||||
}
|
||||
|
||||
public LzmaEncoderProperties(bool eos, int dictionary, int numFastBytes)
|
||||
{
|
||||
int posStateBits = 2;
|
||||
int litContextBits = 4;
|
||||
int litPosBits = 0;
|
||||
int algorithm = 2;
|
||||
string mf = "bt4";
|
||||
|
||||
propIDs = new CoderPropID[]
|
||||
{
|
||||
CoderPropID.DictionarySize,
|
||||
CoderPropID.PosStateBits,
|
||||
CoderPropID.LitContextBits,
|
||||
CoderPropID.LitPosBits,
|
||||
CoderPropID.Algorithm,
|
||||
CoderPropID.NumFastBytes,
|
||||
CoderPropID.MatchFinder,
|
||||
CoderPropID.EndMarker
|
||||
};
|
||||
properties = new object[]
|
||||
{
|
||||
dictionary,
|
||||
posStateBits,
|
||||
litContextBits,
|
||||
litPosBits,
|
||||
algorithm,
|
||||
numFastBytes,
|
||||
mf,
|
||||
eos
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
318
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaStream.cs
vendored
Normal file
318
SabreTools.Library/External/Compress/SevenZip/Compress/LZMA/LzmaStream.cs
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Compress.SevenZip.Common;
|
||||
using Compress.SevenZip.Compress.LZ;
|
||||
|
||||
namespace Compress.SevenZip.Compress.LZMA
|
||||
{
|
||||
public class LzmaStream : Stream
|
||||
{
|
||||
private Stream inputStream;
|
||||
private long inputSize;
|
||||
private long outputSize;
|
||||
|
||||
private int dictionarySize;
|
||||
private OutWindow outWindow = new OutWindow();
|
||||
private RangeCoder.Decoder rangeDecoder = new RangeCoder.Decoder();
|
||||
private Decoder decoder;
|
||||
|
||||
private long position = 0;
|
||||
private bool endReached = false;
|
||||
private long availableBytes;
|
||||
private long rangeDecoderLimit;
|
||||
private long inputPosition = 0;
|
||||
|
||||
// LZMA2
|
||||
private bool isLZMA2;
|
||||
private bool uncompressedChunk = false;
|
||||
private bool needDictReset = true;
|
||||
private bool needProps = true;
|
||||
private byte[] props = new byte[5];
|
||||
|
||||
private Encoder encoder;
|
||||
|
||||
public LzmaStream(byte[] properties, Stream inputStream)
|
||||
: this(properties, inputStream, -1, -1, null, properties.Length < 5)
|
||||
{
|
||||
}
|
||||
|
||||
public LzmaStream(byte[] properties, Stream inputStream, long inputSize)
|
||||
: this(properties, inputStream, inputSize, -1, null, properties.Length < 5)
|
||||
{
|
||||
}
|
||||
|
||||
public LzmaStream(byte[] properties, Stream inputStream, long inputSize, long outputSize)
|
||||
: this(properties, inputStream, inputSize, outputSize, null, properties.Length < 5)
|
||||
{
|
||||
}
|
||||
|
||||
public LzmaStream(byte[] properties, Stream inputStream, long inputSize, long outputSize,
|
||||
Stream presetDictionary, bool isLZMA2)
|
||||
{
|
||||
this.inputStream = inputStream;
|
||||
this.inputSize = inputSize;
|
||||
this.outputSize = outputSize;
|
||||
this.isLZMA2 = isLZMA2;
|
||||
|
||||
if (!isLZMA2)
|
||||
{
|
||||
dictionarySize = BitConverter.ToInt32(properties, 1);
|
||||
outWindow.Create(dictionarySize);
|
||||
if (presetDictionary != null)
|
||||
outWindow.Train(presetDictionary);
|
||||
|
||||
rangeDecoder.Init(inputStream);
|
||||
|
||||
decoder = new Decoder();
|
||||
decoder.SetDecoderProperties(properties);
|
||||
props = properties;
|
||||
|
||||
availableBytes = outputSize < 0 ? long.MaxValue : outputSize;
|
||||
rangeDecoderLimit = inputSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionarySize = 2 | (properties[0] & 1);
|
||||
dictionarySize <<= (properties[0] >> 1) + 11;
|
||||
|
||||
outWindow.Create(dictionarySize);
|
||||
if (presetDictionary != null)
|
||||
{
|
||||
outWindow.Train(presetDictionary);
|
||||
needDictReset = false;
|
||||
}
|
||||
|
||||
props = new byte[1];
|
||||
availableBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public LzmaStream(LzmaEncoderProperties properties, bool isLZMA2, Stream outputStream)
|
||||
: this(properties, isLZMA2, null, outputStream)
|
||||
{
|
||||
}
|
||||
|
||||
public LzmaStream(LzmaEncoderProperties properties, bool isLZMA2, Stream presetDictionary, Stream outputStream)
|
||||
{
|
||||
this.isLZMA2 = isLZMA2;
|
||||
availableBytes = 0;
|
||||
endReached = true;
|
||||
|
||||
if (isLZMA2)
|
||||
throw new NotImplementedException();
|
||||
|
||||
encoder = new Encoder();
|
||||
encoder.SetCoderProperties(properties.propIDs, properties.properties);
|
||||
MemoryStream propStream = new MemoryStream(5);
|
||||
encoder.WriteCoderProperties(propStream);
|
||||
props = propStream.ToArray();
|
||||
|
||||
encoder.SetStreams(null, outputStream, -1, -1);
|
||||
if (presetDictionary != null)
|
||||
encoder.Train(presetDictionary);
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return encoder == null; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return encoder != null; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (encoder != null)
|
||||
position = encoder.Code(null, true);
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { return position + availableBytes; }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return position;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (endReached)
|
||||
return 0;
|
||||
|
||||
int total = 0;
|
||||
while (total < count)
|
||||
{
|
||||
if (availableBytes == 0)
|
||||
{
|
||||
if (isLZMA2)
|
||||
decodeChunkHeader();
|
||||
else
|
||||
endReached = true;
|
||||
if (endReached)
|
||||
break;
|
||||
}
|
||||
|
||||
int toProcess = count - total;
|
||||
if (toProcess > availableBytes)
|
||||
toProcess = (int)availableBytes;
|
||||
|
||||
outWindow.SetLimit(toProcess);
|
||||
if(uncompressedChunk)
|
||||
{
|
||||
inputPosition += outWindow.CopyStream(inputStream, toProcess);
|
||||
}
|
||||
else if(decoder.Code(dictionarySize, outWindow, rangeDecoder)
|
||||
&& outputSize < 0)
|
||||
{
|
||||
availableBytes = outWindow.AvailableBytes;
|
||||
}
|
||||
|
||||
int read = outWindow.Read(buffer, offset, toProcess);
|
||||
total += read;
|
||||
offset += read;
|
||||
position += read;
|
||||
availableBytes -= read;
|
||||
|
||||
if (availableBytes == 0 && !uncompressedChunk)
|
||||
{
|
||||
rangeDecoder.ReleaseStream();
|
||||
if (!rangeDecoder.IsFinished || (rangeDecoderLimit >= 0 && rangeDecoder.Total != rangeDecoderLimit))
|
||||
throw new DataErrorException();
|
||||
inputPosition += rangeDecoder.Total;
|
||||
if (outWindow.HasPending)
|
||||
throw new DataErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
if (endReached)
|
||||
{
|
||||
if (inputSize >= 0 && inputPosition != inputSize)
|
||||
throw new DataErrorException();
|
||||
if (outputSize >= 0 && position != outputSize)
|
||||
throw new DataErrorException();
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
private void decodeChunkHeader()
|
||||
{
|
||||
int control = inputStream.ReadByte();
|
||||
inputPosition++;
|
||||
|
||||
if (control == 0x00)
|
||||
{
|
||||
endReached = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (control >= 0xE0 || control == 0x01)
|
||||
{
|
||||
needProps = true;
|
||||
needDictReset = false;
|
||||
outWindow.Reset();
|
||||
}
|
||||
else if (needDictReset)
|
||||
throw new DataErrorException();
|
||||
|
||||
if (control >= 0x80)
|
||||
{
|
||||
uncompressedChunk = false;
|
||||
|
||||
availableBytes = (control & 0x1F) << 16;
|
||||
availableBytes += (inputStream.ReadByte() << 8) + inputStream.ReadByte() + 1;
|
||||
inputPosition += 2;
|
||||
|
||||
rangeDecoderLimit = (inputStream.ReadByte() << 8) + inputStream.ReadByte() + 1;
|
||||
inputPosition += 2;
|
||||
|
||||
if (control >= 0xC0)
|
||||
{
|
||||
needProps = false;
|
||||
props[0] = (byte)inputStream.ReadByte();
|
||||
inputPosition++;
|
||||
|
||||
decoder = new Decoder();
|
||||
decoder.SetDecoderProperties(props);
|
||||
}
|
||||
else if (needProps)
|
||||
throw new DataErrorException();
|
||||
else if (control >= 0xA0)
|
||||
{
|
||||
decoder = new Decoder();
|
||||
decoder.SetDecoderProperties(props);
|
||||
}
|
||||
|
||||
rangeDecoder.Init(inputStream);
|
||||
}
|
||||
else if (control > 0x02)
|
||||
throw new DataErrorException();
|
||||
else
|
||||
{
|
||||
uncompressedChunk = true;
|
||||
availableBytes = (inputStream.ReadByte() << 8) + inputStream.ReadByte() + 1;
|
||||
inputPosition += 2;
|
||||
}
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (origin!=SeekOrigin.Current)
|
||||
throw new NotImplementedException();
|
||||
|
||||
byte[] tmpBuff=new byte[1024];
|
||||
long sizeToGo = offset;
|
||||
while (sizeToGo > 0)
|
||||
{
|
||||
int sizenow = sizeToGo > 1024 ? 1024 : (int)sizeToGo;
|
||||
Read(tmpBuff, 0, sizenow);
|
||||
sizeToGo -= sizenow;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (encoder != null)
|
||||
position = encoder.Code(new MemoryStream(buffer, offset, count), false);
|
||||
}
|
||||
|
||||
public byte[] Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
return props;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/FreqData.cs
vendored
Normal file
75
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/FreqData.cs
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class FreqData : Pointer
|
||||
{
|
||||
internal const int Size = 6;
|
||||
|
||||
// struct FreqData
|
||||
// {
|
||||
// ushort SummFreq;
|
||||
// STATE _PACK_ATTR * Stats;
|
||||
// };
|
||||
|
||||
internal FreqData(byte[] Memory)
|
||||
: base(Memory)
|
||||
{
|
||||
}
|
||||
|
||||
internal int SummFreq
|
||||
{
|
||||
get
|
||||
{
|
||||
return Utility.readShortLittleEndian(Memory, Address) & 0xffff;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address, (short)value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal FreqData Initialize(byte[] mem)
|
||||
{
|
||||
return base.Initialize<FreqData>(mem);
|
||||
}
|
||||
|
||||
internal void IncrementSummFreq(int dSummFreq)
|
||||
{
|
||||
Utility.incShortLittleEndian(Memory, Address, (short)dSummFreq);
|
||||
}
|
||||
|
||||
internal int GetStats()
|
||||
{
|
||||
return Utility.readIntLittleEndian(Memory, Address + 2);
|
||||
}
|
||||
|
||||
internal virtual void SetStats(State state)
|
||||
{
|
||||
SetStats(state.Address);
|
||||
}
|
||||
|
||||
internal void SetStats(int state)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address + 2, state);
|
||||
}
|
||||
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("FreqData[");
|
||||
buffer.Append("\n Address=");
|
||||
buffer.Append(Address);
|
||||
buffer.Append("\n size=");
|
||||
buffer.Append(Size);
|
||||
buffer.Append("\n summFreq=");
|
||||
buffer.Append(SummFreq);
|
||||
buffer.Append("\n stats=");
|
||||
buffer.Append(GetStats());
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
945
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/ModelPPM.cs
vendored
Normal file
945
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/ModelPPM.cs
vendored
Normal file
@@ -0,0 +1,945 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Decoder = Compress.SevenZip.Compress.RangeCoder.Decoder;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class ModelPPM
|
||||
{
|
||||
private void InitBlock()
|
||||
{
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
SEE2Cont[i] = new SEE2Context[16];
|
||||
}
|
||||
for (int i2 = 0; i2 < 128; i2++)
|
||||
{
|
||||
binSumm[i2] = new int[64];
|
||||
}
|
||||
}
|
||||
public SubAllocator SubAlloc
|
||||
{
|
||||
get
|
||||
{
|
||||
return subAlloc;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public SEE2Context DummySEE2Cont
|
||||
{
|
||||
get
|
||||
{
|
||||
return dummySEE2Cont;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int InitRL
|
||||
{
|
||||
get
|
||||
{
|
||||
return initRL;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int EscCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return escCount;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.escCount = value & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int[] CharMask
|
||||
{
|
||||
get
|
||||
{
|
||||
return charMask;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int NumMasked
|
||||
{
|
||||
get
|
||||
{
|
||||
return numMasked;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.numMasked = value;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int PrevSuccess
|
||||
{
|
||||
get
|
||||
{
|
||||
return prevSuccess;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.prevSuccess = value & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int InitEsc
|
||||
{
|
||||
get
|
||||
{
|
||||
return initEsc;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.initEsc = value;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int RunLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return runLength;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.runLength = value;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int HiBitsFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return hiBitsFlag;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.hiBitsFlag = value & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int[][] BinSumm
|
||||
{
|
||||
get
|
||||
{
|
||||
return binSumm;
|
||||
}
|
||||
|
||||
}
|
||||
internal RangeCoder Coder
|
||||
{
|
||||
get
|
||||
{
|
||||
return coder;
|
||||
}
|
||||
|
||||
}
|
||||
internal State FoundState
|
||||
{
|
||||
get
|
||||
{
|
||||
return foundState;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public byte[] Heap
|
||||
{
|
||||
get
|
||||
{
|
||||
return subAlloc.Heap;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int OrderFall
|
||||
{
|
||||
get
|
||||
{
|
||||
return orderFall;
|
||||
}
|
||||
|
||||
}
|
||||
public const int MAX_O = 64; /* maximum allowed model order */
|
||||
|
||||
public const int INT_BITS = 7;
|
||||
|
||||
public const int PERIOD_BITS = 7;
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'TOT_BITS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public static readonly int TOT_BITS = INT_BITS + PERIOD_BITS;
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'INTERVAL '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public static readonly int INTERVAL = 1 << INT_BITS;
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'BIN_SCALE '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public static readonly int BIN_SCALE = 1 << TOT_BITS;
|
||||
|
||||
public const int MAX_FREQ = 124;
|
||||
|
||||
private SEE2Context[][] SEE2Cont = new SEE2Context[25][];
|
||||
|
||||
private SEE2Context dummySEE2Cont;
|
||||
|
||||
private PPMContext minContext; //medContext
|
||||
|
||||
private PPMContext maxContext;
|
||||
|
||||
private State foundState; // found next state transition
|
||||
|
||||
private int numMasked, initEsc, orderFall, maxOrder, runLength, initRL;
|
||||
|
||||
private int[] charMask = new int[256];
|
||||
|
||||
private int[] NS2Indx = new int[256];
|
||||
|
||||
private int[] NS2BSIndx = new int[256];
|
||||
|
||||
private int[] HB2Flag = new int[256];
|
||||
|
||||
// byte EscCount, PrevSuccess, HiBitsFlag;
|
||||
private int escCount, prevSuccess, hiBitsFlag;
|
||||
|
||||
private int[][] binSumm = new int[128][]; // binary SEE-contexts
|
||||
|
||||
private RangeCoder coder;
|
||||
|
||||
private SubAllocator subAlloc = new SubAllocator();
|
||||
|
||||
private static int[] InitBinEsc = new int[] { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051 };
|
||||
|
||||
// Temp fields
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState1 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState2 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState3 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState3 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState4 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState4 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempStateRef1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private StateRef tempStateRef1 = new StateRef();
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempStateRef2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private StateRef tempStateRef2 = new StateRef();
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private PPMContext tempPPMContext1 = new PPMContext(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private PPMContext tempPPMContext2 = new PPMContext(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext3 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private PPMContext tempPPMContext3 = new PPMContext(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext4 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private PPMContext tempPPMContext4 = new PPMContext(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'ps '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private int[] ps = new int[MAX_O];
|
||||
|
||||
public ModelPPM()
|
||||
{
|
||||
InitBlock();
|
||||
minContext = null;
|
||||
maxContext = null;
|
||||
//medContext = null;
|
||||
}
|
||||
|
||||
private void restartModelRare()
|
||||
{
|
||||
Utility.Fill(charMask, 0);
|
||||
subAlloc.initSubAllocator();
|
||||
initRL = -(maxOrder < 12 ? maxOrder : 12) - 1;
|
||||
int addr = subAlloc.allocContext();
|
||||
minContext.Address = addr;
|
||||
maxContext.Address = addr;
|
||||
minContext.setSuffix(0);
|
||||
orderFall = maxOrder;
|
||||
minContext.NumStats = 256;
|
||||
minContext.FreqData.SummFreq = minContext.NumStats + 1;
|
||||
|
||||
addr = subAlloc.allocUnits(256 / 2);
|
||||
foundState.Address = addr;
|
||||
minContext.FreqData.SetStats(addr);
|
||||
|
||||
State state = new State(subAlloc.Heap);
|
||||
addr = minContext.FreqData.GetStats();
|
||||
runLength = initRL;
|
||||
prevSuccess = 0;
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
state.Address = addr + i * State.Size;
|
||||
state.Symbol = i;
|
||||
state.Freq = 1;
|
||||
state.SetSuccessor(0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
for (int m = 0; m < 64; m += 8)
|
||||
{
|
||||
binSumm[i][k + m] = BIN_SCALE - InitBinEsc[k] / (i + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
for (int k = 0; k < 16; k++)
|
||||
{
|
||||
SEE2Cont[i][k].Initialize(5 * i + 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startModelRare(int MaxOrder)
|
||||
{
|
||||
int i, k, m, Step;
|
||||
escCount = 1;
|
||||
this.maxOrder = MaxOrder;
|
||||
restartModelRare();
|
||||
// Bug Fixed
|
||||
NS2BSIndx[0] = 0;
|
||||
NS2BSIndx[1] = 2;
|
||||
for (int j = 0; j < 9; j++)
|
||||
{
|
||||
NS2BSIndx[2 + j] = 4;
|
||||
}
|
||||
for (int j = 0; j < 256 - 11; j++)
|
||||
{
|
||||
NS2BSIndx[11 + j] = 6;
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
NS2Indx[i] = i;
|
||||
}
|
||||
for (m = i, k = 1, Step = 1; i < 256; i++)
|
||||
{
|
||||
NS2Indx[i] = m;
|
||||
if ((--k) == 0)
|
||||
{
|
||||
k = ++Step;
|
||||
m++;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 0x40; j++)
|
||||
{
|
||||
HB2Flag[j] = 0;
|
||||
}
|
||||
for (int j = 0; j < 0x100 - 0x40; j++)
|
||||
{
|
||||
HB2Flag[0x40 + j] = 0x08;
|
||||
}
|
||||
dummySEE2Cont.Shift = PERIOD_BITS;
|
||||
}
|
||||
|
||||
private void clearMask()
|
||||
{
|
||||
escCount = 1;
|
||||
Utility.Fill(charMask, 0);
|
||||
}
|
||||
|
||||
|
||||
public virtual int decodeChar()
|
||||
{
|
||||
// Debug
|
||||
//subAlloc.dumpHeap();
|
||||
|
||||
if (minContext.Address <= subAlloc.PText || minContext.Address > subAlloc.HeapEnd)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (minContext.NumStats != 1)
|
||||
{
|
||||
if (minContext.FreqData.GetStats() <= subAlloc.PText || minContext.FreqData.GetStats() > subAlloc.HeapEnd)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
if (!minContext.decodeSymbol1(this))
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
minContext.decodeBinSymbol(this);
|
||||
}
|
||||
coder.Decode();
|
||||
while (foundState.Address == 0)
|
||||
{
|
||||
coder.AriDecNormalize();
|
||||
do
|
||||
{
|
||||
orderFall++;
|
||||
minContext.Address = minContext.getSuffix(); // =MinContext->Suffix;
|
||||
if (minContext.Address <= subAlloc.PText || minContext.Address > subAlloc.HeapEnd)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
while (minContext.NumStats == numMasked);
|
||||
if (!minContext.decodeSymbol2(this))
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
coder.Decode();
|
||||
}
|
||||
int Symbol = foundState.Symbol;
|
||||
if ((orderFall == 0) && foundState.GetSuccessor() > subAlloc.PText)
|
||||
{
|
||||
// MinContext=MaxContext=FoundState->Successor;
|
||||
int addr = foundState.GetSuccessor();
|
||||
minContext.Address = addr;
|
||||
maxContext.Address = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
updateModel();
|
||||
//this.foundState.Address=foundState.Address);//TODO just 4 debugging
|
||||
if (escCount == 0)
|
||||
{
|
||||
clearMask();
|
||||
}
|
||||
}
|
||||
coder.AriDecNormalize(); // ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||
return (Symbol);
|
||||
}
|
||||
|
||||
public virtual SEE2Context[][] getSEE2Cont()
|
||||
{
|
||||
return SEE2Cont;
|
||||
}
|
||||
|
||||
public virtual void incEscCount(int dEscCount)
|
||||
{
|
||||
EscCount = EscCount + dEscCount;
|
||||
}
|
||||
|
||||
public virtual void incRunLength(int dRunLength)
|
||||
{
|
||||
RunLength = RunLength + dRunLength;
|
||||
}
|
||||
|
||||
public virtual int[] getHB2Flag()
|
||||
{
|
||||
return HB2Flag;
|
||||
}
|
||||
|
||||
public virtual int[] getNS2BSIndx()
|
||||
{
|
||||
return NS2BSIndx;
|
||||
}
|
||||
|
||||
public virtual int[] getNS2Indx()
|
||||
{
|
||||
return NS2Indx;
|
||||
}
|
||||
|
||||
private int createSuccessors(bool Skip, State p1)
|
||||
{
|
||||
//State upState = tempState1.Initialize(null);
|
||||
StateRef upState = tempStateRef2;
|
||||
State tempState = tempState1.Initialize(Heap);
|
||||
|
||||
// PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
|
||||
PPMContext pc = tempPPMContext1.Initialize(Heap);
|
||||
pc.Address = minContext.Address;
|
||||
PPMContext upBranch = tempPPMContext2.Initialize(Heap);
|
||||
upBranch.Address = foundState.GetSuccessor();
|
||||
|
||||
// STATE * p, * ps[MAX_O], ** pps=ps;
|
||||
State p = tempState2.Initialize(Heap);
|
||||
int pps = 0;
|
||||
|
||||
bool noLoop = false;
|
||||
|
||||
if (!Skip)
|
||||
{
|
||||
ps[pps++] = foundState.Address; // *pps++ = FoundState;
|
||||
if (pc.getSuffix() == 0)
|
||||
{
|
||||
noLoop = true;
|
||||
}
|
||||
}
|
||||
if (!noLoop)
|
||||
{
|
||||
bool loopEntry = false;
|
||||
if (p1.Address != 0)
|
||||
{
|
||||
p.Address = p1.Address;
|
||||
pc.Address = pc.getSuffix(); // =pc->Suffix;
|
||||
loopEntry = true;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (!loopEntry)
|
||||
{
|
||||
pc.Address = pc.getSuffix(); // pc=pc->Suffix;
|
||||
if (pc.NumStats != 1)
|
||||
{
|
||||
p.Address = pc.FreqData.GetStats(); // p=pc->U.Stats
|
||||
if (p.Symbol != foundState.Symbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
p.IncrementAddress();
|
||||
}
|
||||
while (p.Symbol != foundState.Symbol);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Address = pc.getOneState().Address; // p=&(pc->OneState);
|
||||
}
|
||||
} // LOOP_ENTRY:
|
||||
loopEntry = false;
|
||||
if (p.GetSuccessor() != upBranch.Address)
|
||||
{
|
||||
pc.Address = p.GetSuccessor(); // =p->Successor;
|
||||
break;
|
||||
}
|
||||
ps[pps++] = p.Address;
|
||||
}
|
||||
while (pc.getSuffix() != 0);
|
||||
} // NO_LOOP:
|
||||
if (pps == 0)
|
||||
{
|
||||
return pc.Address;
|
||||
}
|
||||
upState.Symbol = Heap[upBranch.Address]; // UpState.Symbol=*(byte*)
|
||||
// UpBranch;
|
||||
// UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
|
||||
upState.SetSuccessor(upBranch.Address + 1); //TODO check if +1 necessary
|
||||
if (pc.NumStats != 1)
|
||||
{
|
||||
if (pc.Address <= subAlloc.PText)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
p.Address = pc.FreqData.GetStats();
|
||||
if (p.Symbol != upState.Symbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
p.IncrementAddress();
|
||||
}
|
||||
while (p.Symbol != upState.Symbol);
|
||||
}
|
||||
int cf = p.Freq - 1;
|
||||
int s0 = pc.FreqData.SummFreq - pc.NumStats - cf;
|
||||
// UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
|
||||
upState.Freq = 1 + ((2 * cf <= s0) ? (5 * cf > s0 ? 1 : 0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
upState.Freq = pc.getOneState().Freq; // UpState.Freq=pc->OneState.Freq;
|
||||
}
|
||||
do
|
||||
{
|
||||
// pc = pc->createChild(this,*--pps,UpState);
|
||||
tempState.Address = ps[--pps];
|
||||
pc.Address = pc.createChild(this, tempState, upState);
|
||||
if (pc.Address == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while (pps != 0);
|
||||
return pc.Address;
|
||||
}
|
||||
|
||||
private void updateModelRestart()
|
||||
{
|
||||
restartModelRare();
|
||||
escCount = 0;
|
||||
}
|
||||
|
||||
private void updateModel()
|
||||
{
|
||||
//System.out.println("ModelPPM.updateModel()");
|
||||
// STATE fs = *FoundState, *p = NULL;
|
||||
StateRef fs = tempStateRef1;
|
||||
fs.Values = foundState;
|
||||
State p = tempState3.Initialize(Heap);
|
||||
State tempState = tempState4.Initialize(Heap);
|
||||
|
||||
PPMContext pc = tempPPMContext3.Initialize(Heap);
|
||||
PPMContext successor = tempPPMContext4.Initialize(Heap);
|
||||
|
||||
int ns1, ns, cf, sf, s0;
|
||||
pc.Address = minContext.getSuffix();
|
||||
if (fs.Freq < MAX_FREQ / 4 && pc.Address != 0)
|
||||
{
|
||||
if (pc.NumStats != 1)
|
||||
{
|
||||
p.Address = pc.FreqData.GetStats();
|
||||
if (p.Symbol != fs.Symbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
p.IncrementAddress();
|
||||
}
|
||||
while (p.Symbol != fs.Symbol);
|
||||
tempState.Address = p.Address - State.Size;
|
||||
if (p.Freq >= tempState.Freq)
|
||||
{
|
||||
State.PPMDSwap(p, tempState);
|
||||
p.DecrementAddress();
|
||||
}
|
||||
}
|
||||
if (p.Freq < MAX_FREQ - 9)
|
||||
{
|
||||
p.IncrementFreq(2);
|
||||
pc.FreqData.IncrementSummFreq(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Address = pc.getOneState().Address;
|
||||
if (p.Freq < 32)
|
||||
{
|
||||
p.IncrementFreq(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (orderFall == 0)
|
||||
{
|
||||
foundState.SetSuccessor(createSuccessors(true, p));
|
||||
minContext.Address = foundState.GetSuccessor();
|
||||
maxContext.Address = foundState.GetSuccessor();
|
||||
if (minContext.Address == 0)
|
||||
{
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
subAlloc.Heap[subAlloc.PText] = (byte)fs.Symbol;
|
||||
subAlloc.incPText();
|
||||
successor.Address = subAlloc.PText;
|
||||
if (subAlloc.PText >= subAlloc.FakeUnitsStart)
|
||||
{
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
// // Debug
|
||||
// subAlloc.dumpHeap();
|
||||
if (fs.GetSuccessor() != 0)
|
||||
{
|
||||
if (fs.GetSuccessor() <= subAlloc.PText)
|
||||
{
|
||||
fs.SetSuccessor(createSuccessors(false, p));
|
||||
if (fs.GetSuccessor() == 0)
|
||||
{
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (--orderFall == 0)
|
||||
{
|
||||
successor.Address = fs.GetSuccessor();
|
||||
if (maxContext.Address != minContext.Address)
|
||||
{
|
||||
subAlloc.decPText(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foundState.SetSuccessor(successor.Address);
|
||||
fs.SetSuccessor(minContext);
|
||||
}
|
||||
// // Debug
|
||||
// subAlloc.dumpHeap();
|
||||
ns = minContext.NumStats;
|
||||
s0 = minContext.FreqData.SummFreq - (ns) - (fs.Freq - 1);
|
||||
for (pc.Address = maxContext.Address; pc.Address != minContext.Address; pc.Address = pc.getSuffix())
|
||||
{
|
||||
if ((ns1 = pc.NumStats) != 1)
|
||||
{
|
||||
if ((ns1 & 1) == 0)
|
||||
{
|
||||
//System.out.println(ns1);
|
||||
pc.FreqData.SetStats(subAlloc.expandUnits(pc.FreqData.GetStats(), Utility.URShift(ns1, 1)));
|
||||
if (pc.FreqData.GetStats() == 0)
|
||||
{
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// bug fixed
|
||||
// int sum = ((2 * ns1 < ns) ? 1 : 0) +
|
||||
// 2 * ((4 * ((ns1 <= ns) ? 1 : 0)) & ((pc.getFreqData()
|
||||
// .getSummFreq() <= 8 * ns1) ? 1 : 0));
|
||||
int sum = ((2 * ns1 < ns) ? 1 : 0) + 2 * (((4 * ns1 <= ns) ? 1 : 0) & ((pc.FreqData.SummFreq <= 8 * ns1) ? 1 : 0));
|
||||
pc.FreqData.IncrementSummFreq(sum);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Address = subAlloc.allocUnits(1);
|
||||
if (p.Address == 0)
|
||||
{
|
||||
updateModelRestart();
|
||||
return;
|
||||
}
|
||||
p.SetValues(pc.getOneState());
|
||||
pc.FreqData.SetStats(p);
|
||||
if (p.Freq < MAX_FREQ / 4 - 1)
|
||||
{
|
||||
p.IncrementFreq(p.Freq);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Freq = MAX_FREQ - 4;
|
||||
}
|
||||
pc.FreqData.SummFreq = (p.Freq + initEsc + (ns > 3 ? 1 : 0));
|
||||
}
|
||||
cf = 2 * fs.Freq * (pc.FreqData.SummFreq + 6);
|
||||
sf = s0 + pc.FreqData.SummFreq;
|
||||
if (cf < 6 * sf)
|
||||
{
|
||||
cf = 1 + (cf > sf ? 1 : 0) + (cf >= 4 * sf ? 1 : 0);
|
||||
pc.FreqData.IncrementSummFreq(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
cf = 4 + (cf >= 9 * sf ? 1 : 0) + (cf >= 12 * sf ? 1 : 0) + (cf >= 15 * sf ? 1 : 0);
|
||||
pc.FreqData.IncrementSummFreq(cf);
|
||||
}
|
||||
p.Address = pc.FreqData.GetStats() + ns1 * State.Size;
|
||||
p.SetSuccessor(successor);
|
||||
p.Symbol = fs.Symbol;
|
||||
p.Freq = cf;
|
||||
pc.NumStats = ++ns1;
|
||||
}
|
||||
|
||||
int address = fs.GetSuccessor();
|
||||
maxContext.Address = address;
|
||||
minContext.Address = address;
|
||||
//TODO-----debug
|
||||
// int pos = minContext.getFreqData().getStats();
|
||||
// State a = new State(getHeap());
|
||||
// a.Address=pos);
|
||||
// pos+=State.size;
|
||||
// a.Address=pos);
|
||||
//--dbg end
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("ModelPPM[");
|
||||
buffer.Append("\n numMasked=");
|
||||
buffer.Append(numMasked);
|
||||
buffer.Append("\n initEsc=");
|
||||
buffer.Append(initEsc);
|
||||
buffer.Append("\n orderFall=");
|
||||
buffer.Append(orderFall);
|
||||
buffer.Append("\n maxOrder=");
|
||||
buffer.Append(maxOrder);
|
||||
buffer.Append("\n runLength=");
|
||||
buffer.Append(runLength);
|
||||
buffer.Append("\n initRL=");
|
||||
buffer.Append(initRL);
|
||||
buffer.Append("\n escCount=");
|
||||
buffer.Append(escCount);
|
||||
buffer.Append("\n prevSuccess=");
|
||||
buffer.Append(prevSuccess);
|
||||
buffer.Append("\n foundState=");
|
||||
buffer.Append(foundState);
|
||||
buffer.Append("\n coder=");
|
||||
buffer.Append(coder);
|
||||
buffer.Append("\n subAlloc=");
|
||||
buffer.Append(subAlloc);
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
|
||||
// Debug
|
||||
// public void dumpHeap() {
|
||||
// subAlloc.dumpHeap();
|
||||
// }
|
||||
|
||||
internal bool decodeInit(Stream stream, int maxOrder, int maxMemory)
|
||||
{
|
||||
if (stream != null)
|
||||
coder = new RangeCoder(stream);
|
||||
|
||||
if (maxOrder == 1)
|
||||
{
|
||||
subAlloc.stopSubAllocator();
|
||||
return (false);
|
||||
}
|
||||
subAlloc.startSubAllocator(maxMemory);
|
||||
minContext = new PPMContext(Heap);
|
||||
//medContext = new PPMContext(Heap);
|
||||
maxContext = new PPMContext(Heap);
|
||||
foundState = new State(Heap);
|
||||
dummySEE2Cont = new SEE2Context();
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
SEE2Cont[i][j] = new SEE2Context();
|
||||
}
|
||||
}
|
||||
startModelRare(maxOrder);
|
||||
|
||||
return (minContext.Address != 0);
|
||||
}
|
||||
|
||||
internal void nextContext()
|
||||
{
|
||||
int addr = foundState.GetSuccessor();
|
||||
if (orderFall == 0 && addr > subAlloc.PText)
|
||||
{
|
||||
minContext.Address = addr;
|
||||
maxContext.Address = addr;
|
||||
}
|
||||
else
|
||||
updateModel();
|
||||
}
|
||||
|
||||
public int decodeChar(Decoder decoder)
|
||||
{
|
||||
if (minContext.NumStats != 1)
|
||||
{
|
||||
State s = tempState1.Initialize(Heap);
|
||||
s.Address = minContext.FreqData.GetStats();
|
||||
int i;
|
||||
int count, hiCnt;
|
||||
if ((count = (int)decoder.GetThreshold((uint)minContext.FreqData.SummFreq)) < (hiCnt = s.Freq))
|
||||
{
|
||||
byte symbol;
|
||||
decoder.Decode(0, (uint)s.Freq);
|
||||
symbol = (byte)s.Symbol;
|
||||
minContext.update1_0(this, s.Address);
|
||||
nextContext();
|
||||
return symbol;
|
||||
}
|
||||
prevSuccess = 0;
|
||||
i = minContext.NumStats - 1;
|
||||
do
|
||||
{
|
||||
s.IncrementAddress();
|
||||
if ((hiCnt += s.Freq) > count)
|
||||
{
|
||||
byte symbol;
|
||||
decoder.Decode((uint)(hiCnt - s.Freq), (uint)s.Freq);
|
||||
symbol = (byte)s.Symbol;
|
||||
minContext.update1(this, s.Address);
|
||||
nextContext();
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
while (--i > 0);
|
||||
if (count >= minContext.FreqData.SummFreq)
|
||||
return -2;
|
||||
hiBitsFlag = HB2Flag[foundState.Symbol];
|
||||
decoder.Decode((uint)hiCnt, (uint)(minContext.FreqData.SummFreq - hiCnt));
|
||||
for (i = 0; i < 256; i++)
|
||||
charMask[i] = -1;
|
||||
charMask[s.Symbol] = 0;
|
||||
i = minContext.NumStats - 1;
|
||||
do
|
||||
{
|
||||
s.DecrementAddress();
|
||||
charMask[s.Symbol] = 0;
|
||||
}
|
||||
while (--i > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
State rs = tempState1.Initialize(Heap);
|
||||
rs.Address = minContext.getOneState().Address;
|
||||
hiBitsFlag = getHB2Flag()[foundState.Symbol];
|
||||
int off1 = rs.Freq - 1;
|
||||
int off2 = minContext.getArrayIndex(this, rs);
|
||||
int bs = binSumm[off1][off2];
|
||||
if (decoder.DecodeBit((uint)bs, 14) == 0)
|
||||
{
|
||||
byte symbol;
|
||||
binSumm[off1][off2] = (bs + INTERVAL - minContext.getMean(bs, PERIOD_BITS, 2)) & 0xFFFF;
|
||||
foundState.Address = rs.Address;
|
||||
symbol = (byte)rs.Symbol;
|
||||
rs.IncrementFreq((rs.Freq < 128) ? 1 : 0);
|
||||
prevSuccess = 1;
|
||||
incRunLength(1);
|
||||
nextContext();
|
||||
return symbol;
|
||||
}
|
||||
bs = (bs - minContext.getMean(bs, PERIOD_BITS, 2)) & 0xFFFF;
|
||||
binSumm[off1][off2] = bs;
|
||||
initEsc = PPMContext.ExpEscape[Utility.URShift(bs, 10)];
|
||||
int i;
|
||||
for (i = 0; i < 256; i++)
|
||||
charMask[i] = -1;
|
||||
charMask[rs.Symbol] = 0;
|
||||
prevSuccess = 0;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
State s = tempState1.Initialize(Heap);
|
||||
int i;
|
||||
int freqSum, count, hiCnt;
|
||||
SEE2Context see;
|
||||
int num, numMasked = minContext.NumStats;
|
||||
do
|
||||
{
|
||||
orderFall++;
|
||||
minContext.Address = minContext.getSuffix();
|
||||
if (minContext.Address <= subAlloc.PText || minContext.Address > subAlloc.HeapEnd)
|
||||
return -1;
|
||||
}
|
||||
while (minContext.NumStats == numMasked);
|
||||
hiCnt = 0;
|
||||
s.Address = minContext.FreqData.GetStats();
|
||||
i = 0;
|
||||
num = minContext.NumStats - numMasked;
|
||||
do
|
||||
{
|
||||
int k = charMask[s.Symbol];
|
||||
hiCnt += s.Freq & k;
|
||||
minContext.ps[i] = s.Address;
|
||||
s.IncrementAddress();
|
||||
i -= k;
|
||||
}
|
||||
while (i != num);
|
||||
|
||||
see = minContext.makeEscFreq(this, numMasked, out freqSum);
|
||||
freqSum += hiCnt;
|
||||
count = (int)decoder.GetThreshold((uint)freqSum);
|
||||
|
||||
if (count < hiCnt)
|
||||
{
|
||||
byte symbol;
|
||||
State ps = tempState2.Initialize(Heap);
|
||||
for (hiCnt = 0, i = 0, ps.Address = minContext.ps[i]; (hiCnt += ps.Freq) <= count; i++, ps.Address = minContext.ps[i]);
|
||||
s.Address = ps.Address;
|
||||
decoder.Decode((uint)(hiCnt - s.Freq), (uint)s.Freq);
|
||||
see.update();
|
||||
symbol = (byte)s.Symbol;
|
||||
minContext.update2(this, s.Address);
|
||||
updateModel();
|
||||
return symbol;
|
||||
}
|
||||
if (count >= freqSum)
|
||||
return -2;
|
||||
decoder.Decode((uint)hiCnt, (uint)(freqSum - hiCnt));
|
||||
see.Summ = see.Summ + freqSum;
|
||||
do
|
||||
{
|
||||
s.Address = minContext.ps[--i];
|
||||
charMask[s.Symbol] = 0;
|
||||
}
|
||||
while (i != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
563
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/PPMContext.cs
vendored
Normal file
563
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/PPMContext.cs
vendored
Normal file
@@ -0,0 +1,563 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class PPMContext : Pointer
|
||||
{
|
||||
internal FreqData FreqData
|
||||
{
|
||||
get
|
||||
{
|
||||
return freqData;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.freqData.SummFreq = value.SummFreq;
|
||||
this.freqData.SetStats(value.GetStats());
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int NumStats
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Memory != null)
|
||||
{
|
||||
numStats = Utility.readShortLittleEndian(Memory, Address) & 0xffff;
|
||||
}
|
||||
return numStats;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.numStats = value & 0xffff;
|
||||
if (Memory != null)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address, (short)value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'unionSize '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
//UPGRADE_NOTE: The initialization of 'unionSize' was moved to static method 'SharpCompress.Unpack.PPM.PPMContext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
|
||||
private static readonly int unionSize;
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'size '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public static readonly int size = 2 + unionSize + 4; // 12
|
||||
|
||||
// ushort NumStats;
|
||||
private int numStats; // determines if feqData or onstate is used
|
||||
|
||||
// (1==onestate)
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'freqData '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private FreqData freqData; // -\
|
||||
|
||||
// |-> union
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'oneState '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State oneState; // -/
|
||||
|
||||
private int suffix; // pointer ppmcontext
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'ExpEscape'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public static readonly int[] ExpEscape = new int[] { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
|
||||
// Temp fields
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState1 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState2 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState3 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState3 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState4 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState4 = new State(null);
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'tempState5 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private State tempState5 = new State(null);
|
||||
private PPMContext tempPPMContext = null;
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'ps '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
internal int[] ps = new int[256];
|
||||
|
||||
public PPMContext(byte[] Memory)
|
||||
: base(Memory)
|
||||
{
|
||||
oneState = new State(Memory);
|
||||
freqData = new FreqData(Memory);
|
||||
}
|
||||
|
||||
internal PPMContext Initialize(byte[] mem)
|
||||
{
|
||||
oneState.Initialize(mem);
|
||||
freqData.Initialize(mem);
|
||||
return base.Initialize<PPMContext>(mem);
|
||||
}
|
||||
|
||||
internal State getOneState()
|
||||
{
|
||||
return oneState;
|
||||
}
|
||||
|
||||
internal void setOneState(StateRef oneState)
|
||||
{
|
||||
this.oneState.SetValues(oneState);
|
||||
}
|
||||
|
||||
internal int getSuffix()
|
||||
{
|
||||
if (Memory != null)
|
||||
{
|
||||
suffix = Utility.readIntLittleEndian(Memory, Address + 8);
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
|
||||
internal void setSuffix(PPMContext suffix)
|
||||
{
|
||||
setSuffix(suffix.Address);
|
||||
}
|
||||
|
||||
internal void setSuffix(int suffix)
|
||||
{
|
||||
this.suffix = suffix;
|
||||
if (Memory != null)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address + 8, suffix);
|
||||
}
|
||||
}
|
||||
|
||||
internal override int Address
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Address;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Address = value;
|
||||
oneState.Address = value + 2;
|
||||
freqData.Address = value + 2;
|
||||
}
|
||||
}
|
||||
|
||||
private PPMContext getTempPPMContext(byte[] Memory)
|
||||
{
|
||||
if (tempPPMContext == null)
|
||||
{
|
||||
tempPPMContext = new PPMContext(null);
|
||||
}
|
||||
return tempPPMContext.Initialize(Memory);
|
||||
}
|
||||
|
||||
internal int createChild(ModelPPM model, State pStats, StateRef firstState)
|
||||
{
|
||||
PPMContext pc = getTempPPMContext(model.SubAlloc.Heap);
|
||||
pc.Address = model.SubAlloc.allocContext();
|
||||
if (pc != null)
|
||||
{
|
||||
pc.NumStats = 1;
|
||||
pc.setOneState(firstState);
|
||||
pc.setSuffix(this);
|
||||
pStats.SetSuccessor(pc);
|
||||
}
|
||||
return pc.Address;
|
||||
}
|
||||
|
||||
internal void rescale(ModelPPM model)
|
||||
{
|
||||
int OldNS = NumStats, i = NumStats - 1, Adder, EscFreq;
|
||||
// STATE* p1, * p;
|
||||
State p1 = new State(model.Heap);
|
||||
State p = new State(model.Heap);
|
||||
State temp = new State(model.Heap);
|
||||
|
||||
for (p.Address = model.FoundState.Address; p.Address != freqData.GetStats(); p.DecrementAddress())
|
||||
{
|
||||
temp.Address = p.Address - State.Size;
|
||||
State.PPMDSwap(p, temp);
|
||||
}
|
||||
temp.Address = freqData.GetStats();
|
||||
temp.IncrementFreq(4);
|
||||
freqData.IncrementSummFreq(4);
|
||||
EscFreq = freqData.SummFreq - p.Freq;
|
||||
Adder = (model.OrderFall != 0) ? 1 : 0;
|
||||
p.Freq = Utility.URShift((p.Freq + Adder), 1);
|
||||
freqData.SummFreq = p.Freq;
|
||||
do
|
||||
{
|
||||
p.IncrementAddress();
|
||||
EscFreq -= p.Freq;
|
||||
p.Freq = Utility.URShift((p.Freq + Adder), 1);
|
||||
freqData.IncrementSummFreq(p.Freq);
|
||||
temp.Address = p.Address - State.Size;
|
||||
if (p.Freq > temp.Freq)
|
||||
{
|
||||
p1.Address = p.Address;
|
||||
StateRef tmp = new StateRef();
|
||||
tmp.Values = p1;
|
||||
State temp2 = new State(model.Heap);
|
||||
State temp3 = new State(model.Heap);
|
||||
do
|
||||
{
|
||||
// p1[0]=p1[-1];
|
||||
temp2.Address = p1.Address - State.Size;
|
||||
p1.SetValues(temp2);
|
||||
p1.DecrementAddress();
|
||||
temp3.Address = p1.Address - State.Size;
|
||||
}
|
||||
while (p1.Address != freqData.GetStats() && tmp.Freq > temp3.Freq);
|
||||
p1.SetValues(tmp);
|
||||
}
|
||||
}
|
||||
while (--i != 0);
|
||||
if (p.Freq == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
i++;
|
||||
p.DecrementAddress();
|
||||
}
|
||||
while (p.Freq == 0);
|
||||
EscFreq += i;
|
||||
NumStats = NumStats - i;
|
||||
if (NumStats == 1)
|
||||
{
|
||||
StateRef tmp = new StateRef();
|
||||
temp.Address = freqData.GetStats();
|
||||
tmp.Values = temp;
|
||||
// STATE tmp=*U.Stats;
|
||||
do
|
||||
{
|
||||
// tmp.Freq-=(tmp.Freq >> 1)
|
||||
tmp.DecrementFreq(Utility.URShift(tmp.Freq, 1));
|
||||
EscFreq = Utility.URShift(EscFreq, 1);
|
||||
}
|
||||
while (EscFreq > 1);
|
||||
model.SubAlloc.freeUnits(freqData.GetStats(), Utility.URShift((OldNS + 1), 1));
|
||||
oneState.SetValues(tmp);
|
||||
model.FoundState.Address = oneState.Address;
|
||||
return;
|
||||
}
|
||||
}
|
||||
EscFreq -= Utility.URShift(EscFreq, 1);
|
||||
freqData.IncrementSummFreq(EscFreq);
|
||||
int n0 = Utility.URShift((OldNS + 1), 1), n1 = Utility.URShift((NumStats + 1), 1);
|
||||
if (n0 != n1)
|
||||
{
|
||||
freqData.SetStats(model.SubAlloc.shrinkUnits(freqData.GetStats(), n0, n1));
|
||||
}
|
||||
model.FoundState.Address = freqData.GetStats();
|
||||
}
|
||||
|
||||
internal int getArrayIndex(ModelPPM Model, State rs)
|
||||
{
|
||||
PPMContext tempSuffix = getTempPPMContext(Model.SubAlloc.Heap);
|
||||
tempSuffix.Address = getSuffix();
|
||||
int ret = 0;
|
||||
ret += Model.PrevSuccess;
|
||||
ret += Model.getNS2BSIndx()[tempSuffix.NumStats - 1];
|
||||
ret += Model.HiBitsFlag + 2 * Model.getHB2Flag()[rs.Symbol];
|
||||
ret += ((Utility.URShift(Model.RunLength, 26)) & 0x20);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal int getMean(int summ, int shift, int round)
|
||||
{
|
||||
return (Utility.URShift((summ + (1 << (shift - round))), (shift)));
|
||||
}
|
||||
|
||||
internal void decodeBinSymbol(ModelPPM model)
|
||||
{
|
||||
State rs = tempState1.Initialize(model.Heap);
|
||||
rs.Address = oneState.Address; // State&
|
||||
model.HiBitsFlag = model.getHB2Flag()[model.FoundState.Symbol];
|
||||
int off1 = rs.Freq - 1;
|
||||
int off2 = getArrayIndex(model, rs);
|
||||
int bs = model.BinSumm[off1][off2];
|
||||
if (model.Coder.GetCurrentShiftCount(ModelPPM.TOT_BITS) < bs)
|
||||
{
|
||||
model.FoundState.Address = rs.Address;
|
||||
rs.IncrementFreq((rs.Freq < 128) ? 1 : 0);
|
||||
model.Coder.SubRange.LowCount = 0;
|
||||
model.Coder.SubRange.HighCount = bs;
|
||||
bs = ((bs + ModelPPM.INTERVAL - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xffff);
|
||||
model.BinSumm[off1][off2] = bs;
|
||||
model.PrevSuccess = 1;
|
||||
model.incRunLength(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
model.Coder.SubRange.LowCount = bs;
|
||||
bs = (bs - getMean(bs, ModelPPM.PERIOD_BITS, 2)) & 0xFFFF;
|
||||
model.BinSumm[off1][off2] = bs;
|
||||
model.Coder.SubRange.HighCount = ModelPPM.BIN_SCALE;
|
||||
model.InitEsc = ExpEscape[Utility.URShift(bs, 10)];
|
||||
model.NumMasked = 1;
|
||||
model.CharMask[rs.Symbol] = model.EscCount;
|
||||
model.PrevSuccess = 0;
|
||||
model.FoundState.Address = 0;
|
||||
}
|
||||
//int a = 0;//TODO just 4 debugging
|
||||
}
|
||||
|
||||
// public static void ppmdSwap(ModelPPM model, StatePtr state1, StatePtr state2)
|
||||
// {
|
||||
// byte[] bytes = model.getSubAlloc().getHeap();
|
||||
// int p1 = state1.Address;
|
||||
// int p2 = state2.Address;
|
||||
//
|
||||
// for (int i = 0; i < StatePtr.size; i++) {
|
||||
// byte temp = bytes[p1+i];
|
||||
// bytes[p1+i] = bytes[p2+i];
|
||||
// bytes[p2+i] = temp;
|
||||
// }
|
||||
// state1.Address=p1);
|
||||
// state2.Address=p2);
|
||||
// }
|
||||
|
||||
internal void update1(ModelPPM model, int p)
|
||||
{
|
||||
model.FoundState.Address = p;
|
||||
model.FoundState.IncrementFreq(4);
|
||||
freqData.IncrementSummFreq(4);
|
||||
State p0 = tempState3.Initialize(model.Heap);
|
||||
State p1 = tempState4.Initialize(model.Heap);
|
||||
p0.Address = p;
|
||||
p1.Address = p - State.Size;
|
||||
if (p0.Freq > p1.Freq)
|
||||
{
|
||||
State.PPMDSwap(p0, p1);
|
||||
model.FoundState.Address = p1.Address;
|
||||
if (p1.Freq > ModelPPM.MAX_FREQ)
|
||||
rescale(model);
|
||||
}
|
||||
}
|
||||
|
||||
internal void update1_0(ModelPPM model, int p)
|
||||
{
|
||||
model.FoundState.Address = p;
|
||||
model.PrevSuccess = 2 * model.FoundState.Freq > freqData.SummFreq ? 1 : 0;
|
||||
model.incRunLength(model.PrevSuccess);
|
||||
freqData.IncrementSummFreq(4);
|
||||
model.FoundState.IncrementFreq(4);
|
||||
if (model.FoundState.Freq > ModelPPM.MAX_FREQ)
|
||||
rescale(model);
|
||||
}
|
||||
|
||||
internal bool decodeSymbol2(ModelPPM model)
|
||||
{
|
||||
long count;
|
||||
int hiCnt, i = NumStats - model.NumMasked;
|
||||
SEE2Context psee2c = makeEscFreq2(model, i);
|
||||
RangeCoder coder = model.Coder;
|
||||
// STATE* ps[256], ** pps=ps, * p=U.Stats-1;
|
||||
State p = tempState1.Initialize(model.Heap);
|
||||
State temp = tempState2.Initialize(model.Heap);
|
||||
p.Address = freqData.GetStats() - State.Size;
|
||||
int pps = 0;
|
||||
hiCnt = 0;
|
||||
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
p.IncrementAddress(); // p++;
|
||||
}
|
||||
while (model.CharMask[p.Symbol] == model.EscCount);
|
||||
hiCnt += p.Freq;
|
||||
ps[pps++] = p.Address;
|
||||
}
|
||||
while (--i != 0);
|
||||
coder.SubRange.incScale(hiCnt);
|
||||
count = coder.CurrentCount;
|
||||
if (count >= coder.SubRange.Scale)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
pps = 0;
|
||||
p.Address = ps[pps];
|
||||
if (count < hiCnt)
|
||||
{
|
||||
hiCnt = 0;
|
||||
while ((hiCnt += p.Freq) <= count)
|
||||
{
|
||||
p.Address = ps[++pps]; // p=*++pps;
|
||||
}
|
||||
coder.SubRange.HighCount = hiCnt;
|
||||
coder.SubRange.LowCount = hiCnt - p.Freq;
|
||||
psee2c.update();
|
||||
update2(model, p.Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
coder.SubRange.LowCount = hiCnt;
|
||||
coder.SubRange.HighCount = coder.SubRange.Scale;
|
||||
i = NumStats - model.NumMasked; // ->NumMasked;
|
||||
pps--;
|
||||
do
|
||||
{
|
||||
temp.Address = ps[++pps]; // (*++pps)
|
||||
model.CharMask[temp.Symbol] = model.EscCount;
|
||||
}
|
||||
while (--i != 0);
|
||||
psee2c.incSumm((int)coder.SubRange.Scale);
|
||||
model.NumMasked = NumStats;
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
internal void update2(ModelPPM model, int p)
|
||||
{
|
||||
State temp = tempState5.Initialize(model.Heap);
|
||||
temp.Address = p;
|
||||
model.FoundState.Address = p;
|
||||
model.FoundState.IncrementFreq(4);
|
||||
freqData.IncrementSummFreq(4);
|
||||
if (temp.Freq > ModelPPM.MAX_FREQ)
|
||||
{
|
||||
rescale(model);
|
||||
}
|
||||
model.incEscCount(1);
|
||||
model.RunLength = model.InitRL;
|
||||
}
|
||||
|
||||
private SEE2Context makeEscFreq2(ModelPPM model, int Diff)
|
||||
{
|
||||
SEE2Context psee2c;
|
||||
int numStats = NumStats;
|
||||
if (numStats != 256)
|
||||
{
|
||||
PPMContext suff = getTempPPMContext(model.Heap);
|
||||
suff.Address = getSuffix();
|
||||
int idx1 = model.getNS2Indx()[Diff - 1];
|
||||
int idx2 = 0;
|
||||
idx2 += ((Diff < suff.NumStats - numStats) ? 1 : 0);
|
||||
idx2 += 2 * ((freqData.SummFreq < 11 * numStats) ? 1 : 0);
|
||||
idx2 += 4 * ((model.NumMasked > Diff) ? 1 : 0);
|
||||
idx2 += model.HiBitsFlag;
|
||||
psee2c = model.getSEE2Cont()[idx1][idx2];
|
||||
model.Coder.SubRange.Scale = psee2c.Mean;
|
||||
}
|
||||
else
|
||||
{
|
||||
psee2c = model.DummySEE2Cont;
|
||||
model.Coder.SubRange.Scale = 1;
|
||||
}
|
||||
return psee2c;
|
||||
}
|
||||
|
||||
internal SEE2Context makeEscFreq(ModelPPM model, int numMasked, out int escFreq)
|
||||
{
|
||||
SEE2Context psee2c;
|
||||
int numStats = NumStats;
|
||||
int nonMasked = numStats - numMasked;
|
||||
if (numStats != 256)
|
||||
{
|
||||
PPMContext suff = getTempPPMContext(model.Heap);
|
||||
suff.Address = getSuffix();
|
||||
int idx1 = model.getNS2Indx()[nonMasked - 1];
|
||||
int idx2 = 0;
|
||||
idx2 += ((nonMasked < suff.NumStats - numStats) ? 1 : 0);
|
||||
idx2 += 2 * ((freqData.SummFreq < 11 * numStats) ? 1 : 0);
|
||||
idx2 += 4 * ((numMasked > nonMasked) ? 1 : 0);
|
||||
idx2 += model.HiBitsFlag;
|
||||
psee2c = model.getSEE2Cont()[idx1][idx2];
|
||||
escFreq = psee2c.Mean;
|
||||
}
|
||||
else
|
||||
{
|
||||
psee2c = model.DummySEE2Cont;
|
||||
escFreq = 1;
|
||||
}
|
||||
return psee2c;
|
||||
}
|
||||
|
||||
internal bool decodeSymbol1(ModelPPM model)
|
||||
{
|
||||
|
||||
RangeCoder coder = model.Coder;
|
||||
coder.SubRange.Scale = freqData.SummFreq;
|
||||
State p = new State(model.Heap);
|
||||
p.Address = freqData.GetStats();
|
||||
int i, HiCnt;
|
||||
long count = coder.CurrentCount;
|
||||
if (count >= coder.SubRange.Scale)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (count < (HiCnt = p.Freq))
|
||||
{
|
||||
coder.SubRange.HighCount = HiCnt;
|
||||
model.PrevSuccess = (2 * HiCnt > coder.SubRange.Scale) ? 1 : 0;
|
||||
model.incRunLength(model.PrevSuccess);
|
||||
HiCnt += 4;
|
||||
model.FoundState.Address = p.Address;
|
||||
model.FoundState.Freq = HiCnt;
|
||||
freqData.IncrementSummFreq(4);
|
||||
if (HiCnt > ModelPPM.MAX_FREQ)
|
||||
{
|
||||
rescale(model);
|
||||
}
|
||||
coder.SubRange.LowCount = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (model.FoundState.Address == 0)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
model.PrevSuccess = 0;
|
||||
int numStats = NumStats;
|
||||
i = numStats - 1;
|
||||
while ((HiCnt += p.IncrementAddress().Freq) <= count)
|
||||
{
|
||||
if (--i == 0)
|
||||
{
|
||||
model.HiBitsFlag = model.getHB2Flag()[model.FoundState.Symbol];
|
||||
coder.SubRange.LowCount = HiCnt;
|
||||
model.CharMask[p.Symbol] = model.EscCount;
|
||||
model.NumMasked = numStats;
|
||||
i = numStats - 1;
|
||||
model.FoundState.Address = 0;
|
||||
do
|
||||
{
|
||||
model.CharMask[p.DecrementAddress().Symbol] = model.EscCount;
|
||||
}
|
||||
while (--i != 0);
|
||||
coder.SubRange.HighCount = coder.SubRange.Scale;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
coder.SubRange.LowCount = HiCnt - p.Freq;
|
||||
coder.SubRange.HighCount = HiCnt;
|
||||
update1(model, p.Address);
|
||||
return (true);
|
||||
}
|
||||
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("PPMContext[");
|
||||
buffer.Append("\n Address=");
|
||||
buffer.Append(Address);
|
||||
buffer.Append("\n size=");
|
||||
buffer.Append(size);
|
||||
buffer.Append("\n numStats=");
|
||||
buffer.Append(NumStats);
|
||||
buffer.Append("\n Suffix=");
|
||||
buffer.Append(getSuffix());
|
||||
buffer.Append("\n freqData=");
|
||||
buffer.Append(freqData);
|
||||
buffer.Append("\n oneState=");
|
||||
buffer.Append(oneState);
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
static PPMContext()
|
||||
{
|
||||
unionSize = System.Math.Max(FreqData.Size, State.Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/Pointer.cs
vendored
Normal file
34
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/Pointer.cs
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal abstract class Pointer
|
||||
{
|
||||
/// <summary> Initialize the object with the array (may be null)</summary>
|
||||
/// <param name="mem">the byte array
|
||||
/// </param>
|
||||
internal Pointer(byte[] mem)
|
||||
{
|
||||
Memory = mem;
|
||||
}
|
||||
|
||||
internal byte[] Memory
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
internal virtual int Address
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
protected T Initialize<T>(byte[] mem)
|
||||
where T : Pointer
|
||||
{
|
||||
Memory = mem;
|
||||
Address = 0;
|
||||
return this as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
183
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/RangeCoder.cs
vendored
Normal file
183
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/RangeCoder.cs
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class RangeCoder
|
||||
{
|
||||
internal const int TOP = 1 << 24;
|
||||
internal const int BOT = 1 << 15;
|
||||
internal const long UintMask = 0xFFFFffffL;
|
||||
|
||||
// uint low, code, range;
|
||||
private long low, code, range;
|
||||
private Stream stream;
|
||||
|
||||
internal RangeCoder(Stream stream)
|
||||
{
|
||||
this.stream = stream;
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
this.SubRange = new SubRange();
|
||||
|
||||
low = code = 0L;
|
||||
range = 0xFFFFffffL;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
code = ((code << 8) | Char) & UintMask;
|
||||
}
|
||||
}
|
||||
|
||||
internal int CurrentCount
|
||||
{
|
||||
get
|
||||
{
|
||||
range = (range / SubRange.Scale) & UintMask;
|
||||
return (int)((code - low) / (range));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private long Char
|
||||
{
|
||||
get
|
||||
{
|
||||
if (stream != null)
|
||||
return stream.ReadByte();
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal SubRange SubRange
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
|
||||
internal long GetCurrentShiftCount(int SHIFT)
|
||||
{
|
||||
range = Utility.URShift(range, SHIFT);
|
||||
return ((code - low) / (range)) & UintMask;
|
||||
}
|
||||
|
||||
internal void Decode()
|
||||
{
|
||||
low = (low + (range * SubRange.LowCount)) & UintMask;
|
||||
range = (range * (SubRange.HighCount - SubRange.LowCount)) & UintMask;
|
||||
}
|
||||
|
||||
internal void AriDecNormalize()
|
||||
{
|
||||
// while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true))
|
||||
// {
|
||||
// code = ((code << 8) | unpackRead.getChar()&0xff)&uintMask;
|
||||
// range = (range << 8)&uintMask;
|
||||
// low = (low << 8)&uintMask;
|
||||
// }
|
||||
|
||||
// Rewrote for clarity
|
||||
bool c2 = false;
|
||||
while ((low ^ (low + range)) < TOP || (c2 = range < BOT))
|
||||
{
|
||||
if (c2)
|
||||
{
|
||||
range = (-low & (BOT - 1)) & UintMask;
|
||||
c2 = false;
|
||||
}
|
||||
code = ((code << 8) | Char) & UintMask;
|
||||
range = (range << 8) & UintMask;
|
||||
low = (low << 8) & UintMask;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("RangeCoder[");
|
||||
buffer.Append("\n low=");
|
||||
buffer.Append(low);
|
||||
buffer.Append("\n code=");
|
||||
buffer.Append(code);
|
||||
buffer.Append("\n range=");
|
||||
buffer.Append(range);
|
||||
buffer.Append("\n subrange=");
|
||||
buffer.Append(SubRange);
|
||||
buffer.Append("]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
internal class SubRange
|
||||
{
|
||||
// uint LowCount, HighCount, scale;
|
||||
private long lowCount, highCount, scale;
|
||||
|
||||
internal void incScale(int dScale)
|
||||
{
|
||||
Scale = Scale + dScale;
|
||||
}
|
||||
|
||||
internal long HighCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return highCount;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.highCount = value & RangeCoder.UintMask;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal long LowCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return lowCount & RangeCoder.UintMask;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.lowCount = value & RangeCoder.UintMask;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal long Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
return scale;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.scale = value & RangeCoder.UintMask;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Debug
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("SubRange[");
|
||||
buffer.Append("\n lowCount=");
|
||||
buffer.Append(lowCount);
|
||||
buffer.Append("\n highCount=");
|
||||
buffer.Append(highCount);
|
||||
buffer.Append("\n scale=");
|
||||
buffer.Append(scale);
|
||||
buffer.Append("]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
125
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/RarMemBlock.cs
vendored
Normal file
125
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/RarMemBlock.cs
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class RarMemBlock : Pointer
|
||||
{
|
||||
public const int size = 12;
|
||||
|
||||
private int stamp, NU;
|
||||
|
||||
private int next, prev; // Pointer RarMemBlock
|
||||
|
||||
public RarMemBlock(byte[] Memory)
|
||||
: base(Memory)
|
||||
{
|
||||
}
|
||||
|
||||
internal int Stamp
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Memory != null)
|
||||
{
|
||||
stamp = Utility.readShortLittleEndian(Memory, Address) & 0xffff;
|
||||
}
|
||||
return stamp;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.stamp = value;
|
||||
if (Memory != null)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address, (short)value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal void InsertAt(RarMemBlock p)
|
||||
{
|
||||
RarMemBlock temp = new RarMemBlock(Memory);
|
||||
SetPrev(p.Address);
|
||||
temp.Address = GetPrev();
|
||||
SetNext(temp.GetNext()); // prev.getNext();
|
||||
temp.SetNext(this); // prev.setNext(this);
|
||||
temp.Address = GetNext();
|
||||
temp.SetPrev(this); // next.setPrev(this);
|
||||
}
|
||||
|
||||
internal void Remove()
|
||||
{
|
||||
RarMemBlock temp = new RarMemBlock(Memory);
|
||||
temp.Address = GetPrev();
|
||||
temp.SetNext(GetNext()); // prev.setNext(next);
|
||||
temp.Address = GetNext();
|
||||
temp.SetPrev(GetPrev()); // next.setPrev(prev);
|
||||
// next = -1;
|
||||
// prev = -1;
|
||||
}
|
||||
|
||||
internal int GetNext()
|
||||
{
|
||||
if (Memory != null)
|
||||
{
|
||||
next = Utility.readIntLittleEndian(Memory, Address + 4);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
internal void SetNext(RarMemBlock next)
|
||||
{
|
||||
SetNext(next.Address);
|
||||
}
|
||||
|
||||
internal void SetNext(int next)
|
||||
{
|
||||
this.next = next;
|
||||
if (Memory != null)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address + 4, next);
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetNU()
|
||||
{
|
||||
if (Memory != null)
|
||||
{
|
||||
NU = Utility.readShortLittleEndian(Memory, Address + 2) & 0xffff;
|
||||
}
|
||||
return NU;
|
||||
}
|
||||
|
||||
internal void SetNU(int nu)
|
||||
{
|
||||
NU = nu & 0xffff;
|
||||
if (Memory != null)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address + 2, (short)nu);
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetPrev()
|
||||
{
|
||||
if (Memory != null)
|
||||
{
|
||||
prev = Utility.readIntLittleEndian(Memory, Address + 8);
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
internal void SetPrev(RarMemBlock prev)
|
||||
{
|
||||
SetPrev(prev.Address);
|
||||
}
|
||||
|
||||
internal void SetPrev(int prev)
|
||||
{
|
||||
this.prev = prev;
|
||||
if (Memory != null)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address + 8, prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/RarNode.cs
vendored
Normal file
53
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/RarNode.cs
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class RarNode : Pointer
|
||||
{
|
||||
private int next; //rarnode pointer
|
||||
|
||||
public const int size = 4;
|
||||
|
||||
public RarNode(byte[] Memory)
|
||||
: base(Memory)
|
||||
{
|
||||
}
|
||||
|
||||
internal int GetNext()
|
||||
{
|
||||
if (Memory != null)
|
||||
{
|
||||
next = Utility.readIntLittleEndian(Memory, Address);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
internal void SetNext(RarNode next)
|
||||
{
|
||||
SetNext(next.Address);
|
||||
}
|
||||
|
||||
internal void SetNext(int next)
|
||||
{
|
||||
this.next = next;
|
||||
if (Memory != null)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address, next);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("State[");
|
||||
buffer.Append("\n Address=");
|
||||
buffer.Append(Address);
|
||||
buffer.Append("\n size=");
|
||||
buffer.Append(size);
|
||||
buffer.Append("\n next=");
|
||||
buffer.Append(GetNext());
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
107
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/SEE2Context.cs
vendored
Normal file
107
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/SEE2Context.cs
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class SEE2Context
|
||||
{
|
||||
virtual public int Mean
|
||||
{
|
||||
get
|
||||
{
|
||||
int retVal = Utility.URShift(summ, shift);
|
||||
summ -= retVal;
|
||||
return retVal + ((retVal == 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.count = value & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int Shift
|
||||
{
|
||||
get
|
||||
{
|
||||
return shift;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.shift = value & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int Summ
|
||||
{
|
||||
get
|
||||
{
|
||||
return summ;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.summ = value & 0xffff;
|
||||
}
|
||||
|
||||
}
|
||||
public const int size = 4;
|
||||
|
||||
// ushort Summ;
|
||||
private int summ;
|
||||
|
||||
// byte Shift;
|
||||
private int shift;
|
||||
|
||||
// byte Count;
|
||||
private int count;
|
||||
|
||||
public void Initialize(int initVal)
|
||||
{
|
||||
shift = (ModelPPM.PERIOD_BITS - 4) & 0xff;
|
||||
summ = (initVal << shift) & 0xffff;
|
||||
count = 4;
|
||||
}
|
||||
|
||||
public virtual void update()
|
||||
{
|
||||
if (shift < ModelPPM.PERIOD_BITS && --count == 0)
|
||||
{
|
||||
summ += summ;
|
||||
count = (3 << shift++);
|
||||
}
|
||||
summ &= 0xffff;
|
||||
count &= 0xff;
|
||||
shift &= 0xff;
|
||||
}
|
||||
|
||||
public virtual void incSumm(int dSumm)
|
||||
{
|
||||
Summ = Summ + dSumm;
|
||||
}
|
||||
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("SEE2Context[");
|
||||
buffer.Append("\n size=");
|
||||
buffer.Append(size);
|
||||
buffer.Append("\n summ=");
|
||||
buffer.Append(summ);
|
||||
buffer.Append("\n shift=");
|
||||
buffer.Append(shift);
|
||||
buffer.Append("\n count=");
|
||||
buffer.Append(count);
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
120
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/State.cs
vendored
Normal file
120
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/State.cs
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class State : Pointer
|
||||
{
|
||||
internal const int Size = 6;
|
||||
|
||||
internal State(byte[] Memory)
|
||||
: base(Memory)
|
||||
{
|
||||
}
|
||||
|
||||
internal int Symbol
|
||||
{
|
||||
get
|
||||
{
|
||||
return Memory[Address] & 0xff;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Memory[Address] = (byte)value;
|
||||
}
|
||||
|
||||
}
|
||||
internal int Freq
|
||||
{
|
||||
get
|
||||
{
|
||||
return Memory[Address + 1] & 0xff;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Memory[Address + 1] = (byte)value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal State Initialize(byte[] mem)
|
||||
{
|
||||
return base.Initialize<State>(mem);
|
||||
}
|
||||
|
||||
internal void IncrementFreq(int dFreq)
|
||||
{
|
||||
Memory[Address + 1] = (byte)(Memory[Address + 1] + dFreq);
|
||||
}
|
||||
|
||||
internal int GetSuccessor()
|
||||
{
|
||||
return Utility.readIntLittleEndian(Memory, Address + 2);
|
||||
}
|
||||
|
||||
internal void SetSuccessor(PPMContext successor)
|
||||
{
|
||||
SetSuccessor(successor.Address);
|
||||
}
|
||||
|
||||
internal void SetSuccessor(int successor)
|
||||
{
|
||||
Utility.WriteLittleEndian(Memory, Address + 2, successor);
|
||||
}
|
||||
|
||||
internal void SetValues(StateRef state)
|
||||
{
|
||||
Symbol = state.Symbol;
|
||||
Freq = state.Freq;
|
||||
SetSuccessor(state.GetSuccessor());
|
||||
}
|
||||
|
||||
internal void SetValues(State ptr)
|
||||
{
|
||||
Array.Copy(ptr.Memory, ptr.Address, Memory, Address, Size);
|
||||
}
|
||||
|
||||
internal State DecrementAddress()
|
||||
{
|
||||
Address = Address - Size;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal State IncrementAddress()
|
||||
{
|
||||
Address = Address + Size;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal static void PPMDSwap(State ptr1, State ptr2)
|
||||
{
|
||||
byte[] mem1 = ptr1.Memory, mem2 = ptr2.Memory;
|
||||
for (int i = 0, pos1 = ptr1.Address, pos2 = ptr2.Address; i < Size; i++, pos1++, pos2++)
|
||||
{
|
||||
byte temp = mem1[pos1];
|
||||
mem1[pos1] = mem2[pos2];
|
||||
mem2[pos2] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("State[");
|
||||
buffer.Append("\n Address=");
|
||||
buffer.Append(Address);
|
||||
buffer.Append("\n size=");
|
||||
buffer.Append(Size);
|
||||
buffer.Append("\n symbol=");
|
||||
buffer.Append(Symbol);
|
||||
buffer.Append("\n freq=");
|
||||
buffer.Append(Freq);
|
||||
buffer.Append("\n successor=");
|
||||
buffer.Append(GetSuccessor());
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
90
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/StateRef.cs
vendored
Normal file
90
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/StateRef.cs
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class StateRef
|
||||
{
|
||||
private int symbol;
|
||||
|
||||
private int freq;
|
||||
|
||||
private int successor; // pointer ppmcontext
|
||||
|
||||
internal int Symbol
|
||||
{
|
||||
get
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.symbol = value & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
internal int Freq
|
||||
{
|
||||
get
|
||||
{
|
||||
return freq;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.freq = value & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal State Values
|
||||
{
|
||||
set
|
||||
{
|
||||
Freq = value.Freq;
|
||||
SetSuccessor(value.GetSuccessor());
|
||||
Symbol = value.Symbol;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual void IncrementFreq(int dFreq)
|
||||
{
|
||||
freq = (freq + dFreq) & 0xff;
|
||||
}
|
||||
|
||||
public virtual void DecrementFreq(int dFreq)
|
||||
{
|
||||
freq = (freq - dFreq) & 0xff;
|
||||
}
|
||||
|
||||
public virtual int GetSuccessor()
|
||||
{
|
||||
return successor;
|
||||
}
|
||||
|
||||
public virtual void SetSuccessor(PPMContext successor)
|
||||
{
|
||||
SetSuccessor(successor.Address);
|
||||
}
|
||||
|
||||
public virtual void SetSuccessor(int successor)
|
||||
{
|
||||
this.successor = successor;
|
||||
}
|
||||
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("State[");
|
||||
buffer.Append("\n symbol=");
|
||||
buffer.Append(Symbol);
|
||||
buffer.Append("\n freq=");
|
||||
buffer.Append(Freq);
|
||||
buffer.Append("\n successor=");
|
||||
buffer.Append(GetSuccessor());
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
489
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/SubAllocator.cs
vendored
Normal file
489
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/H/SubAllocator.cs
vendored
Normal file
@@ -0,0 +1,489 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.H
|
||||
{
|
||||
internal class SubAllocator
|
||||
{
|
||||
virtual public int FakeUnitsStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return fakeUnitsStart;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.fakeUnitsStart = value;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int HeapEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
return heapEnd;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int PText
|
||||
{
|
||||
get
|
||||
{
|
||||
return pText;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
pText = value;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public int UnitsStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return unitsStart;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.unitsStart = value;
|
||||
}
|
||||
|
||||
}
|
||||
virtual public byte[] Heap
|
||||
{
|
||||
get
|
||||
{
|
||||
return heap;
|
||||
}
|
||||
|
||||
}
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'N4 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public const int N1 = 4;
|
||||
public const int N2 = 4;
|
||||
public const int N3 = 4;
|
||||
public static readonly int N4 = (128 + 3 - 1 * N1 - 2 * N2 - 3 * N3) / 4;
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'N_INDEXES '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
public static readonly int N_INDEXES = N1 + N2 + N3 + N4;
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'UNIT_SIZE '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
//UPGRADE_NOTE: The initialization of 'UNIT_SIZE' was moved to static method 'SharpCompress.Unpack.PPM.SubAllocator'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
|
||||
public static readonly int UNIT_SIZE;
|
||||
|
||||
public const int FIXED_UNIT_SIZE = 12;
|
||||
|
||||
private int subAllocatorSize;
|
||||
|
||||
// byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
|
||||
private int[] indx2Units = new int[N_INDEXES];
|
||||
private int[] units2Indx = new int[128];
|
||||
private int glueCount;
|
||||
|
||||
// byte *HeapStart,*LoUnit, *HiUnit;
|
||||
private int heapStart, loUnit, hiUnit;
|
||||
|
||||
//UPGRADE_NOTE: Final was removed from the declaration of 'freeList '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
|
||||
private RarNode[] freeList = new RarNode[N_INDEXES];
|
||||
|
||||
// byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart;
|
||||
private int pText, unitsStart, heapEnd, fakeUnitsStart;
|
||||
|
||||
private byte[] heap;
|
||||
|
||||
private int freeListPos;
|
||||
|
||||
private int tempMemBlockPos;
|
||||
|
||||
// Temp fields
|
||||
private RarNode tempRarNode = null;
|
||||
private RarMemBlock tempRarMemBlock1 = null;
|
||||
private RarMemBlock tempRarMemBlock2 = null;
|
||||
private RarMemBlock tempRarMemBlock3 = null;
|
||||
|
||||
public SubAllocator()
|
||||
{
|
||||
clean();
|
||||
}
|
||||
|
||||
public virtual void clean()
|
||||
{
|
||||
subAllocatorSize = 0;
|
||||
}
|
||||
|
||||
private void insertNode(int p, int indx)
|
||||
{
|
||||
RarNode temp = tempRarNode;
|
||||
temp.Address = p;
|
||||
temp.SetNext(freeList[indx].GetNext());
|
||||
freeList[indx].SetNext(temp);
|
||||
}
|
||||
|
||||
public virtual void incPText()
|
||||
{
|
||||
pText++;
|
||||
}
|
||||
|
||||
private int removeNode(int indx)
|
||||
{
|
||||
int retVal = freeList[indx].GetNext();
|
||||
RarNode temp = tempRarNode;
|
||||
temp.Address = retVal;
|
||||
freeList[indx].SetNext(temp.GetNext());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private int U2B(int NU)
|
||||
{
|
||||
return UNIT_SIZE * NU;
|
||||
}
|
||||
|
||||
/* memblockptr */
|
||||
private int MBPtr(int BasePtr, int Items)
|
||||
{
|
||||
return (BasePtr + U2B(Items));
|
||||
}
|
||||
|
||||
private void splitBlock(int pv, int oldIndx, int newIndx)
|
||||
{
|
||||
int i, uDiff = indx2Units[oldIndx] - indx2Units[newIndx];
|
||||
int p = pv + U2B(indx2Units[newIndx]);
|
||||
if (indx2Units[i = units2Indx[uDiff - 1]] != uDiff)
|
||||
{
|
||||
insertNode(p, --i);
|
||||
p += U2B(i = indx2Units[i]);
|
||||
uDiff -= i;
|
||||
}
|
||||
insertNode(p, units2Indx[uDiff - 1]);
|
||||
}
|
||||
|
||||
public virtual void stopSubAllocator()
|
||||
{
|
||||
if (subAllocatorSize != 0)
|
||||
{
|
||||
subAllocatorSize = 0;
|
||||
//ArrayFactory.BYTES_FACTORY.recycle(heap);
|
||||
heap = null;
|
||||
heapStart = 1;
|
||||
// rarfree(HeapStart);
|
||||
// Free temp fields
|
||||
tempRarNode = null;
|
||||
tempRarMemBlock1 = null;
|
||||
tempRarMemBlock2 = null;
|
||||
tempRarMemBlock3 = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int GetAllocatedMemory()
|
||||
{
|
||||
return subAllocatorSize;
|
||||
}
|
||||
|
||||
|
||||
public virtual bool startSubAllocator(int SASize)
|
||||
{
|
||||
int t = SASize;
|
||||
if (subAllocatorSize == t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
stopSubAllocator();
|
||||
int allocSize = t / FIXED_UNIT_SIZE * UNIT_SIZE + UNIT_SIZE;
|
||||
|
||||
// adding space for freelist (needed for poiters)
|
||||
// 1+ for null pointer
|
||||
int realAllocSize = 1 + allocSize + 4 * N_INDEXES;
|
||||
// adding space for an additional memblock
|
||||
tempMemBlockPos = realAllocSize;
|
||||
realAllocSize += RarMemBlock.size;
|
||||
|
||||
heap = new byte[realAllocSize];
|
||||
heapStart = 1;
|
||||
heapEnd = heapStart + allocSize - UNIT_SIZE;
|
||||
subAllocatorSize = t;
|
||||
// Bug fixed
|
||||
freeListPos = heapStart + allocSize;
|
||||
//UPGRADE_ISSUE: The following fragment of code could not be parsed and was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1156'"
|
||||
//assert(realAllocSize - tempMemBlockPos == RarMemBlock.size): realAllocSize
|
||||
//+ + tempMemBlockPos + + RarMemBlock.size;
|
||||
|
||||
// Init freeList
|
||||
for (int i = 0, pos = freeListPos; i < freeList.Length; i++, pos += RarNode.size)
|
||||
{
|
||||
freeList[i] = new RarNode(heap);
|
||||
freeList[i].Address = pos;
|
||||
}
|
||||
|
||||
// Init temp fields
|
||||
tempRarNode = new RarNode(heap);
|
||||
tempRarMemBlock1 = new RarMemBlock(heap);
|
||||
tempRarMemBlock2 = new RarMemBlock(heap);
|
||||
tempRarMemBlock3 = new RarMemBlock(heap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void glueFreeBlocks()
|
||||
{
|
||||
RarMemBlock s0 = tempRarMemBlock1;
|
||||
s0.Address = tempMemBlockPos;
|
||||
RarMemBlock p = tempRarMemBlock2;
|
||||
RarMemBlock p1 = tempRarMemBlock3;
|
||||
int i, k, sz;
|
||||
if (loUnit != hiUnit)
|
||||
{
|
||||
heap[loUnit] = 0;
|
||||
}
|
||||
for (i = 0, s0.SetPrev(s0), s0.SetNext(s0); i < N_INDEXES; i++)
|
||||
{
|
||||
while (freeList[i].GetNext() != 0)
|
||||
{
|
||||
p.Address = removeNode(i); // =(RAR_MEM_BLK*)RemoveNode(i);
|
||||
p.InsertAt(s0); // p->insertAt(&s0);
|
||||
p.Stamp = 0xFFFF; // p->Stamp=0xFFFF;
|
||||
p.SetNU(indx2Units[i]); // p->NU=Indx2Units[i];
|
||||
}
|
||||
}
|
||||
for (p.Address = s0.GetNext(); p.Address != s0.Address; p.Address = p.GetNext())
|
||||
{
|
||||
// while ((p1=MBPtr(p,p->NU))->Stamp == 0xFFFF && int(p->NU)+p1->NU
|
||||
// < 0x10000)
|
||||
// Bug fixed
|
||||
p1.Address = MBPtr(p.Address, p.GetNU());
|
||||
while (p1.Stamp == 0xFFFF && p.GetNU() + p1.GetNU() < 0x10000)
|
||||
{
|
||||
p1.Remove();
|
||||
p.SetNU(p.GetNU() + p1.GetNU()); // ->NU += p1->NU;
|
||||
p1.Address = MBPtr(p.Address, p.GetNU());
|
||||
}
|
||||
}
|
||||
// while ((p=s0.next) != &s0)
|
||||
// Bug fixed
|
||||
p.Address = s0.GetNext();
|
||||
while (p.Address != s0.Address)
|
||||
{
|
||||
for (p.Remove(), sz = p.GetNU(); sz > 128; sz -= 128, p.Address = MBPtr(p.Address, 128))
|
||||
{
|
||||
insertNode(p.Address, N_INDEXES - 1);
|
||||
}
|
||||
if (indx2Units[i = units2Indx[sz - 1]] != sz)
|
||||
{
|
||||
k = sz - indx2Units[--i];
|
||||
insertNode(MBPtr(p.Address, sz - k), k - 1);
|
||||
}
|
||||
insertNode(p.Address, i);
|
||||
p.Address = s0.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
private int allocUnitsRare(int indx)
|
||||
{
|
||||
if (glueCount == 0)
|
||||
{
|
||||
glueCount = 255;
|
||||
glueFreeBlocks();
|
||||
if (freeList[indx].GetNext() != 0)
|
||||
{
|
||||
return removeNode(indx);
|
||||
}
|
||||
}
|
||||
int i = indx;
|
||||
do
|
||||
{
|
||||
if (++i == N_INDEXES)
|
||||
{
|
||||
glueCount--;
|
||||
i = U2B(indx2Units[indx]);
|
||||
int j = FIXED_UNIT_SIZE * indx2Units[indx];
|
||||
if (fakeUnitsStart - pText > j)
|
||||
{
|
||||
fakeUnitsStart -= j;
|
||||
unitsStart -= i;
|
||||
return unitsStart;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
while (freeList[i].GetNext() == 0);
|
||||
int retVal = removeNode(i);
|
||||
splitBlock(retVal, i, indx);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public virtual int allocUnits(int NU)
|
||||
{
|
||||
int indx = units2Indx[NU - 1];
|
||||
if (freeList[indx].GetNext() != 0)
|
||||
{
|
||||
return removeNode(indx);
|
||||
}
|
||||
int retVal = loUnit;
|
||||
loUnit += U2B(indx2Units[indx]);
|
||||
if (loUnit <= hiUnit)
|
||||
{
|
||||
return retVal;
|
||||
}
|
||||
loUnit -= U2B(indx2Units[indx]);
|
||||
return allocUnitsRare(indx);
|
||||
}
|
||||
|
||||
public virtual int allocContext()
|
||||
{
|
||||
if (hiUnit != loUnit)
|
||||
return (hiUnit -= UNIT_SIZE);
|
||||
if (freeList[0].GetNext() != 0)
|
||||
{
|
||||
return removeNode(0);
|
||||
}
|
||||
return allocUnitsRare(0);
|
||||
}
|
||||
|
||||
public virtual int expandUnits(int oldPtr, int OldNU)
|
||||
{
|
||||
int i0 = units2Indx[OldNU - 1];
|
||||
int i1 = units2Indx[OldNU - 1 + 1];
|
||||
if (i0 == i1)
|
||||
{
|
||||
return oldPtr;
|
||||
}
|
||||
int ptr = allocUnits(OldNU + 1);
|
||||
if (ptr != 0)
|
||||
{
|
||||
// memcpy(ptr,OldPtr,U2B(OldNU));
|
||||
Array.Copy(heap, oldPtr, heap, ptr, U2B(OldNU));
|
||||
insertNode(oldPtr, i0);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
public virtual int shrinkUnits(int oldPtr, int oldNU, int newNU)
|
||||
{
|
||||
// System.out.println("SubAllocator.shrinkUnits(" + OldPtr + ", " +
|
||||
// OldNU + ", " + NewNU + ")");
|
||||
int i0 = units2Indx[oldNU - 1];
|
||||
int i1 = units2Indx[newNU - 1];
|
||||
if (i0 == i1)
|
||||
{
|
||||
return oldPtr;
|
||||
}
|
||||
if (freeList[i1].GetNext() != 0)
|
||||
{
|
||||
int ptr = removeNode(i1);
|
||||
// memcpy(ptr,OldPtr,U2B(NewNU));
|
||||
// for (int i = 0; i < U2B(NewNU); i++) {
|
||||
// heap[ptr + i] = heap[OldPtr + i];
|
||||
// }
|
||||
Array.Copy(heap, oldPtr, heap, ptr, U2B(newNU));
|
||||
insertNode(oldPtr, i0);
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
splitBlock(oldPtr, i0, i1);
|
||||
return oldPtr;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void freeUnits(int ptr, int OldNU)
|
||||
{
|
||||
insertNode(ptr, units2Indx[OldNU - 1]);
|
||||
}
|
||||
|
||||
public virtual void decPText(int dPText)
|
||||
{
|
||||
PText = PText - dPText;
|
||||
}
|
||||
|
||||
public virtual void initSubAllocator()
|
||||
{
|
||||
int i, k;
|
||||
Utility.Fill(heap, freeListPos, freeListPos + sizeOfFreeList(), (byte)0);
|
||||
|
||||
pText = heapStart;
|
||||
|
||||
int size2 = FIXED_UNIT_SIZE * (subAllocatorSize / 8 / FIXED_UNIT_SIZE * 7);
|
||||
int realSize2 = size2 / FIXED_UNIT_SIZE * UNIT_SIZE;
|
||||
int size1 = subAllocatorSize - size2;
|
||||
int realSize1 = size1 / FIXED_UNIT_SIZE * UNIT_SIZE + size1 % FIXED_UNIT_SIZE;
|
||||
hiUnit = heapStart + subAllocatorSize;
|
||||
loUnit = unitsStart = heapStart + realSize1;
|
||||
fakeUnitsStart = heapStart + size1;
|
||||
hiUnit = loUnit + realSize2;
|
||||
|
||||
for (i = 0, k = 1; i < N1; i++, k += 1)
|
||||
{
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
for (k++; i < N1 + N2; i++, k += 2)
|
||||
{
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
for (k++; i < N1 + N2 + N3; i++, k += 3)
|
||||
{
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
for (k++; i < (N1 + N2 + N3 + N4); i++, k += 4)
|
||||
{
|
||||
indx2Units[i] = k & 0xff;
|
||||
}
|
||||
|
||||
for (glueCount = 0, k = 0, i = 0; k < 128; k++)
|
||||
{
|
||||
i += ((indx2Units[i] < (k + 1)) ? 1 : 0);
|
||||
units2Indx[k] = i & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
private int sizeOfFreeList()
|
||||
{
|
||||
return freeList.Length * RarNode.size;
|
||||
}
|
||||
|
||||
// Debug
|
||||
// public void dumpHeap() {
|
||||
// File file = new File("P:\\test\\heapdumpj");
|
||||
// OutputStream out = null;
|
||||
// try {
|
||||
// out = new FileOutputStream(file);
|
||||
// out.write(heap, heapStart, heapEnd - heapStart);
|
||||
// out.flush();
|
||||
// System.out.println("Heap dumped to " + file.getAbsolutePath());
|
||||
// }
|
||||
// catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// finally {
|
||||
// FileUtil.close(out);
|
||||
// }
|
||||
// }
|
||||
|
||||
// Debug
|
||||
public override System.String ToString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.Append("SubAllocator[");
|
||||
buffer.Append("\n subAllocatorSize=");
|
||||
buffer.Append(subAllocatorSize);
|
||||
buffer.Append("\n glueCount=");
|
||||
buffer.Append(glueCount);
|
||||
buffer.Append("\n heapStart=");
|
||||
buffer.Append(heapStart);
|
||||
buffer.Append("\n loUnit=");
|
||||
buffer.Append(loUnit);
|
||||
buffer.Append("\n hiUnit=");
|
||||
buffer.Append(hiUnit);
|
||||
buffer.Append("\n pText=");
|
||||
buffer.Append(pText);
|
||||
buffer.Append("\n unitsStart=");
|
||||
buffer.Append(unitsStart);
|
||||
buffer.Append("\n]");
|
||||
return buffer.ToString();
|
||||
}
|
||||
static SubAllocator()
|
||||
{
|
||||
UNIT_SIZE = System.Math.Max(PPMContext.size, RarMemBlock.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
457
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Allocator.cs
vendored
Normal file
457
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Allocator.cs
vendored
Normal file
@@ -0,0 +1,457 @@
|
||||
#region Using
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
|
||||
/// Allocate a single, large array and then provide sections of this array to callers. Callers are provided with
|
||||
/// instances of <see cref="Pointer"/> (which simply contain a single address value, representing a location
|
||||
/// in the large array). Callers can then cast <see cref="Pointer"/> to one of the following structures (all
|
||||
/// of which also simply contain a single address value):
|
||||
internal class Allocator
|
||||
{
|
||||
private const uint UnitSize = 12;
|
||||
private const uint LocalOffset = 4; // reserve the first four bytes for Pointer.Zero
|
||||
private const uint NodeOffset = LocalOffset + MemoryNode.Size; // reserve space for a single memory node
|
||||
private const uint HeapOffset = NodeOffset + IndexCount * MemoryNode.Size; // reserve space for the array of memory nodes
|
||||
private const uint N1 = 4;
|
||||
private const uint N2 = 4;
|
||||
private const uint N3 = 4;
|
||||
private const uint N4 = (128 + 3 - 1 * N1 - 2 * N2 - 3 * N3) / 4;
|
||||
private const uint IndexCount = N1 + N2 + N3 + N4;
|
||||
|
||||
private static readonly byte[] indexToUnits;
|
||||
private static readonly byte[] unitsToIndex;
|
||||
|
||||
public uint AllocatorSize;
|
||||
public uint GlueCount;
|
||||
public Pointer BaseUnit;
|
||||
public Pointer LowUnit;
|
||||
public Pointer HighUnit;
|
||||
public Pointer Text;
|
||||
public Pointer Heap;
|
||||
public MemoryNode[] MemoryNodes;
|
||||
|
||||
public byte[] Memory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes static read-only arrays used by the <see cref="Allocator"/>.
|
||||
/// </summary>
|
||||
static Allocator()
|
||||
{
|
||||
// Construct the static index to units lookup array. It will contain the following values.
|
||||
//
|
||||
// 1 2 3 4 6 8 10 12 15 18 21 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108
|
||||
// 112 116 120 124 128
|
||||
|
||||
uint index;
|
||||
uint unitCount;
|
||||
|
||||
indexToUnits = new byte[IndexCount];
|
||||
|
||||
for (index = 0, unitCount = 1; index < N1; index++, unitCount += 1)
|
||||
indexToUnits[index] = (byte)unitCount;
|
||||
|
||||
for (unitCount++; index < N1 + N2; index++, unitCount += 2)
|
||||
indexToUnits[index] = (byte)unitCount;
|
||||
|
||||
for (unitCount++; index < N1 + N2 + N3; index++, unitCount += 3)
|
||||
indexToUnits[index] = (byte)unitCount;
|
||||
|
||||
for (unitCount++; index < N1 + N2 + N3 + N4; index++, unitCount += 4)
|
||||
indexToUnits[index] = (byte)unitCount;
|
||||
|
||||
// Construct the static units to index lookup array. It will contain the following values.
|
||||
//
|
||||
// 00 01 02 03 04 04 05 05 06 06 07 07 08 08 08 09 09 09 10 10 10 11 11 11 12 12 12 12 13 13 13 13
|
||||
// 14 14 14 14 15 15 15 15 16 16 16 16 17 17 17 17 18 18 18 18 19 19 19 19 20 20 20 20 21 21 21 21
|
||||
// 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 27 27 27 27 28 28 28 28 29 29 29 29
|
||||
// 30 30 30 30 31 31 31 31 32 32 32 32 33 33 33 33 34 34 34 34 35 35 35 35 36 36 36 36 37 37 37 37
|
||||
|
||||
unitsToIndex = new byte[128];
|
||||
|
||||
for (unitCount = index = 0; unitCount < 128; unitCount++)
|
||||
{
|
||||
index += (uint)((indexToUnits[index] < unitCount + 1) ? 1 : 0);
|
||||
unitsToIndex[unitCount] = (byte)index;
|
||||
}
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public Allocator()
|
||||
{
|
||||
MemoryNodes = new MemoryNode[IndexCount];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize or reset the memory allocator (so that the single, large array can be re-used without destroying
|
||||
/// and re-creating it).
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
for (int index = 0; index < IndexCount; index++)
|
||||
{
|
||||
MemoryNodes[index] = new MemoryNode((uint)(NodeOffset + index * MemoryNode.Size), Memory);
|
||||
MemoryNodes[index].Stamp = 0;
|
||||
MemoryNodes[index].Next = MemoryNode.Zero;
|
||||
MemoryNodes[index].UnitCount = 0;
|
||||
}
|
||||
|
||||
Text = Heap;
|
||||
|
||||
uint difference = UnitSize * (AllocatorSize / 8 / UnitSize * 7);
|
||||
|
||||
HighUnit = Heap + AllocatorSize;
|
||||
LowUnit = HighUnit - difference;
|
||||
BaseUnit = HighUnit - difference;
|
||||
|
||||
GlueCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the allocator (create a single, large array of bytes).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that .NET will create that array on the large object heap (because it is so large).
|
||||
/// </remarks>
|
||||
/// <param name="allocatorSize"></param>
|
||||
public void Start(int allocatorSize)
|
||||
{
|
||||
uint size = (uint)allocatorSize;
|
||||
if (AllocatorSize != size)
|
||||
{
|
||||
Stop();
|
||||
Memory = new byte[HeapOffset + size]; // the single, large array of bytes
|
||||
Heap = new Pointer(HeapOffset, Memory); // reserve bytes in the range 0 .. HeapOffset - 1
|
||||
AllocatorSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the allocator (free the single, large array of bytes). This can safely be called multiple times (without
|
||||
/// intervening calls to <see cref="Start"/>).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Because the array is on the large object heap it may not be freed immediately.
|
||||
/// </remarks>
|
||||
public void Stop()
|
||||
{
|
||||
if (AllocatorSize != 0)
|
||||
{
|
||||
AllocatorSize = 0;
|
||||
Memory = null;
|
||||
Heap = Pointer.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine how much memory (from the single, large array) is currenly in use.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public uint GetMemoryUsed()
|
||||
{
|
||||
uint memoryUsed = AllocatorSize - (HighUnit - LowUnit) - (BaseUnit - Text);
|
||||
for (uint index = 0; index < IndexCount; index++)
|
||||
memoryUsed -= UnitSize * indexToUnits[index] * MemoryNodes[index].Stamp;
|
||||
return memoryUsed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocate a given number of units from the single, large array. Each unit is <see cref="UnitSize"/> bytes
|
||||
/// in size.
|
||||
/// </summary>
|
||||
/// <param name="unitCount"></param>
|
||||
/// <returns></returns>
|
||||
public Pointer AllocateUnits(uint unitCount)
|
||||
{
|
||||
uint index = unitsToIndex[unitCount - 1];
|
||||
if (MemoryNodes[index].Available)
|
||||
return MemoryNodes[index].Remove();
|
||||
|
||||
Pointer allocatedBlock = LowUnit;
|
||||
LowUnit += indexToUnits[index] * UnitSize;
|
||||
if (LowUnit <= HighUnit)
|
||||
return allocatedBlock;
|
||||
|
||||
LowUnit -= indexToUnits[index] * UnitSize;
|
||||
return AllocateUnitsRare(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocate enough space for a PpmContext instance in the single, large array.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Pointer AllocateContext()
|
||||
{
|
||||
if (HighUnit != LowUnit)
|
||||
return (HighUnit -= UnitSize);
|
||||
else if (MemoryNodes[0].Available)
|
||||
return MemoryNodes[0].Remove();
|
||||
else
|
||||
return AllocateUnitsRare(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increase the size of an existing allocation (represented by a <see cref="Pointer"/>).
|
||||
/// </summary>
|
||||
/// <param name="oldPointer"></param>
|
||||
/// <param name="oldUnitCount"></param>
|
||||
/// <returns></returns>
|
||||
public Pointer ExpandUnits(Pointer oldPointer, uint oldUnitCount)
|
||||
{
|
||||
uint oldIndex = unitsToIndex[oldUnitCount - 1];
|
||||
uint newIndex = unitsToIndex[oldUnitCount];
|
||||
|
||||
if (oldIndex == newIndex)
|
||||
return oldPointer;
|
||||
|
||||
Pointer pointer = AllocateUnits(oldUnitCount + 1);
|
||||
|
||||
if (pointer != Pointer.Zero)
|
||||
{
|
||||
CopyUnits(pointer, oldPointer, oldUnitCount);
|
||||
MemoryNodes[oldIndex].Insert(oldPointer, oldUnitCount);
|
||||
}
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrease the size of an existing allocation (represented by a <see cref="Pointer"/>).
|
||||
/// </summary>
|
||||
/// <param name="oldPointer"></param>
|
||||
/// <param name="oldUnitCount"></param>
|
||||
/// <param name="newUnitCount"></param>
|
||||
/// <returns></returns>
|
||||
public Pointer ShrinkUnits(Pointer oldPointer, uint oldUnitCount, uint newUnitCount)
|
||||
{
|
||||
uint oldIndex = unitsToIndex[oldUnitCount - 1];
|
||||
uint newIndex = unitsToIndex[newUnitCount - 1];
|
||||
|
||||
if (oldIndex == newIndex)
|
||||
return oldPointer;
|
||||
|
||||
if (MemoryNodes[newIndex].Available)
|
||||
{
|
||||
Pointer pointer = MemoryNodes[newIndex].Remove();
|
||||
CopyUnits(pointer, oldPointer, newUnitCount);
|
||||
MemoryNodes[oldIndex].Insert(oldPointer, indexToUnits[oldIndex]);
|
||||
return pointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitBlock(oldPointer, oldIndex, newIndex);
|
||||
return oldPointer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free previously allocated space (the location and amount of space to free must be specified by using
|
||||
/// a <see cref="Pointer"/> to indicate the location and a number of units to indicate the amount).
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <param name="unitCount"></param>
|
||||
public void FreeUnits(Pointer pointer, uint unitCount)
|
||||
{
|
||||
uint index = unitsToIndex[unitCount - 1];
|
||||
MemoryNodes[index].Insert(pointer, indexToUnits[index]);
|
||||
}
|
||||
|
||||
public void SpecialFreeUnits(Pointer pointer)
|
||||
{
|
||||
if (pointer != BaseUnit)
|
||||
{
|
||||
MemoryNodes[0].Insert(pointer, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryNode memoryNode = pointer;
|
||||
memoryNode.Stamp = uint.MaxValue;
|
||||
BaseUnit += UnitSize;
|
||||
}
|
||||
}
|
||||
|
||||
public Pointer MoveUnitsUp(Pointer oldPointer, uint unitCount)
|
||||
{
|
||||
uint index = unitsToIndex[unitCount - 1];
|
||||
|
||||
if (oldPointer > BaseUnit + 16 * 1024 || oldPointer > MemoryNodes[index].Next)
|
||||
return oldPointer;
|
||||
|
||||
Pointer pointer = MemoryNodes[index].Remove();
|
||||
CopyUnits(pointer, oldPointer, unitCount);
|
||||
unitCount = indexToUnits[index];
|
||||
|
||||
if (oldPointer != BaseUnit)
|
||||
MemoryNodes[index].Insert(oldPointer, unitCount);
|
||||
else
|
||||
BaseUnit += unitCount * UnitSize;
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expand the space allocated (in the single, large array) for the bytes of the data (ie. the "text") that is
|
||||
/// being encoded or decoded.
|
||||
/// </summary>
|
||||
public void ExpandText()
|
||||
{
|
||||
MemoryNode memoryNode;
|
||||
uint[] counts = new uint[IndexCount];
|
||||
|
||||
while ((memoryNode = BaseUnit).Stamp == uint.MaxValue)
|
||||
{
|
||||
BaseUnit = memoryNode + memoryNode.UnitCount;
|
||||
counts[unitsToIndex[memoryNode.UnitCount - 1]]++;
|
||||
memoryNode.Stamp = 0;
|
||||
}
|
||||
|
||||
for (uint index = 0; index < IndexCount; index++)
|
||||
{
|
||||
for (memoryNode = MemoryNodes[index]; counts[index] != 0; memoryNode = memoryNode.Next)
|
||||
{
|
||||
while (memoryNode.Next.Stamp == 0)
|
||||
{
|
||||
memoryNode.Unlink();
|
||||
MemoryNodes[index].Stamp--;
|
||||
if (--counts[index] == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private Pointer AllocateUnitsRare(uint index)
|
||||
{
|
||||
if (GlueCount == 0)
|
||||
{
|
||||
GlueFreeBlocks();
|
||||
if (MemoryNodes[index].Available)
|
||||
return MemoryNodes[index].Remove();
|
||||
}
|
||||
|
||||
uint oldIndex = index;
|
||||
do
|
||||
{
|
||||
if (++oldIndex == IndexCount)
|
||||
{
|
||||
GlueCount--;
|
||||
oldIndex = indexToUnits[index] * UnitSize;
|
||||
return (BaseUnit - Text > oldIndex) ? (BaseUnit -= oldIndex) : Pointer.Zero;
|
||||
}
|
||||
} while (!MemoryNodes[oldIndex].Available);
|
||||
|
||||
Pointer allocatedBlock = MemoryNodes[oldIndex].Remove();
|
||||
SplitBlock(allocatedBlock, oldIndex, index);
|
||||
return allocatedBlock;
|
||||
}
|
||||
|
||||
private void SplitBlock(Pointer pointer, uint oldIndex, uint newIndex)
|
||||
{
|
||||
uint unitCountDifference = (uint)(indexToUnits[oldIndex] - indexToUnits[newIndex]);
|
||||
Pointer newPointer = pointer + indexToUnits[newIndex] * UnitSize;
|
||||
|
||||
uint index = unitsToIndex[unitCountDifference - 1];
|
||||
if (indexToUnits[index] != unitCountDifference)
|
||||
{
|
||||
uint unitCount = indexToUnits[--index];
|
||||
MemoryNodes[index].Insert(newPointer, unitCount);
|
||||
newPointer += unitCount * UnitSize;
|
||||
unitCountDifference -= unitCount;
|
||||
}
|
||||
|
||||
MemoryNodes[unitsToIndex[unitCountDifference - 1]].Insert(newPointer, unitCountDifference);
|
||||
}
|
||||
|
||||
private void GlueFreeBlocks()
|
||||
{
|
||||
MemoryNode memoryNode = new MemoryNode(LocalOffset, Memory);
|
||||
memoryNode.Stamp = 0;
|
||||
memoryNode.Next = MemoryNode.Zero;
|
||||
memoryNode.UnitCount = 0;
|
||||
|
||||
MemoryNode memoryNode0;
|
||||
MemoryNode memoryNode1;
|
||||
MemoryNode memoryNode2;
|
||||
|
||||
if (LowUnit != HighUnit)
|
||||
LowUnit[0] = 0;
|
||||
|
||||
// Find all unused memory nodes.
|
||||
|
||||
memoryNode1 = memoryNode;
|
||||
for (uint index = 0; index < IndexCount; index++)
|
||||
{
|
||||
while (MemoryNodes[index].Available)
|
||||
{
|
||||
memoryNode0 = MemoryNodes[index].Remove();
|
||||
if (memoryNode0.UnitCount != 0)
|
||||
{
|
||||
while ((memoryNode2 = memoryNode0 + memoryNode0.UnitCount).Stamp == uint.MaxValue)
|
||||
{
|
||||
memoryNode0.UnitCount = memoryNode0.UnitCount + memoryNode2.UnitCount;
|
||||
memoryNode2.UnitCount = 0;
|
||||
}
|
||||
memoryNode1.Link(memoryNode0);
|
||||
memoryNode1 = memoryNode0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Coalesce the memory represented by the unused memory nodes.
|
||||
|
||||
while (memoryNode.Available)
|
||||
{
|
||||
memoryNode0 = memoryNode.Remove();
|
||||
uint unitCount = memoryNode0.UnitCount;
|
||||
if (unitCount != 0)
|
||||
{
|
||||
for (; unitCount > 128; unitCount -= 128, memoryNode0 += 128)
|
||||
MemoryNodes[IndexCount - 1].Insert(memoryNode0, 128);
|
||||
|
||||
uint index = unitsToIndex[unitCount - 1];
|
||||
if (indexToUnits[index] != unitCount)
|
||||
{
|
||||
uint unitCountDifference = unitCount - indexToUnits[--index];
|
||||
MemoryNodes[unitCountDifference - 1].Insert(memoryNode0 + (unitCount - unitCountDifference), unitCountDifference);
|
||||
}
|
||||
|
||||
MemoryNodes[index].Insert(memoryNode0, indexToUnits[index]);
|
||||
}
|
||||
}
|
||||
|
||||
GlueCount = 1 << 13;
|
||||
}
|
||||
|
||||
private void CopyUnits(Pointer target, Pointer source, uint unitCount)
|
||||
{
|
||||
do
|
||||
{
|
||||
target[0] = source[0];
|
||||
target[1] = source[1];
|
||||
target[2] = source[2];
|
||||
target[3] = source[3];
|
||||
target[4] = source[4];
|
||||
target[5] = source[5];
|
||||
target[6] = source[6];
|
||||
target[7] = source[7];
|
||||
target[8] = source[8];
|
||||
target[9] = source[9];
|
||||
target[10] = source[10];
|
||||
target[11] = source[11];
|
||||
target += UnitSize;
|
||||
source += UnitSize;
|
||||
} while (--unitCount != 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
100
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Coder.cs
vendored
Normal file
100
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Coder.cs
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
#region Using
|
||||
|
||||
using System.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple range coder.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that in most cases fields are used rather than properties for performance reasons (for example,
|
||||
/// <see cref="Scale"/> is a field rather than a property).
|
||||
/// </remarks>
|
||||
internal class Coder
|
||||
{
|
||||
private const uint RangeTop = 1 << 24;
|
||||
private const uint RangeBottom = 1 << 15;
|
||||
private uint low;
|
||||
private uint code;
|
||||
private uint range;
|
||||
|
||||
public uint LowCount;
|
||||
public uint HighCount;
|
||||
public uint Scale;
|
||||
|
||||
public void RangeEncoderInitialize()
|
||||
{
|
||||
low = 0;
|
||||
range = uint.MaxValue;
|
||||
}
|
||||
|
||||
public void RangeEncoderNormalize(Stream stream)
|
||||
{
|
||||
while ((low ^ (low + range)) < RangeTop || range < RangeBottom && ((range = (uint) -low & (RangeBottom - 1)) != 0 || true))
|
||||
{
|
||||
stream.WriteByte((byte) (low >> 24));
|
||||
range <<= 8;
|
||||
low <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void RangeEncodeSymbol()
|
||||
{
|
||||
low += LowCount * (range /= Scale);
|
||||
range *= HighCount - LowCount;
|
||||
}
|
||||
|
||||
public void RangeShiftEncodeSymbol(int rangeShift)
|
||||
{
|
||||
low += LowCount * (range >>= rangeShift);
|
||||
range *= HighCount - LowCount;
|
||||
}
|
||||
|
||||
public void RangeEncoderFlush(Stream stream)
|
||||
{
|
||||
for (uint index = 0; index < 4; index++)
|
||||
{
|
||||
stream.WriteByte((byte) (low >> 24));
|
||||
low <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void RangeDecoderInitialize(Stream stream)
|
||||
{
|
||||
low = 0;
|
||||
code = 0;
|
||||
range = uint.MaxValue;
|
||||
for (uint index = 0; index < 4; index++)
|
||||
code = (code << 8) | (byte) stream.ReadByte();
|
||||
}
|
||||
|
||||
public void RangeDecoderNormalize(Stream stream)
|
||||
{
|
||||
while ((low ^ (low + range)) < RangeTop || range < RangeBottom && ((range = (uint) -low & (RangeBottom - 1)) != 0 || true))
|
||||
{
|
||||
code = (code << 8) | (byte) stream.ReadByte();
|
||||
range <<= 8;
|
||||
low <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public uint RangeGetCurrentCount()
|
||||
{
|
||||
return (code - low) / (range /= Scale);
|
||||
}
|
||||
|
||||
public uint RangeGetCurrentShiftCount(int rangeShift)
|
||||
{
|
||||
return (code - low) / (range >>= rangeShift);
|
||||
}
|
||||
|
||||
public void RangeRemoveSubrange()
|
||||
{
|
||||
low += range * LowCount;
|
||||
range *= HighCount - LowCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
246
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/MemoryNode.cs
vendored
Normal file
246
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/MemoryNode.cs
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
#region Using
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// A structure containing a single address. The address represents a location in the <see cref="Memory"/>
|
||||
/// array. That location in the <see cref="Memory"/> array contains information itself describing a section
|
||||
/// of the <see cref="Memory"/> array (ie. a block of memory).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This must be a structure rather than a class because several places in the associated code assume that
|
||||
/// <see cref="MemoryNode"/> is a value type (meaning that assignment creates a completely new copy of
|
||||
/// the instance rather than just copying a reference to the same instance).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// MemoryNode
|
||||
/// 4 Stamp
|
||||
/// 4 Next
|
||||
/// 4 UnitCount
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Note that <see cref="Address"/> is a field rather than a property for performance reasons.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal struct MemoryNode
|
||||
{
|
||||
public uint Address;
|
||||
public byte[] Memory;
|
||||
public static readonly MemoryNode Zero = new MemoryNode(0, null);
|
||||
public const int Size = 12;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MemoryNode"/> structure.
|
||||
/// </summary>
|
||||
public MemoryNode(uint address, byte[] memory)
|
||||
{
|
||||
Address = address;
|
||||
Memory = memory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the stamp.
|
||||
/// </summary>
|
||||
public uint Stamp
|
||||
{
|
||||
get { return ((uint) Memory[Address]) | ((uint) Memory[Address + 1]) << 8 | ((uint) Memory[Address + 2]) << 16 | ((uint) Memory[Address + 3]) << 24; }
|
||||
set
|
||||
{
|
||||
Memory[Address] = (byte) value;
|
||||
Memory[Address + 1] = (byte) (value >> 8);
|
||||
Memory[Address + 2] = (byte) (value >> 16);
|
||||
Memory[Address + 3] = (byte) (value >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next memory node.
|
||||
/// </summary>
|
||||
public MemoryNode Next
|
||||
{
|
||||
get { return new MemoryNode(((uint) Memory[Address + 4]) | ((uint) Memory[Address + 5]) << 8 | ((uint) Memory[Address + 6]) << 16 | ((uint) Memory[Address + 7]) << 24, Memory); }
|
||||
set
|
||||
{
|
||||
Memory[Address + 4] = (byte) value.Address;
|
||||
Memory[Address + 5] = (byte) (value.Address >> 8);
|
||||
Memory[Address + 6] = (byte) (value.Address >> 16);
|
||||
Memory[Address + 7] = (byte) (value.Address >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the unit count.
|
||||
/// </summary>
|
||||
public uint UnitCount
|
||||
{
|
||||
get { return ((uint) Memory[Address + 8]) | ((uint) Memory[Address + 9]) << 8 | ((uint) Memory[Address + 10]) << 16 | ((uint) Memory[Address + 11]) << 24; }
|
||||
set
|
||||
{
|
||||
Memory[Address + 8] = (byte) value;
|
||||
Memory[Address + 9] = (byte) (value >> 8);
|
||||
Memory[Address + 10] = (byte) (value >> 16);
|
||||
Memory[Address + 11] = (byte) (value >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether there is a next memory node available.
|
||||
/// </summary>
|
||||
public bool Available
|
||||
{
|
||||
get { return Next.Address != 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Link in the provided memory node.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode"></param>
|
||||
public void Link(MemoryNode memoryNode)
|
||||
{
|
||||
memoryNode.Next = Next;
|
||||
Next = memoryNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlink this memory node.
|
||||
/// </summary>
|
||||
public void Unlink()
|
||||
{
|
||||
Next = Next.Next;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert the memory node into the linked list.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode"></param>
|
||||
/// <param name="unitCount"></param>
|
||||
public void Insert(MemoryNode memoryNode, uint unitCount)
|
||||
{
|
||||
Link(memoryNode);
|
||||
memoryNode.Stamp = uint.MaxValue;
|
||||
memoryNode.UnitCount = unitCount;
|
||||
Stamp++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove this memory node from the linked list.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public MemoryNode Remove()
|
||||
{
|
||||
MemoryNode next = Next;
|
||||
Unlink();
|
||||
Stamp--;
|
||||
return next;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow a pointer to be implicitly converted to a memory node.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator MemoryNode(Pointer pointer)
|
||||
{
|
||||
return new MemoryNode(pointer.Address, pointer.Memory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like addition on a memory node.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static MemoryNode operator +(MemoryNode memoryNode, int offset)
|
||||
{
|
||||
memoryNode.Address = (uint) (memoryNode.Address + offset * Size);
|
||||
return memoryNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like addition on a memory node.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static MemoryNode operator +(MemoryNode memoryNode, uint offset)
|
||||
{
|
||||
memoryNode.Address += offset * Size;
|
||||
return memoryNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like subtraction on a memory node.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static MemoryNode operator -(MemoryNode memoryNode, int offset)
|
||||
{
|
||||
memoryNode.Address = (uint) (memoryNode.Address - offset * Size);
|
||||
return memoryNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like subtraction on a memory node.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static MemoryNode operator -(MemoryNode memoryNode, uint offset)
|
||||
{
|
||||
memoryNode.Address -= offset * Size;
|
||||
return memoryNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two memory nodes.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode1"></param>
|
||||
/// <param name="memoryNode2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator ==(MemoryNode memoryNode1, MemoryNode memoryNode2)
|
||||
{
|
||||
return memoryNode1.Address == memoryNode2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two memory nodes.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode1"></param>
|
||||
/// <param name="memoryNode2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator !=(MemoryNode memoryNode1, MemoryNode memoryNode2)
|
||||
{
|
||||
return memoryNode1.Address != memoryNode2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <returns>true if obj and this instance are the same type and represent the same value; otherwise, false.</returns>
|
||||
/// <param name="obj">Another object to compare to.</param>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is MemoryNode)
|
||||
{
|
||||
MemoryNode memoryNode = (MemoryNode) obj;
|
||||
return memoryNode.Address == Address;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Address.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
819
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Model.cs
vendored
Normal file
819
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Model.cs
vendored
Normal file
@@ -0,0 +1,819 @@
|
||||
#region Using
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
// This is a port of Dmitry Shkarin's PPMd Variant I Revision 1.
|
||||
// Ported by Michael Bone (mjbone03@yahoo.com.au).
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// The model.
|
||||
/// </summary>
|
||||
internal partial class Model
|
||||
{
|
||||
public const uint Signature = 0x84acaf8fU;
|
||||
public const char Variant = 'I';
|
||||
public const int MaximumOrder = 16; // maximum allowed model order
|
||||
|
||||
private const byte UpperFrequency = 5;
|
||||
private const byte IntervalBitCount = 7;
|
||||
private const byte PeriodBitCount = 7;
|
||||
private const byte TotalBitCount = IntervalBitCount + PeriodBitCount;
|
||||
private const uint Interval = 1 << IntervalBitCount;
|
||||
private const uint BinaryScale = 1 << TotalBitCount;
|
||||
private const uint MaximumFrequency = 124;
|
||||
private const uint OrderBound = 9;
|
||||
|
||||
private See2Context[,] see2Contexts;
|
||||
private See2Context emptySee2Context;
|
||||
private PpmContext maximumContext;
|
||||
private ushort[,] binarySummary = new ushort[25, 64]; // binary SEE-contexts
|
||||
private byte[] numberStatisticsToBinarySummaryIndex = new byte[256];
|
||||
private byte[] probabilities = new byte[260];
|
||||
private byte[] characterMask = new byte[256];
|
||||
private byte escapeCount;
|
||||
private int modelOrder;
|
||||
private int orderFall;
|
||||
private int initialEscape;
|
||||
private int initialRunLength;
|
||||
private int runLength;
|
||||
private byte previousSuccess;
|
||||
private byte numberMasked;
|
||||
private ModelRestorationMethod method;
|
||||
private PpmState foundState; // found next state transition
|
||||
|
||||
private Allocator Allocator;
|
||||
private Coder Coder;
|
||||
private PpmContext minimumContext;
|
||||
private byte numberStatistics;
|
||||
private PpmState[] decodeStates = new PpmState[256];
|
||||
|
||||
private static readonly ushort[] InitialBinaryEscapes = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051 };
|
||||
private static readonly byte[] ExponentialEscapes = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public Model()
|
||||
{
|
||||
// Construct the conversion table for number statistics. Initially it will contain the following values.
|
||||
//
|
||||
// 0 2 4 4 4 4 4 4 4 4 4 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
// 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
// 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
// 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
// 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
// 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
// 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
// 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
|
||||
numberStatisticsToBinarySummaryIndex[0] = 2 * 0;
|
||||
numberStatisticsToBinarySummaryIndex[1] = 2 * 1;
|
||||
for (int index = 2; index < 11; index++)
|
||||
numberStatisticsToBinarySummaryIndex[index] = 2 * 2;
|
||||
for (int index = 11; index < 256; index++)
|
||||
numberStatisticsToBinarySummaryIndex[index] = 2 * 3;
|
||||
|
||||
// Construct the probability table. Initially it will contain the following values (depending on the value of
|
||||
// the upper frequency).
|
||||
//
|
||||
// 00 01 02 03 04 05 06 06 07 07 07 08 08 08 08 09 09 09 09 09 10 10 10 10 10 10 11 11 11 11 11 11
|
||||
// 11 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13 13 13 14 14 14 14 14 14 14 14 14 14 15 15 15 15
|
||||
// 15 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17 17 17 17 17 17 17 17
|
||||
// 18 18 18 18 18 18 18 18 18 18 18 18 18 18 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 20 20 20
|
||||
// 20 20 20 20 20 20 20 20 20 20 20 20 20 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 22 22
|
||||
// 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
|
||||
// 23 23 23 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 25 25 25 25 25 25 25 25 25
|
||||
// 25 25 25 25 25 25 25 25 25 25 25 25 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26
|
||||
// 26 26 27 27
|
||||
|
||||
uint count = 1;
|
||||
uint step = 1;
|
||||
uint probability = UpperFrequency;
|
||||
|
||||
for (int index = 0; index < UpperFrequency; index++)
|
||||
probabilities[index] = (byte)index;
|
||||
|
||||
for (int index = UpperFrequency; index < 260; index++)
|
||||
{
|
||||
probabilities[index] = (byte)probability;
|
||||
count--;
|
||||
if (count == 0)
|
||||
{
|
||||
step++;
|
||||
count = step;
|
||||
probability++;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the context array.
|
||||
|
||||
see2Contexts = new See2Context[24, 32];
|
||||
for (int index1 = 0; index1 < 24; index1++)
|
||||
for (int index2 = 0; index2 < 32; index2++)
|
||||
see2Contexts[index1, index2] = new See2Context();
|
||||
|
||||
// Set the signature (identifying the algorithm).
|
||||
|
||||
emptySee2Context = new See2Context();
|
||||
emptySee2Context.Summary = (ushort)(Signature & 0x0000ffff);
|
||||
emptySee2Context.Shift = (byte)((Signature >> 16) & 0x000000ff);
|
||||
emptySee2Context.Count = (byte)(Signature >> 24);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode (ie. compress) a given source stream, writing the encoded result to the target stream.
|
||||
/// </summary>
|
||||
public void Encode(Stream target, Stream source, PpmdProperties properties)
|
||||
{
|
||||
if (target == null)
|
||||
throw new ArgumentNullException("target");
|
||||
|
||||
if (source == null)
|
||||
throw new ArgumentNullException("source");
|
||||
|
||||
EncodeStart(properties);
|
||||
EncodeBlock(target, source, true);
|
||||
}
|
||||
|
||||
internal Coder EncodeStart(PpmdProperties properties)
|
||||
{
|
||||
Allocator = properties.Allocator;
|
||||
Coder = new Coder();
|
||||
Coder.RangeEncoderInitialize();
|
||||
StartModel(properties.ModelOrder, properties.ModelRestorationMethod);
|
||||
return Coder;
|
||||
}
|
||||
|
||||
internal void EncodeBlock(Stream target, Stream source, bool final)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
minimumContext = maximumContext;
|
||||
numberStatistics = minimumContext.NumberStatistics;
|
||||
|
||||
int c = source.ReadByte();
|
||||
if (c < 0 && !final)
|
||||
return;
|
||||
|
||||
if (numberStatistics != 0)
|
||||
{
|
||||
EncodeSymbol1(c, minimumContext);
|
||||
Coder.RangeEncodeSymbol();
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeBinarySymbol(c, minimumContext);
|
||||
Coder.RangeShiftEncodeSymbol(TotalBitCount);
|
||||
}
|
||||
|
||||
while (foundState == PpmState.Zero)
|
||||
{
|
||||
Coder.RangeEncoderNormalize(target);
|
||||
do
|
||||
{
|
||||
orderFall++;
|
||||
minimumContext = minimumContext.Suffix;
|
||||
if (minimumContext == PpmContext.Zero)
|
||||
goto StopEncoding;
|
||||
} while (minimumContext.NumberStatistics == numberMasked);
|
||||
EncodeSymbol2(c, minimumContext);
|
||||
Coder.RangeEncodeSymbol();
|
||||
}
|
||||
|
||||
if (orderFall == 0 && (Pointer)foundState.Successor >= Allocator.BaseUnit)
|
||||
{
|
||||
maximumContext = foundState.Successor;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateModel(minimumContext);
|
||||
if (escapeCount == 0)
|
||||
ClearMask();
|
||||
}
|
||||
|
||||
Coder.RangeEncoderNormalize(target);
|
||||
}
|
||||
|
||||
StopEncoding:
|
||||
Coder.RangeEncoderFlush(target);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dencode (ie. decompress) a given source stream, writing the decoded result to the target stream.
|
||||
/// </summary>
|
||||
public void Decode(Stream target, Stream source, PpmdProperties properties)
|
||||
{
|
||||
if (target == null)
|
||||
throw new ArgumentNullException("target");
|
||||
|
||||
if (source == null)
|
||||
throw new ArgumentNullException("source");
|
||||
|
||||
DecodeStart(source, properties);
|
||||
byte[] buffer = new byte[65536];
|
||||
int read;
|
||||
while ((read = DecodeBlock(source, buffer, 0, buffer.Length)) != 0)
|
||||
target.Write(buffer, 0, read);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
internal Coder DecodeStart(Stream source, PpmdProperties properties)
|
||||
{
|
||||
Allocator = properties.Allocator;
|
||||
Coder = new Coder();
|
||||
Coder.RangeDecoderInitialize(source);
|
||||
StartModel(properties.ModelOrder, properties.ModelRestorationMethod);
|
||||
minimumContext = maximumContext;
|
||||
numberStatistics = minimumContext.NumberStatistics;
|
||||
return Coder;
|
||||
}
|
||||
|
||||
internal int DecodeBlock(Stream source, byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (minimumContext == PpmContext.Zero)
|
||||
return 0;
|
||||
|
||||
int total = 0;
|
||||
while (total < count)
|
||||
{
|
||||
if (numberStatistics != 0)
|
||||
DecodeSymbol1(minimumContext);
|
||||
else
|
||||
DecodeBinarySymbol(minimumContext);
|
||||
|
||||
Coder.RangeRemoveSubrange();
|
||||
|
||||
while (foundState == PpmState.Zero)
|
||||
{
|
||||
Coder.RangeDecoderNormalize(source);
|
||||
do
|
||||
{
|
||||
orderFall++;
|
||||
minimumContext = minimumContext.Suffix;
|
||||
if (minimumContext == PpmContext.Zero)
|
||||
goto StopDecoding;
|
||||
} while (minimumContext.NumberStatistics == numberMasked);
|
||||
DecodeSymbol2(minimumContext);
|
||||
Coder.RangeRemoveSubrange();
|
||||
}
|
||||
|
||||
buffer[offset] = foundState.Symbol;
|
||||
offset++;
|
||||
total++;
|
||||
|
||||
if (orderFall == 0 && (Pointer)foundState.Successor >= Allocator.BaseUnit)
|
||||
{
|
||||
maximumContext = foundState.Successor;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateModel(minimumContext);
|
||||
if (escapeCount == 0)
|
||||
ClearMask();
|
||||
}
|
||||
|
||||
minimumContext = maximumContext;
|
||||
numberStatistics = minimumContext.NumberStatistics;
|
||||
Coder.RangeDecoderNormalize(source);
|
||||
}
|
||||
|
||||
StopDecoding:
|
||||
return total;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Initialise the model (unless the model order is set to 1 in which case the model should be cleared so that
|
||||
/// the statistics are carried over, allowing "solid" mode compression).
|
||||
/// </summary>
|
||||
private void StartModel(int modelOrder, ModelRestorationMethod modelRestorationMethod)
|
||||
{
|
||||
Array.Clear(characterMask, 0, characterMask.Length);
|
||||
escapeCount = 1;
|
||||
|
||||
// Compress in "solid" mode if the model order value is set to 1 (this will examine the current PPM context
|
||||
// structures to determine the value of orderFall).
|
||||
|
||||
if (modelOrder < 2)
|
||||
{
|
||||
orderFall = this.modelOrder;
|
||||
for (PpmContext context = maximumContext; context.Suffix != PpmContext.Zero; context = context.Suffix)
|
||||
orderFall--;
|
||||
return;
|
||||
}
|
||||
|
||||
this.modelOrder = modelOrder;
|
||||
orderFall = modelOrder;
|
||||
method = modelRestorationMethod;
|
||||
Allocator.Initialize();
|
||||
initialRunLength = -((modelOrder < 12) ? modelOrder : 12) - 1;
|
||||
runLength = initialRunLength;
|
||||
|
||||
// Allocate the context structure.
|
||||
|
||||
maximumContext = Allocator.AllocateContext();
|
||||
maximumContext.Suffix = PpmContext.Zero;
|
||||
maximumContext.NumberStatistics = 255;
|
||||
maximumContext.SummaryFrequency = (ushort)(maximumContext.NumberStatistics + 2);
|
||||
maximumContext.Statistics = Allocator.AllocateUnits(256 / 2); // allocates enough space for 256 PPM states (each is 6 bytes)
|
||||
|
||||
previousSuccess = 0;
|
||||
for (int index = 0; index < 256; index++)
|
||||
{
|
||||
PpmState state = maximumContext.Statistics[index];
|
||||
state.Symbol = (byte)index;
|
||||
state.Frequency = 1;
|
||||
state.Successor = PpmContext.Zero;
|
||||
}
|
||||
|
||||
uint probability = 0;
|
||||
for (int index1 = 0; probability < 25; probability++)
|
||||
{
|
||||
while (probabilities[index1] == probability)
|
||||
index1++;
|
||||
for (int index2 = 0; index2 < 8; index2++)
|
||||
binarySummary[probability, index2] = (ushort)(BinaryScale - InitialBinaryEscapes[index2] / (index1 + 1));
|
||||
for (int index2 = 8; index2 < 64; index2 += 8)
|
||||
for (int index3 = 0; index3 < 8; index3++)
|
||||
binarySummary[probability, index2 + index3] = binarySummary[probability, index3];
|
||||
}
|
||||
|
||||
probability = 0;
|
||||
for (uint index1 = 0; probability < 24; probability++)
|
||||
{
|
||||
while (probabilities[index1 + 3] == probability + 3)
|
||||
index1++;
|
||||
for (int index2 = 0; index2 < 32; index2++)
|
||||
see2Contexts[probability, index2].Initialize(2 * index1 + 5);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateModel(PpmContext minimumContext)
|
||||
{
|
||||
PpmState state = PpmState.Zero;
|
||||
PpmContext Successor;
|
||||
PpmContext currentContext = maximumContext;
|
||||
uint numberStatistics;
|
||||
uint ns1;
|
||||
uint cf;
|
||||
uint sf;
|
||||
uint s0;
|
||||
uint foundStateFrequency = foundState.Frequency;
|
||||
byte foundStateSymbol = foundState.Symbol;
|
||||
byte symbol;
|
||||
byte flag;
|
||||
|
||||
PpmContext foundStateSuccessor = foundState.Successor;
|
||||
PpmContext context = minimumContext.Suffix;
|
||||
|
||||
if ((foundStateFrequency < MaximumFrequency / 4) && (context != PpmContext.Zero))
|
||||
{
|
||||
if (context.NumberStatistics != 0)
|
||||
{
|
||||
state = context.Statistics;
|
||||
if (state.Symbol != foundStateSymbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
symbol = state[1].Symbol;
|
||||
state++;
|
||||
} while (symbol != foundStateSymbol);
|
||||
if (state[0].Frequency >= state[-1].Frequency)
|
||||
{
|
||||
Swap(state[0], state[-1]);
|
||||
state--;
|
||||
}
|
||||
}
|
||||
cf = (uint)((state.Frequency < MaximumFrequency - 9) ? 2 : 0);
|
||||
state.Frequency += (byte)cf;
|
||||
context.SummaryFrequency += (byte)cf;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = context.FirstState;
|
||||
state.Frequency += (byte)((state.Frequency < 32) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (orderFall == 0 && foundStateSuccessor != PpmContext.Zero)
|
||||
{
|
||||
foundState.Successor = CreateSuccessors(true, state, minimumContext);
|
||||
if (foundState.Successor == PpmContext.Zero)
|
||||
goto RestartModel;
|
||||
maximumContext = foundState.Successor;
|
||||
return;
|
||||
}
|
||||
|
||||
Allocator.Text[0] = foundStateSymbol;
|
||||
Allocator.Text++;
|
||||
Successor = Allocator.Text;
|
||||
|
||||
if (Allocator.Text >= Allocator.BaseUnit)
|
||||
goto RestartModel;
|
||||
|
||||
if (foundStateSuccessor != PpmContext.Zero)
|
||||
{
|
||||
if (foundStateSuccessor < Allocator.BaseUnit)
|
||||
foundStateSuccessor = CreateSuccessors(false, state, minimumContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
foundStateSuccessor = ReduceOrder(state, minimumContext);
|
||||
}
|
||||
|
||||
if (foundStateSuccessor == PpmContext.Zero)
|
||||
goto RestartModel;
|
||||
|
||||
if (--orderFall == 0)
|
||||
{
|
||||
Successor = foundStateSuccessor;
|
||||
Allocator.Text -= (maximumContext != minimumContext) ? 1 : 0;
|
||||
}
|
||||
else if (method > ModelRestorationMethod.Freeze)
|
||||
{
|
||||
Successor = foundStateSuccessor;
|
||||
Allocator.Text = Allocator.Heap;
|
||||
orderFall = 0;
|
||||
}
|
||||
|
||||
numberStatistics = minimumContext.NumberStatistics;
|
||||
s0 = minimumContext.SummaryFrequency - numberStatistics - foundStateFrequency;
|
||||
flag = (byte)((foundStateSymbol >= 0x40) ? 0x08 : 0x00);
|
||||
for (; currentContext != minimumContext; currentContext = currentContext.Suffix)
|
||||
{
|
||||
ns1 = currentContext.NumberStatistics;
|
||||
if (ns1 != 0)
|
||||
{
|
||||
if ((ns1 & 1) != 0)
|
||||
{
|
||||
state = Allocator.ExpandUnits(currentContext.Statistics, (ns1 + 1) >> 1);
|
||||
if (state == PpmState.Zero)
|
||||
goto RestartModel;
|
||||
currentContext.Statistics = state;
|
||||
}
|
||||
currentContext.SummaryFrequency += (ushort)((3 * ns1 + 1 < numberStatistics) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = Allocator.AllocateUnits(1);
|
||||
if (state == PpmState.Zero)
|
||||
goto RestartModel;
|
||||
Copy(state, currentContext.FirstState);
|
||||
currentContext.Statistics = state;
|
||||
if (state.Frequency < MaximumFrequency / 4 - 1)
|
||||
state.Frequency += state.Frequency;
|
||||
else
|
||||
state.Frequency = (byte)(MaximumFrequency - 4);
|
||||
currentContext.SummaryFrequency = (ushort)(state.Frequency + initialEscape + ((numberStatistics > 2) ? 1 : 0));
|
||||
}
|
||||
|
||||
cf = (uint)(2 * foundStateFrequency * (currentContext.SummaryFrequency + 6));
|
||||
sf = s0 + currentContext.SummaryFrequency;
|
||||
|
||||
if (cf < 6 * sf)
|
||||
{
|
||||
cf = (uint)(1 + ((cf > sf) ? 1 : 0) + ((cf >= 4 * sf) ? 1 : 0));
|
||||
currentContext.SummaryFrequency += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
cf = (uint)(4 + ((cf > 9 * sf) ? 1 : 0) + ((cf > 12 * sf) ? 1 : 0) + ((cf > 15 * sf) ? 1 : 0));
|
||||
currentContext.SummaryFrequency += (ushort)cf;
|
||||
}
|
||||
|
||||
state = currentContext.Statistics + (++currentContext.NumberStatistics);
|
||||
state.Successor = Successor;
|
||||
state.Symbol = foundStateSymbol;
|
||||
state.Frequency = (byte)cf;
|
||||
currentContext.Flags |= flag;
|
||||
}
|
||||
|
||||
maximumContext = foundStateSuccessor;
|
||||
return;
|
||||
|
||||
RestartModel:
|
||||
RestoreModel(currentContext, minimumContext, foundStateSuccessor);
|
||||
}
|
||||
|
||||
private PpmContext CreateSuccessors(bool skip, PpmState state, PpmContext context)
|
||||
{
|
||||
PpmContext upBranch = foundState.Successor;
|
||||
PpmState[] states = new PpmState[MaximumOrder];
|
||||
uint stateIndex = 0;
|
||||
byte symbol = foundState.Symbol;
|
||||
|
||||
if (!skip)
|
||||
{
|
||||
states[stateIndex++] = foundState;
|
||||
if (context.Suffix == PpmContext.Zero)
|
||||
goto NoLoop;
|
||||
}
|
||||
|
||||
bool gotoLoopEntry = false;
|
||||
if (state != PpmState.Zero)
|
||||
{
|
||||
context = context.Suffix;
|
||||
gotoLoopEntry = true;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (gotoLoopEntry)
|
||||
{
|
||||
gotoLoopEntry = false;
|
||||
goto LoopEntry;
|
||||
}
|
||||
|
||||
context = context.Suffix;
|
||||
if (context.NumberStatistics != 0)
|
||||
{
|
||||
byte temporary;
|
||||
state = context.Statistics;
|
||||
if (state.Symbol != symbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
temporary = state[1].Symbol;
|
||||
state++;
|
||||
} while (temporary != symbol);
|
||||
}
|
||||
temporary = (byte)((state.Frequency < MaximumFrequency - 9) ? 1 : 0);
|
||||
state.Frequency += temporary;
|
||||
context.SummaryFrequency += temporary;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = context.FirstState;
|
||||
state.Frequency += (byte)(((context.Suffix.NumberStatistics == 0) ? 1 : 0) & ((state.Frequency < 24) ? 1 : 0));
|
||||
}
|
||||
|
||||
LoopEntry:
|
||||
if (state.Successor != upBranch)
|
||||
{
|
||||
context = state.Successor;
|
||||
break;
|
||||
}
|
||||
states[stateIndex++] = state;
|
||||
} while (context.Suffix != PpmContext.Zero);
|
||||
|
||||
NoLoop:
|
||||
if (stateIndex == 0)
|
||||
return context;
|
||||
|
||||
byte localNumberStatistics = 0;
|
||||
byte localFlags = (byte)((symbol >= 0x40) ? 0x10 : 0x00);
|
||||
symbol = upBranch.NumberStatistics;
|
||||
byte localSymbol = symbol;
|
||||
byte localFrequency;
|
||||
PpmContext localSuccessor = ((Pointer)upBranch) + 1;
|
||||
localFlags |= (byte)((symbol >= 0x40) ? 0x08 : 0x00);
|
||||
|
||||
if (context.NumberStatistics != 0)
|
||||
{
|
||||
state = context.Statistics;
|
||||
if (state.Symbol != symbol)
|
||||
{
|
||||
byte temporary;
|
||||
do
|
||||
{
|
||||
temporary = state[1].Symbol;
|
||||
state++;
|
||||
} while (temporary != symbol);
|
||||
}
|
||||
uint cf = (uint)(state.Frequency - 1);
|
||||
uint s0 = (uint)(context.SummaryFrequency - context.NumberStatistics - cf);
|
||||
localFrequency = (byte)(1 + ((2 * cf <= s0) ? (uint)((5 * cf > s0) ? 1 : 0) : ((cf + 2 * s0 - 3) / s0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
localFrequency = context.FirstStateFrequency;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
PpmContext currentContext = Allocator.AllocateContext();
|
||||
if (currentContext == PpmContext.Zero)
|
||||
return PpmContext.Zero;
|
||||
currentContext.NumberStatistics = localNumberStatistics;
|
||||
currentContext.Flags = localFlags;
|
||||
currentContext.FirstStateSymbol = localSymbol;
|
||||
currentContext.FirstStateFrequency = localFrequency;
|
||||
currentContext.FirstStateSuccessor = localSuccessor;
|
||||
currentContext.Suffix = context;
|
||||
context = currentContext;
|
||||
states[--stateIndex].Successor = context;
|
||||
} while (stateIndex != 0);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private PpmContext ReduceOrder(PpmState state, PpmContext context)
|
||||
{
|
||||
PpmState currentState;
|
||||
PpmState[] states = new PpmState[MaximumOrder];
|
||||
uint stateIndex = 0;
|
||||
PpmContext currentContext = context;
|
||||
PpmContext UpBranch = Allocator.Text;
|
||||
byte temporary;
|
||||
byte symbol = foundState.Symbol;
|
||||
|
||||
states[stateIndex++] = foundState;
|
||||
foundState.Successor = UpBranch;
|
||||
orderFall++;
|
||||
|
||||
bool gotoLoopEntry = false;
|
||||
if (state != PpmState.Zero)
|
||||
{
|
||||
context = context.Suffix;
|
||||
gotoLoopEntry = true;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (gotoLoopEntry)
|
||||
{
|
||||
gotoLoopEntry = false;
|
||||
goto LoopEntry;
|
||||
}
|
||||
|
||||
if (context.Suffix == PpmContext.Zero)
|
||||
{
|
||||
if (method > ModelRestorationMethod.Freeze)
|
||||
{
|
||||
do
|
||||
{
|
||||
states[--stateIndex].Successor = context;
|
||||
} while (stateIndex != 0);
|
||||
Allocator.Text = Allocator.Heap + 1;
|
||||
orderFall = 1;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
context = context.Suffix;
|
||||
if (context.NumberStatistics != 0)
|
||||
{
|
||||
state = context.Statistics;
|
||||
if (state.Symbol != symbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
temporary = state[1].Symbol;
|
||||
state++;
|
||||
} while (temporary != symbol);
|
||||
}
|
||||
temporary = (byte)((state.Frequency < MaximumFrequency - 9) ? 2 : 0);
|
||||
state.Frequency += temporary;
|
||||
context.SummaryFrequency += temporary;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = context.FirstState;
|
||||
state.Frequency += (byte)((state.Frequency < 32) ? 1 : 0);
|
||||
}
|
||||
|
||||
LoopEntry:
|
||||
if (state.Successor != PpmContext.Zero)
|
||||
break;
|
||||
states[stateIndex++] = state;
|
||||
state.Successor = UpBranch;
|
||||
orderFall++;
|
||||
}
|
||||
|
||||
if (method > ModelRestorationMethod.Freeze)
|
||||
{
|
||||
context = state.Successor;
|
||||
do
|
||||
{
|
||||
states[--stateIndex].Successor = context;
|
||||
} while (stateIndex != 0);
|
||||
Allocator.Text = Allocator.Heap + 1;
|
||||
orderFall = 1;
|
||||
return context;
|
||||
}
|
||||
else if (state.Successor <= UpBranch)
|
||||
{
|
||||
currentState = foundState;
|
||||
foundState = state;
|
||||
state.Successor = CreateSuccessors(false, PpmState.Zero, context);
|
||||
foundState = currentState;
|
||||
}
|
||||
|
||||
if (orderFall == 1 && currentContext == maximumContext)
|
||||
{
|
||||
foundState.Successor = state.Successor;
|
||||
Allocator.Text--;
|
||||
}
|
||||
|
||||
return state.Successor;
|
||||
}
|
||||
|
||||
private void RestoreModel(PpmContext context, PpmContext minimumContext, PpmContext foundStateSuccessor)
|
||||
{
|
||||
PpmContext currentContext;
|
||||
|
||||
Allocator.Text = Allocator.Heap;
|
||||
for (currentContext = maximumContext; currentContext != context; currentContext = currentContext.Suffix)
|
||||
{
|
||||
if (--currentContext.NumberStatistics == 0)
|
||||
{
|
||||
currentContext.Flags = (byte)((currentContext.Flags & 0x10) + ((currentContext.Statistics.Symbol >= 0x40) ? 0x08 : 0x00));
|
||||
PpmState state = currentContext.Statistics;
|
||||
Copy(currentContext.FirstState, state);
|
||||
Allocator.SpecialFreeUnits(state);
|
||||
currentContext.FirstStateFrequency = (byte)((currentContext.FirstStateFrequency + 11) >> 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
Refresh((uint)((currentContext.NumberStatistics + 3) >> 1), false, currentContext);
|
||||
}
|
||||
}
|
||||
|
||||
for (; currentContext != minimumContext; currentContext = currentContext.Suffix)
|
||||
{
|
||||
if (currentContext.NumberStatistics == 0)
|
||||
currentContext.FirstStateFrequency -= (byte)(currentContext.FirstStateFrequency >> 1);
|
||||
else if ((currentContext.SummaryFrequency += 4) > 128 + 4 * currentContext.NumberStatistics)
|
||||
Refresh((uint)((currentContext.NumberStatistics + 2) >> 1), true, currentContext);
|
||||
}
|
||||
|
||||
if (method > ModelRestorationMethod.Freeze)
|
||||
{
|
||||
maximumContext = foundStateSuccessor;
|
||||
Allocator.GlueCount += (uint)(((Allocator.MemoryNodes[1].Stamp & 1) == 0) ? 1 : 0);
|
||||
}
|
||||
else if (method == ModelRestorationMethod.Freeze)
|
||||
{
|
||||
while (maximumContext.Suffix != PpmContext.Zero)
|
||||
maximumContext = maximumContext.Suffix;
|
||||
|
||||
RemoveBinaryContexts(0, maximumContext);
|
||||
method = (ModelRestorationMethod)(method + 1);
|
||||
Allocator.GlueCount = 0;
|
||||
orderFall = modelOrder;
|
||||
}
|
||||
else if (method == ModelRestorationMethod.Restart || Allocator.GetMemoryUsed() < (Allocator.AllocatorSize >> 1))
|
||||
{
|
||||
StartModel(modelOrder, method);
|
||||
escapeCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (maximumContext.Suffix != PpmContext.Zero)
|
||||
maximumContext = maximumContext.Suffix;
|
||||
|
||||
do
|
||||
{
|
||||
CutOff(0, maximumContext);
|
||||
Allocator.ExpandText();
|
||||
} while (Allocator.GetMemoryUsed() > 3 * (Allocator.AllocatorSize >> 2));
|
||||
|
||||
Allocator.GlueCount = 0;
|
||||
orderFall = modelOrder;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Swap(PpmState state1, PpmState state2)
|
||||
{
|
||||
byte swapSymbol = state1.Symbol;
|
||||
byte swapFrequency = state1.Frequency;
|
||||
PpmContext swapSuccessor = state1.Successor;
|
||||
|
||||
state1.Symbol = state2.Symbol;
|
||||
state1.Frequency = state2.Frequency;
|
||||
state1.Successor = state2.Successor;
|
||||
|
||||
state2.Symbol = swapSymbol;
|
||||
state2.Frequency = swapFrequency;
|
||||
state2.Successor = swapSuccessor;
|
||||
}
|
||||
|
||||
private static void Copy(PpmState state1, PpmState state2)
|
||||
{
|
||||
state1.Symbol = state2.Symbol;
|
||||
state1.Frequency = state2.Frequency;
|
||||
state1.Successor = state2.Successor;
|
||||
}
|
||||
|
||||
private static int Mean(int sum, int shift, int round)
|
||||
{
|
||||
return (sum + (1 << (shift - round))) >> shift;
|
||||
}
|
||||
|
||||
private void ClearMask()
|
||||
{
|
||||
escapeCount = 1;
|
||||
Array.Clear(characterMask, 0, characterMask.Length);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
29
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/ModelRestorationMethod.cs
vendored
Normal file
29
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/ModelRestorationMethod.cs
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
#region Using
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// The method used to adjust the model when the memory limit is reached.
|
||||
/// </summary>
|
||||
internal enum ModelRestorationMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// Restart the model from scratch (this is the default).
|
||||
/// </summary>
|
||||
Restart = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Cut off the model (nearly twice as slow).
|
||||
/// </summary>
|
||||
CutOff = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Freeze the context tree (in some cases may result in poor compression).
|
||||
/// </summary>
|
||||
Freeze = 2
|
||||
}
|
||||
}
|
||||
319
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Pointer.cs
vendored
Normal file
319
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/Pointer.cs
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
#region Using
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// A structure containing a single address representing a position in the <see cref="Memory"/> array. This
|
||||
/// is intended to mimic the behaviour of a pointer in C/C++.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This must be a structure rather than a class because several places in the associated code assume that
|
||||
/// <see cref="Pointer"/> is a value type (meaning that assignment creates a completely new copy of the
|
||||
/// instance rather than just copying a reference to the same instance).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Note that <see cref="Address"/> is a field rather than a property for performance reasons.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal struct Pointer
|
||||
{
|
||||
public uint Address;
|
||||
public byte[] Memory;
|
||||
public static readonly Pointer Zero = new Pointer(0, null);
|
||||
public const int Size = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Pointer"/> structure.
|
||||
/// </summary>
|
||||
public Pointer(uint address, byte[] memory)
|
||||
{
|
||||
Address = address;
|
||||
Memory = memory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the byte at the given <paramref name="offset"/>.
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public byte this[int offset]
|
||||
{
|
||||
get
|
||||
{
|
||||
#if DEBUG
|
||||
if (Address == 0)
|
||||
throw new InvalidOperationException("The pointer being indexed is a null pointer.");
|
||||
#endif
|
||||
return Memory[Address + offset];
|
||||
}
|
||||
set
|
||||
{
|
||||
#if DEBUG
|
||||
if (Address == 0)
|
||||
throw new InvalidOperationException("The pointer being indexed is a null pointer.");
|
||||
#endif
|
||||
Memory[Address + offset] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow a <see cref="MemoryNode"/> to be implicitly converted to a <see cref="Pointer"/>.
|
||||
/// </summary>
|
||||
/// <param name="memoryNode"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator Pointer(MemoryNode memoryNode)
|
||||
{
|
||||
return new Pointer(memoryNode.Address, memoryNode.Memory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow a <see cref="Model.PpmContext"/> to be implicitly converted to a <see cref="Pointer"/>.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator Pointer(Model.PpmContext context)
|
||||
{
|
||||
return new Pointer(context.Address, context.Memory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow a <see cref="PpmState"/> to be implicitly converted to a <see cref="Pointer"/>.
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator Pointer(PpmState state)
|
||||
{
|
||||
return new Pointer(state.Address, state.Memory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increase the address of a pointer by the given number of bytes.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static Pointer operator +(Pointer pointer, int offset)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer.Address == 0)
|
||||
throw new InvalidOperationException("The pointer is a null pointer.");
|
||||
#endif
|
||||
pointer.Address = (uint) (pointer.Address + offset);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increase the address of a pointer by the given number of bytes.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static Pointer operator +(Pointer pointer, uint offset)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer.Address == 0)
|
||||
throw new InvalidOperationException("The pointer is a null pointer.");
|
||||
#endif
|
||||
pointer.Address += offset;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increment the address of a pointer.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <returns></returns>
|
||||
public static Pointer operator ++(Pointer pointer)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer.Address == 0)
|
||||
throw new InvalidOperationException("The pointer being incremented is a null pointer.");
|
||||
#endif
|
||||
pointer.Address++;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrease the address of a pointer by the given number of bytes.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static Pointer operator -(Pointer pointer, int offset)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer.Address == 0)
|
||||
throw new InvalidOperationException("The pointer is a null pointer.");
|
||||
#endif
|
||||
pointer.Address = (uint) (pointer.Address - offset);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrease the address of a pointer by the given number of bytes.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static Pointer operator -(Pointer pointer, uint offset)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer.Address == 0)
|
||||
throw new InvalidOperationException("The pointer is a null pointer.");
|
||||
#endif
|
||||
pointer.Address -= offset;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrement the address of a pointer.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <returns></returns>
|
||||
public static Pointer operator --(Pointer pointer)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer.Address == 0)
|
||||
throw new InvalidOperationException("The pointer being decremented is a null pointer.");
|
||||
#endif
|
||||
pointer.Address--;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract two pointers.
|
||||
/// </summary>
|
||||
/// <param name="pointer1"></param>
|
||||
/// <param name="pointer2"></param>
|
||||
/// <returns>The number of bytes between the two pointers.</returns>
|
||||
public static uint operator -(Pointer pointer1, Pointer pointer2)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer1.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the left of the subtraction operator is a null pointer.");
|
||||
if (pointer2.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the right of the subtraction operator is a null pointer.");
|
||||
#endif
|
||||
return pointer1.Address - pointer2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare pointers.
|
||||
/// </summary>
|
||||
/// <param name="pointer1"></param>
|
||||
/// <param name="pointer2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator <(Pointer pointer1, Pointer pointer2)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer1.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the left of the less than operator is a null pointer.");
|
||||
if (pointer2.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the right of the less than operator is a null pointer.");
|
||||
#endif
|
||||
return pointer1.Address < pointer2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two pointers.
|
||||
/// </summary>
|
||||
/// <param name="pointer1"></param>
|
||||
/// <param name="pointer2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator <=(Pointer pointer1, Pointer pointer2)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer1.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the left of the less than or equal to operator is a null pointer.");
|
||||
if (pointer2.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the right of the less than or equal to operator is a null pointer.");
|
||||
#endif
|
||||
return pointer1.Address <= pointer2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two pointers.
|
||||
/// </summary>
|
||||
/// <param name="pointer1"></param>
|
||||
/// <param name="pointer2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator >(Pointer pointer1, Pointer pointer2)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer1.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the left of the greater than operator is a null pointer.");
|
||||
if (pointer2.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the right of the greater than operator is a null pointer.");
|
||||
#endif
|
||||
return pointer1.Address > pointer2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two pointers.
|
||||
/// </summary>
|
||||
/// <param name="pointer1"></param>
|
||||
/// <param name="pointer2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator >=(Pointer pointer1, Pointer pointer2)
|
||||
{
|
||||
#if DEBUG
|
||||
if (pointer1.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the left of the greater than or equal to operator is a null pointer.");
|
||||
if (pointer2.Address == 0)
|
||||
throw new InvalidOperationException("The pointer to the right of the greater than or equal to operator is a null pointer.");
|
||||
#endif
|
||||
return pointer1.Address >= pointer2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two pointers.
|
||||
/// </summary>
|
||||
/// <param name="pointer1"></param>
|
||||
/// <param name="pointer2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator ==(Pointer pointer1, Pointer pointer2)
|
||||
{
|
||||
return pointer1.Address == pointer2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two pointers.
|
||||
/// </summary>
|
||||
/// <param name="pointer1"></param>
|
||||
/// <param name="pointer2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator !=(Pointer pointer1, Pointer pointer2)
|
||||
{
|
||||
return pointer1.Address != pointer2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <returns>true if obj and this instance are the same type and represent the same value; otherwise, false.</returns>
|
||||
/// <param name="obj">Another object to compare to.</param>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Pointer)
|
||||
{
|
||||
Pointer pointer = (Pointer) obj;
|
||||
return pointer.Address == Address;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Address.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
787
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/PpmContext.cs
vendored
Normal file
787
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/PpmContext.cs
vendored
Normal file
@@ -0,0 +1,787 @@
|
||||
#region Using
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// The PPM context structure. This is tightly coupled with <see cref="Model"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This must be a structure rather than a class because several places in the associated code assume that
|
||||
/// <see cref="PpmContext"/> is a value type (meaning that assignment creates a completely new copy of
|
||||
/// the instance rather than just copying a reference to the same instance).
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal partial class Model
|
||||
{
|
||||
/// <summary>
|
||||
/// The structure which represents the current PPM context. This is 12 bytes in size.
|
||||
/// </summary>
|
||||
internal struct PpmContext
|
||||
{
|
||||
public uint Address;
|
||||
public byte[] Memory;
|
||||
public static readonly PpmContext Zero = new PpmContext(0, null);
|
||||
public const int Size = 12;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PpmContext"/> structure.
|
||||
/// </summary>
|
||||
public PpmContext(uint address, byte[] memory)
|
||||
{
|
||||
Address = address;
|
||||
Memory = memory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number statistics.
|
||||
/// </summary>
|
||||
public byte NumberStatistics
|
||||
{
|
||||
get { return Memory[Address]; }
|
||||
set { Memory[Address] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the flags.
|
||||
/// </summary>
|
||||
public byte Flags
|
||||
{
|
||||
get { return Memory[Address + 1]; }
|
||||
set { Memory[Address + 1] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the summary frequency.
|
||||
/// </summary>
|
||||
public ushort SummaryFrequency
|
||||
{
|
||||
get { return (ushort)(((ushort)Memory[Address + 2]) | ((ushort)Memory[Address + 3]) << 8); }
|
||||
set
|
||||
{
|
||||
Memory[Address + 2] = (byte)value;
|
||||
Memory[Address + 3] = (byte)(value >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the statistics.
|
||||
/// </summary>
|
||||
public PpmState Statistics
|
||||
{
|
||||
get { return new PpmState(((uint)Memory[Address + 4]) | ((uint)Memory[Address + 5]) << 8 | ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); }
|
||||
set
|
||||
{
|
||||
Memory[Address + 4] = (byte)value.Address;
|
||||
Memory[Address + 5] = (byte)(value.Address >> 8);
|
||||
Memory[Address + 6] = (byte)(value.Address >> 16);
|
||||
Memory[Address + 7] = (byte)(value.Address >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the suffix.
|
||||
/// </summary>
|
||||
public PpmContext Suffix
|
||||
{
|
||||
get { return new PpmContext(((uint)Memory[Address + 8]) | ((uint)Memory[Address + 9]) << 8 | ((uint)Memory[Address + 10]) << 16 | ((uint)Memory[Address + 11]) << 24, Memory); }
|
||||
set
|
||||
{
|
||||
Memory[Address + 8] = (byte)value.Address;
|
||||
Memory[Address + 9] = (byte)(value.Address >> 8);
|
||||
Memory[Address + 10] = (byte)(value.Address >> 16);
|
||||
Memory[Address + 11] = (byte)(value.Address >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The first PPM state associated with the PPM context.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The first PPM state overlaps this PPM context instance (the context.SummaryFrequency and context.Statistics members
|
||||
/// of PpmContext use 6 bytes and so can therefore fit into the space used by the Symbol, Frequency and
|
||||
/// Successor members of PpmState, since they also add up to 6 bytes).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// PpmContext (context.SummaryFrequency and context.Statistics use 6 bytes)
|
||||
/// 1 context.NumberStatistics
|
||||
/// 1 context.Flags
|
||||
/// 2 context.SummaryFrequency
|
||||
/// 4 context.Statistics (pointer to PpmState)
|
||||
/// 4 context.Suffix (pointer to PpmContext)
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// PpmState (total of 6 bytes)
|
||||
/// 1 Symbol
|
||||
/// 1 Frequency
|
||||
/// 4 Successor (pointer to PpmContext)
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
public PpmState FirstState
|
||||
{
|
||||
get { return new PpmState(Address + 2, Memory); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the symbol of the first PPM state. This is provided for convenience. The same
|
||||
/// information can be obtained using the Symbol property on the PPM state provided by the
|
||||
/// <see cref="FirstState"/> property.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "The property getter is provided for completeness.")]
|
||||
public byte FirstStateSymbol
|
||||
{
|
||||
get { return Memory[Address + 2]; }
|
||||
set { Memory[Address + 2] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the frequency of the first PPM state. This is provided for convenience. The same
|
||||
/// information can be obtained using the Frequency property on the PPM state provided by the
|
||||
///context.FirstState property.
|
||||
/// </summary>
|
||||
public byte FirstStateFrequency
|
||||
{
|
||||
get { return Memory[Address + 3]; }
|
||||
set { Memory[Address + 3] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the successor of the first PPM state. This is provided for convenience. The same
|
||||
/// information can be obtained using the Successor property on the PPM state provided by the
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "The property getter is provided for completeness.")]
|
||||
public PpmContext FirstStateSuccessor
|
||||
{
|
||||
get { return new PpmContext(((uint)Memory[Address + 4]) | ((uint)Memory[Address + 5]) << 8 | ((uint)Memory[Address + 6]) << 16 | ((uint)Memory[Address + 7]) << 24, Memory); }
|
||||
set
|
||||
{
|
||||
Memory[Address + 4] = (byte)value.Address;
|
||||
Memory[Address + 5] = (byte)(value.Address >> 8);
|
||||
Memory[Address + 6] = (byte)(value.Address >> 16);
|
||||
Memory[Address + 7] = (byte)(value.Address >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow a pointer to be implicitly converted to a PPM context.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator PpmContext(Pointer pointer)
|
||||
{
|
||||
return new PpmContext(pointer.Address, pointer.Memory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like addition on a PPM context.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static PpmContext operator +(PpmContext context, int offset)
|
||||
{
|
||||
context.Address = (uint)(context.Address + offset * Size);
|
||||
return context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like subtraction on a PPM context.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static PpmContext operator -(PpmContext context, int offset)
|
||||
{
|
||||
context.Address = (uint)(context.Address - offset * Size);
|
||||
return context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM contexts.
|
||||
/// </summary>
|
||||
/// <param name="context1"></param>
|
||||
/// <param name="context2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator <=(PpmContext context1, PpmContext context2)
|
||||
{
|
||||
return context1.Address <= context2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM contexts.
|
||||
/// </summary>
|
||||
/// <param name="context1"></param>
|
||||
/// <param name="context2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator >=(PpmContext context1, PpmContext context2)
|
||||
{
|
||||
return context1.Address >= context2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM contexts.
|
||||
/// </summary>
|
||||
/// <param name="context1"></param>
|
||||
/// <param name="context2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator ==(PpmContext context1, PpmContext context2)
|
||||
{
|
||||
return context1.Address == context2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM contexts.
|
||||
/// </summary>
|
||||
/// <param name="context1"></param>
|
||||
/// <param name="context2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator !=(PpmContext context1, PpmContext context2)
|
||||
{
|
||||
return context1.Address != context2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <returns>true if obj and this instance are the same type and represent the same value; otherwise, false.</returns>
|
||||
/// <param name="obj">Another object to compare to.</param>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is PpmContext)
|
||||
{
|
||||
PpmContext context = (PpmContext)obj;
|
||||
return context.Address == Address;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Address.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private void EncodeBinarySymbol(int symbol, PpmContext context)
|
||||
{
|
||||
PpmState state = context.FirstState;
|
||||
int index1 = probabilities[state.Frequency - 1];
|
||||
int index2 = numberStatisticsToBinarySummaryIndex[context.Suffix.NumberStatistics] + previousSuccess + context.Flags + ((runLength >> 26) & 0x20);
|
||||
|
||||
if (state.Symbol == symbol)
|
||||
{
|
||||
foundState = state;
|
||||
state.Frequency += (byte)((state.Frequency < 196) ? 1 : 0);
|
||||
Coder.LowCount = 0;
|
||||
Coder.HighCount = binarySummary[index1, index2];
|
||||
binarySummary[index1, index2] += (ushort)(Interval - Mean(binarySummary[index1, index2], PeriodBitCount, 2));
|
||||
previousSuccess = 1;
|
||||
runLength++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Coder.LowCount = binarySummary[index1, index2];
|
||||
binarySummary[index1, index2] -= (ushort)Mean(binarySummary[index1, index2], PeriodBitCount, 2);
|
||||
Coder.HighCount = BinaryScale;
|
||||
initialEscape = ExponentialEscapes[binarySummary[index1, index2] >> 10];
|
||||
characterMask[state.Symbol] = escapeCount;
|
||||
previousSuccess = 0;
|
||||
numberMasked = 0;
|
||||
foundState = PpmState.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void EncodeSymbol1(int symbol, PpmContext context)
|
||||
{
|
||||
uint lowCount;
|
||||
uint index = context.Statistics.Symbol;
|
||||
PpmState state = context.Statistics;
|
||||
Coder.Scale = context.SummaryFrequency;
|
||||
if (index == symbol)
|
||||
{
|
||||
Coder.HighCount = state.Frequency;
|
||||
previousSuccess = (byte)((2 * Coder.HighCount >= Coder.Scale) ? 1 : 0);
|
||||
foundState = state;
|
||||
foundState.Frequency += 4;
|
||||
context.SummaryFrequency += 4;
|
||||
runLength += previousSuccess;
|
||||
if (state.Frequency > MaximumFrequency)
|
||||
Rescale(context);
|
||||
Coder.LowCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
lowCount = state.Frequency;
|
||||
index = context.NumberStatistics;
|
||||
previousSuccess = 0;
|
||||
while ((++state).Symbol != symbol)
|
||||
{
|
||||
lowCount += state.Frequency;
|
||||
if (--index == 0)
|
||||
{
|
||||
Coder.LowCount = lowCount;
|
||||
characterMask[state.Symbol] = escapeCount;
|
||||
numberMasked = context.NumberStatistics;
|
||||
index = context.NumberStatistics;
|
||||
foundState = PpmState.Zero;
|
||||
do
|
||||
{
|
||||
characterMask[(--state).Symbol] = escapeCount;
|
||||
} while (--index != 0);
|
||||
Coder.HighCount = Coder.Scale;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Coder.HighCount = (Coder.LowCount = lowCount) + state.Frequency;
|
||||
Update1(state, context);
|
||||
}
|
||||
|
||||
private void EncodeSymbol2(int symbol, PpmContext context)
|
||||
{
|
||||
See2Context see2Context = MakeEscapeFrequency(context);
|
||||
uint currentSymbol;
|
||||
uint lowCount = 0;
|
||||
uint index = (uint)(context.NumberStatistics - numberMasked);
|
||||
PpmState state = context.Statistics - 1;
|
||||
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
currentSymbol = state[1].Symbol;
|
||||
state++;
|
||||
} while (characterMask[currentSymbol] == escapeCount);
|
||||
characterMask[currentSymbol] = escapeCount;
|
||||
if (currentSymbol == symbol)
|
||||
goto SymbolFound;
|
||||
lowCount += state.Frequency;
|
||||
} while (--index != 0);
|
||||
|
||||
Coder.LowCount = lowCount;
|
||||
Coder.Scale += Coder.LowCount;
|
||||
Coder.HighCount = Coder.Scale;
|
||||
see2Context.Summary += (ushort)Coder.Scale;
|
||||
numberMasked = context.NumberStatistics;
|
||||
return;
|
||||
|
||||
SymbolFound:
|
||||
Coder.LowCount = lowCount;
|
||||
lowCount += state.Frequency;
|
||||
Coder.HighCount = lowCount;
|
||||
for (PpmState p1 = state; --index != 0; )
|
||||
{
|
||||
do
|
||||
{
|
||||
currentSymbol = p1[1].Symbol;
|
||||
p1++;
|
||||
} while (characterMask[currentSymbol] == escapeCount);
|
||||
lowCount += p1.Frequency;
|
||||
}
|
||||
Coder.Scale += lowCount;
|
||||
see2Context.Update();
|
||||
Update2(state, context);
|
||||
}
|
||||
|
||||
private void DecodeBinarySymbol(PpmContext context)
|
||||
{
|
||||
PpmState state = context.FirstState;
|
||||
int index1 = probabilities[state.Frequency - 1];
|
||||
int index2 = numberStatisticsToBinarySummaryIndex[context.Suffix.NumberStatistics] + previousSuccess + context.Flags + ((runLength >> 26) & 0x20);
|
||||
|
||||
if (Coder.RangeGetCurrentShiftCount(TotalBitCount) < binarySummary[index1, index2])
|
||||
{
|
||||
foundState = state;
|
||||
state.Frequency += (byte)((state.Frequency < 196) ? 1 : 0);
|
||||
Coder.LowCount = 0;
|
||||
Coder.HighCount = binarySummary[index1, index2];
|
||||
binarySummary[index1, index2] += (ushort)(Interval - Mean(binarySummary[index1, index2], PeriodBitCount, 2));
|
||||
previousSuccess = 1;
|
||||
runLength++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Coder.LowCount = binarySummary[index1, index2];
|
||||
binarySummary[index1, index2] -= (ushort)Mean(binarySummary[index1, index2], PeriodBitCount, 2);
|
||||
Coder.HighCount = BinaryScale;
|
||||
initialEscape = ExponentialEscapes[binarySummary[index1, index2] >> 10];
|
||||
characterMask[state.Symbol] = escapeCount;
|
||||
previousSuccess = 0;
|
||||
numberMasked = 0;
|
||||
foundState = PpmState.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void DecodeSymbol1(PpmContext context)
|
||||
{
|
||||
uint index;
|
||||
uint count;
|
||||
uint highCount = context.Statistics.Frequency;
|
||||
PpmState state = context.Statistics;
|
||||
Coder.Scale = context.SummaryFrequency;
|
||||
|
||||
count = Coder.RangeGetCurrentCount();
|
||||
if (count < highCount)
|
||||
{
|
||||
Coder.HighCount = highCount;
|
||||
previousSuccess = (byte)((2 * Coder.HighCount >= Coder.Scale) ? 1 : 0);
|
||||
foundState = state;
|
||||
highCount += 4;
|
||||
foundState.Frequency = (byte)highCount;
|
||||
context.SummaryFrequency += 4;
|
||||
runLength += previousSuccess;
|
||||
if (highCount > MaximumFrequency)
|
||||
Rescale(context);
|
||||
Coder.LowCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
index = context.NumberStatistics;
|
||||
previousSuccess = 0;
|
||||
while ((highCount += (++state).Frequency) <= count)
|
||||
{
|
||||
if (--index == 0)
|
||||
{
|
||||
Coder.LowCount = highCount;
|
||||
characterMask[state.Symbol] = escapeCount;
|
||||
numberMasked = context.NumberStatistics;
|
||||
index = context.NumberStatistics;
|
||||
foundState = PpmState.Zero;
|
||||
do
|
||||
{
|
||||
characterMask[(--state).Symbol] = escapeCount;
|
||||
} while (--index != 0);
|
||||
Coder.HighCount = Coder.Scale;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Coder.HighCount = highCount;
|
||||
Coder.LowCount = Coder.HighCount - state.Frequency;
|
||||
Update1(state, context);
|
||||
}
|
||||
|
||||
private void DecodeSymbol2(PpmContext context)
|
||||
{
|
||||
See2Context see2Context = MakeEscapeFrequency(context);
|
||||
uint currentSymbol;
|
||||
uint count;
|
||||
uint highCount = 0;
|
||||
uint index = (uint)(context.NumberStatistics - numberMasked);
|
||||
uint stateIndex = 0;
|
||||
PpmState state = context.Statistics - 1;
|
||||
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
currentSymbol = state[1].Symbol;
|
||||
state++;
|
||||
} while (characterMask[currentSymbol] == escapeCount);
|
||||
highCount += state.Frequency;
|
||||
decodeStates[stateIndex++] = state; // note that decodeStates is a static array that is re-used on each call to this method (for performance reasons)
|
||||
} while (--index != 0);
|
||||
|
||||
Coder.Scale += highCount;
|
||||
count = Coder.RangeGetCurrentCount();
|
||||
stateIndex = 0;
|
||||
state = decodeStates[stateIndex];
|
||||
if (count < highCount)
|
||||
{
|
||||
highCount = 0;
|
||||
while ((highCount += state.Frequency) <= count)
|
||||
state = decodeStates[++stateIndex];
|
||||
Coder.HighCount = highCount;
|
||||
Coder.LowCount = Coder.HighCount - state.Frequency;
|
||||
see2Context.Update();
|
||||
Update2(state, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
Coder.LowCount = highCount;
|
||||
Coder.HighCount = Coder.Scale;
|
||||
index = (uint)(context.NumberStatistics - numberMasked);
|
||||
numberMasked = context.NumberStatistics;
|
||||
do
|
||||
{
|
||||
characterMask[decodeStates[stateIndex].Symbol] = escapeCount;
|
||||
stateIndex++;
|
||||
} while (--index != 0);
|
||||
see2Context.Summary += (ushort)Coder.Scale;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update1(PpmState state, PpmContext context)
|
||||
{
|
||||
foundState = state;
|
||||
foundState.Frequency += 4;
|
||||
context.SummaryFrequency += 4;
|
||||
if (state[0].Frequency > state[-1].Frequency)
|
||||
{
|
||||
Swap(state[0], state[-1]);
|
||||
foundState = --state;
|
||||
if (state.Frequency > MaximumFrequency)
|
||||
Rescale(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update2(PpmState state, PpmContext context)
|
||||
{
|
||||
foundState = state;
|
||||
foundState.Frequency += 4;
|
||||
context.SummaryFrequency += 4;
|
||||
if (state.Frequency > MaximumFrequency)
|
||||
Rescale(context);
|
||||
escapeCount++;
|
||||
runLength = initialRunLength;
|
||||
}
|
||||
|
||||
private See2Context MakeEscapeFrequency(PpmContext context)
|
||||
{
|
||||
uint numberStatistics = (uint)2 * context.NumberStatistics;
|
||||
See2Context see2Context;
|
||||
|
||||
if (context.NumberStatistics != 0xff)
|
||||
{
|
||||
// Note that context.Flags is always in the range 0 .. 28 (this ensures that the index used for the second
|
||||
// dimension of the see2Contexts array is always in the range 0 .. 31).
|
||||
|
||||
numberStatistics = context.Suffix.NumberStatistics;
|
||||
int index1 = probabilities[context.NumberStatistics + 2] - 3;
|
||||
int index2 = ((context.SummaryFrequency > 11 * (context.NumberStatistics + 1)) ? 1 : 0) + ((2 * context.NumberStatistics < numberStatistics + numberMasked) ? 2 : 0) + context.Flags;
|
||||
see2Context = see2Contexts[index1, index2];
|
||||
Coder.Scale = see2Context.Mean();
|
||||
}
|
||||
else
|
||||
{
|
||||
see2Context = emptySee2Context;
|
||||
Coder.Scale = 1;
|
||||
}
|
||||
|
||||
return see2Context;
|
||||
}
|
||||
|
||||
private void Rescale(PpmContext context)
|
||||
{
|
||||
uint oldUnitCount;
|
||||
int adder;
|
||||
uint escapeFrequency;
|
||||
uint index = context.NumberStatistics;
|
||||
|
||||
byte localSymbol;
|
||||
byte localFrequency;
|
||||
PpmContext localSuccessor;
|
||||
PpmState p1;
|
||||
PpmState state;
|
||||
|
||||
for (state = foundState; state != context.Statistics; state--)
|
||||
Swap(state[0], state[-1]);
|
||||
|
||||
state.Frequency += 4;
|
||||
context.SummaryFrequency += 4;
|
||||
escapeFrequency = (uint)(context.SummaryFrequency - state.Frequency);
|
||||
adder = (orderFall != 0 || method > ModelRestorationMethod.Freeze) ? 1 : 0;
|
||||
state.Frequency = (byte)((state.Frequency + adder) >> 1);
|
||||
context.SummaryFrequency = state.Frequency;
|
||||
|
||||
do
|
||||
{
|
||||
escapeFrequency -= (++state).Frequency;
|
||||
state.Frequency = (byte)((state.Frequency + adder) >> 1);
|
||||
context.SummaryFrequency += state.Frequency;
|
||||
if (state[0].Frequency > state[-1].Frequency)
|
||||
{
|
||||
p1 = state;
|
||||
localSymbol = p1.Symbol;
|
||||
localFrequency = p1.Frequency;
|
||||
localSuccessor = p1.Successor;
|
||||
do
|
||||
{
|
||||
Copy(p1[0], p1[-1]);
|
||||
} while (localFrequency > (--p1)[-1].Frequency);
|
||||
p1.Symbol = localSymbol;
|
||||
p1.Frequency = localFrequency;
|
||||
p1.Successor = localSuccessor;
|
||||
}
|
||||
} while (--index != 0);
|
||||
|
||||
if (state.Frequency == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
index++;
|
||||
} while ((--state).Frequency == 0);
|
||||
|
||||
escapeFrequency += index;
|
||||
oldUnitCount = (uint)((context.NumberStatistics + 2) >> 1);
|
||||
context.NumberStatistics -= (byte)index;
|
||||
if (context.NumberStatistics == 0)
|
||||
{
|
||||
localSymbol = context.Statistics.Symbol;
|
||||
localFrequency = context.Statistics.Frequency;
|
||||
localSuccessor = context.Statistics.Successor;
|
||||
localFrequency = (byte)((2 * localFrequency + escapeFrequency - 1) / escapeFrequency);
|
||||
if (localFrequency > MaximumFrequency / 3)
|
||||
localFrequency = (byte)(MaximumFrequency / 3);
|
||||
Allocator.FreeUnits(context.Statistics, oldUnitCount);
|
||||
context.FirstStateSymbol = localSymbol;
|
||||
context.FirstStateFrequency = localFrequency;
|
||||
context.FirstStateSuccessor = localSuccessor;
|
||||
context.Flags = (byte)((context.Flags & 0x10) + ((localSymbol >= 0x40) ? 0x08 : 0x00));
|
||||
foundState = context.FirstState;
|
||||
return;
|
||||
}
|
||||
|
||||
context.Statistics = Allocator.ShrinkUnits(context.Statistics, oldUnitCount, (uint)((context.NumberStatistics + 2) >> 1));
|
||||
context.Flags &= 0xf7;
|
||||
index = context.NumberStatistics;
|
||||
state = context.Statistics;
|
||||
context.Flags |= (byte)((state.Symbol >= 0x40) ? 0x08 : 0x00);
|
||||
do
|
||||
{
|
||||
context.Flags |= (byte)(((++state).Symbol >= 0x40) ? 0x08 : 0x00);
|
||||
} while (--index != 0);
|
||||
}
|
||||
|
||||
escapeFrequency -= (escapeFrequency >> 1);
|
||||
context.SummaryFrequency += (ushort)escapeFrequency;
|
||||
context.Flags |= 0x04;
|
||||
foundState = context.Statistics;
|
||||
}
|
||||
|
||||
private void Refresh(uint oldUnitCount, bool scale, PpmContext context)
|
||||
{
|
||||
int index = context.NumberStatistics;
|
||||
int escapeFrequency;
|
||||
int scaleValue = (scale ? 1 : 0);
|
||||
|
||||
context.Statistics = Allocator.ShrinkUnits(context.Statistics, oldUnitCount, (uint)((index + 2) >> 1));
|
||||
PpmState statistics = context.Statistics;
|
||||
context.Flags = (byte)((context.Flags & (0x10 + (scale ? 0x04 : 0x00))) + ((statistics.Symbol >= 0x40) ? 0x08 : 0x00));
|
||||
escapeFrequency = context.SummaryFrequency - statistics.Frequency;
|
||||
statistics.Frequency = (byte)((statistics.Frequency + scaleValue) >> scaleValue);
|
||||
context.SummaryFrequency = statistics.Frequency;
|
||||
|
||||
do
|
||||
{
|
||||
escapeFrequency -= (++statistics).Frequency;
|
||||
statistics.Frequency = (byte)((statistics.Frequency + scaleValue) >> scaleValue);
|
||||
context.SummaryFrequency += statistics.Frequency;
|
||||
context.Flags |= (byte)((statistics.Symbol >= 0x40) ? 0x08 : 0x00);
|
||||
} while (--index != 0);
|
||||
|
||||
escapeFrequency = (escapeFrequency + scaleValue) >> scaleValue;
|
||||
context.SummaryFrequency += (ushort)escapeFrequency;
|
||||
}
|
||||
|
||||
private PpmContext CutOff(int order, PpmContext context)
|
||||
{
|
||||
int index;
|
||||
PpmState state;
|
||||
|
||||
if (context.NumberStatistics == 0)
|
||||
{
|
||||
state = context.FirstState;
|
||||
if ((Pointer)state.Successor >= Allocator.BaseUnit)
|
||||
{
|
||||
if (order < modelOrder)
|
||||
state.Successor = CutOff(order + 1, state.Successor);
|
||||
else
|
||||
state.Successor = PpmContext.Zero;
|
||||
|
||||
if (state.Successor == PpmContext.Zero && order > OrderBound)
|
||||
{
|
||||
Allocator.SpecialFreeUnits(context);
|
||||
return PpmContext.Zero;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
else
|
||||
{
|
||||
Allocator.SpecialFreeUnits(context);
|
||||
return PpmContext.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
uint unitCount = (uint)((context.NumberStatistics + 2) >> 1);
|
||||
context.Statistics = Allocator.MoveUnitsUp(context.Statistics, unitCount);
|
||||
index = context.NumberStatistics;
|
||||
for (state = context.Statistics + index; state >= context.Statistics; state--)
|
||||
{
|
||||
if (state.Successor < Allocator.BaseUnit)
|
||||
{
|
||||
state.Successor = PpmContext.Zero;
|
||||
Swap(state, context.Statistics[index--]);
|
||||
}
|
||||
else if (order < modelOrder)
|
||||
state.Successor = CutOff(order + 1, state.Successor);
|
||||
else
|
||||
state.Successor = PpmContext.Zero;
|
||||
}
|
||||
|
||||
if (index != context.NumberStatistics && order != 0)
|
||||
{
|
||||
context.NumberStatistics = (byte)index;
|
||||
state = context.Statistics;
|
||||
if (index < 0)
|
||||
{
|
||||
Allocator.FreeUnits(state, unitCount);
|
||||
Allocator.SpecialFreeUnits(context);
|
||||
return PpmContext.Zero;
|
||||
}
|
||||
else if (index == 0)
|
||||
{
|
||||
context.Flags = (byte)((context.Flags & 0x10) + ((state.Symbol >= 0x40) ? 0x08 : 0x00));
|
||||
Copy(context.FirstState, state);
|
||||
Allocator.FreeUnits(state, unitCount);
|
||||
context.FirstStateFrequency = (byte)((context.FirstStateFrequency + 11) >> 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
Refresh(unitCount, context.SummaryFrequency > 16 * index, context);
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private PpmContext RemoveBinaryContexts(int order, PpmContext context)
|
||||
{
|
||||
if (context.NumberStatistics == 0)
|
||||
{
|
||||
PpmState state = context.FirstState;
|
||||
if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder)
|
||||
state.Successor = RemoveBinaryContexts(order + 1, state.Successor);
|
||||
else
|
||||
state.Successor = PpmContext.Zero;
|
||||
if ((state.Successor == PpmContext.Zero) && (context.Suffix.NumberStatistics == 0 || context.Suffix.Flags == 0xff))
|
||||
{
|
||||
Allocator.FreeUnits(context, 1);
|
||||
return PpmContext.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
for (PpmState state = context.Statistics + context.NumberStatistics; state >= context.Statistics; state--)
|
||||
{
|
||||
if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder)
|
||||
state.Successor = RemoveBinaryContexts(order + 1, state.Successor);
|
||||
else
|
||||
state.Successor = PpmContext.Zero;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
}
|
||||
206
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/PpmState.cs
vendored
Normal file
206
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/PpmState.cs
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
#region Using
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// PPM state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This must be a structure rather than a class because several places in the associated code assume that
|
||||
/// <see cref="PpmState"/> is a value type (meaning that assignment creates a completely new copy of the
|
||||
/// instance rather than just copying a reference to the same instance).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Note that <see cref="Address"/> is a field rather than a property for performance reasons.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal struct PpmState
|
||||
{
|
||||
public uint Address;
|
||||
public byte[] Memory;
|
||||
public static readonly PpmState Zero = new PpmState(0, null);
|
||||
public const int Size = 6;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PpmState"/> structure.
|
||||
/// </summary>
|
||||
public PpmState(uint address, byte[] memory)
|
||||
{
|
||||
Address = address;
|
||||
Memory = memory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the symbol.
|
||||
/// </summary>
|
||||
public byte Symbol
|
||||
{
|
||||
get { return Memory[Address]; }
|
||||
set { Memory[Address] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the frequency.
|
||||
/// </summary>
|
||||
public byte Frequency
|
||||
{
|
||||
get { return Memory[Address + 1]; }
|
||||
set { Memory[Address + 1] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the successor.
|
||||
/// </summary>
|
||||
public Model.PpmContext Successor
|
||||
{
|
||||
get { return new Model.PpmContext(((uint) Memory[Address + 2]) | ((uint) Memory[Address + 3]) << 8 | ((uint) Memory[Address + 4]) << 16 | ((uint) Memory[Address + 5]) << 24, Memory); }
|
||||
set
|
||||
{
|
||||
Memory[Address + 2] = (byte) value.Address;
|
||||
Memory[Address + 3] = (byte) (value.Address >> 8);
|
||||
Memory[Address + 4] = (byte) (value.Address >> 16);
|
||||
Memory[Address + 5] = (byte) (value.Address >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="PpmState"/> at the <paramref name="offset"/> relative to this
|
||||
/// <see cref="PpmState"/>.
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public PpmState this[int offset]
|
||||
{
|
||||
get { return new PpmState((uint) (Address + offset * Size), Memory); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow a pointer to be implicitly converted to a PPM state.
|
||||
/// </summary>
|
||||
/// <param name="pointer"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator PpmState(Pointer pointer)
|
||||
{
|
||||
return new PpmState(pointer.Address, pointer.Memory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like addition on a PPM state.
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static PpmState operator +(PpmState state, int offset)
|
||||
{
|
||||
state.Address = (uint) (state.Address + offset * Size);
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like incrementing on a PPM state.
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <returns></returns>
|
||||
public static PpmState operator ++(PpmState state)
|
||||
{
|
||||
state.Address += Size;
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like subtraction on a PPM state.
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public static PpmState operator -(PpmState state, int offset)
|
||||
{
|
||||
state.Address = (uint) (state.Address - offset * Size);
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow pointer-like decrementing on a PPM state.
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <returns></returns>
|
||||
public static PpmState operator --(PpmState state)
|
||||
{
|
||||
state.Address -= Size;
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM states.
|
||||
/// </summary>
|
||||
/// <param name="state1"></param>
|
||||
/// <param name="state2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator <=(PpmState state1, PpmState state2)
|
||||
{
|
||||
return state1.Address <= state2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM states.
|
||||
/// </summary>
|
||||
/// <param name="state1"></param>
|
||||
/// <param name="state2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator >=(PpmState state1, PpmState state2)
|
||||
{
|
||||
return state1.Address >= state2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM states.
|
||||
/// </summary>
|
||||
/// <param name="state1"></param>
|
||||
/// <param name="state2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator ==(PpmState state1, PpmState state2)
|
||||
{
|
||||
return state1.Address == state2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two PPM states.
|
||||
/// </summary>
|
||||
/// <param name="state1"></param>
|
||||
/// <param name="state2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool operator !=(PpmState state1, PpmState state2)
|
||||
{
|
||||
return state1.Address != state2.Address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <returns>true if obj and this instance are the same type and represent the same value; otherwise, false.</returns>
|
||||
/// <param name="obj">Another object to compare to.</param>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is PpmState)
|
||||
{
|
||||
PpmState state = (PpmState) obj;
|
||||
return state.Address == Address;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Address.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/See2Context.cs
vendored
Normal file
55
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/I1/See2Context.cs
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
#region Using
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd.I1
|
||||
{
|
||||
/// <summary>
|
||||
/// SEE2 (secondary escape estimation) contexts for PPM contexts with masked symbols.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This must be a class rather than a structure because MakeEscapeFrequency returns a See2Context
|
||||
/// instance from the see2Contexts array. The caller (for example, EncodeSymbol2) then updates the
|
||||
/// returned See2Context instance and expects the updates to be reflected in the see2Contexts array.
|
||||
/// This would not happen if this were a structure.
|
||||
/// </para>
|
||||
/// <remarks>
|
||||
/// Note that in most cases fields are used rather than properties for performance reasons (for example,
|
||||
/// <see cref="Shift"/> is a field rather than a property).
|
||||
/// </remarks>
|
||||
/// </remarks>
|
||||
internal class See2Context
|
||||
{
|
||||
private const byte PeriodBitCount = 7;
|
||||
|
||||
public ushort Summary;
|
||||
public byte Shift;
|
||||
public byte Count;
|
||||
|
||||
public void Initialize(uint initialValue)
|
||||
{
|
||||
Shift = PeriodBitCount - 4;
|
||||
Summary = (ushort) (initialValue << Shift);
|
||||
Count = 7;
|
||||
}
|
||||
|
||||
public uint Mean()
|
||||
{
|
||||
uint value = (uint) (Summary >> Shift);
|
||||
Summary = (ushort) (Summary - value);
|
||||
return (uint) (value + ((value == 0) ? 1 : 0));
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Shift < PeriodBitCount && --Count == 0)
|
||||
{
|
||||
Summary += Summary;
|
||||
Count = (byte) (3 << Shift++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
81
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/PpmdProperties.cs
vendored
Normal file
81
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/PpmdProperties.cs
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd
|
||||
{
|
||||
public enum PpmdVersion
|
||||
{
|
||||
H,
|
||||
H7z,
|
||||
I1,
|
||||
}
|
||||
|
||||
public class PpmdProperties
|
||||
{
|
||||
public PpmdVersion Version = PpmdVersion.I1;
|
||||
public int ModelOrder;
|
||||
internal I1.ModelRestorationMethod ModelRestorationMethod;
|
||||
|
||||
private int allocatorSize;
|
||||
internal I1.Allocator Allocator;
|
||||
|
||||
public PpmdProperties()
|
||||
: this(16 << 20, 6)
|
||||
{
|
||||
}
|
||||
|
||||
public PpmdProperties(int allocatorSize, int modelOrder)
|
||||
: this(allocatorSize, modelOrder, I1.ModelRestorationMethod.Restart)
|
||||
{
|
||||
}
|
||||
|
||||
internal PpmdProperties(int allocatorSize, int modelOrder, I1.ModelRestorationMethod modelRestorationMethod)
|
||||
{
|
||||
AllocatorSize = allocatorSize;
|
||||
ModelOrder = modelOrder;
|
||||
ModelRestorationMethod = modelRestorationMethod;
|
||||
}
|
||||
|
||||
public PpmdProperties(byte[] properties)
|
||||
{
|
||||
if (properties.Length == 2)
|
||||
{
|
||||
ushort props = BitConverter.ToUInt16(properties, 0);
|
||||
AllocatorSize = (((props >> 4) & 0xff) + 1) << 20;
|
||||
ModelOrder = (props & 0x0f) + 1;
|
||||
ModelRestorationMethod = (I1.ModelRestorationMethod)(props >> 12);
|
||||
}
|
||||
else if (properties.Length == 5)
|
||||
{
|
||||
Version = PpmdVersion.H7z;
|
||||
AllocatorSize = BitConverter.ToInt32(properties, 1);
|
||||
ModelOrder = properties[0];
|
||||
}
|
||||
}
|
||||
|
||||
public int AllocatorSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return allocatorSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
allocatorSize = value;
|
||||
if (Version == PpmdVersion.I1)
|
||||
{
|
||||
if (Allocator == null)
|
||||
Allocator = new I1.Allocator();
|
||||
Allocator.Start(allocatorSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
return BitConverter.GetBytes((ushort)((ModelOrder - 1) + (((AllocatorSize >> 20) - 1) << 4) + ((ushort)ModelRestorationMethod << 12)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
154
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/PpmdStream.cs
vendored
Normal file
154
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/PpmdStream.cs
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Compress.SevenZip.Compress.RangeCoder;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd
|
||||
{
|
||||
public class PpmdStream : Stream
|
||||
{
|
||||
private PpmdProperties properties;
|
||||
private Stream stream;
|
||||
private bool compress;
|
||||
private I1.Model model;
|
||||
private H.ModelPPM modelH;
|
||||
private Decoder decoder;
|
||||
private long position = 0;
|
||||
|
||||
public PpmdStream(PpmdProperties properties, Stream stream, bool compress)
|
||||
{
|
||||
this.properties = properties;
|
||||
this.stream = stream;
|
||||
this.compress = compress;
|
||||
|
||||
if (properties.Version == PpmdVersion.I1)
|
||||
{
|
||||
model = new I1.Model();
|
||||
if (compress)
|
||||
model.EncodeStart(properties);
|
||||
else
|
||||
model.DecodeStart(stream, properties);
|
||||
}
|
||||
if (properties.Version == PpmdVersion.H)
|
||||
{
|
||||
modelH = new H.ModelPPM();
|
||||
if (compress)
|
||||
throw new NotImplementedException();
|
||||
else
|
||||
modelH.decodeInit(stream, properties.ModelOrder, properties.AllocatorSize);
|
||||
}
|
||||
if (properties.Version == PpmdVersion.H7z)
|
||||
{
|
||||
modelH = new H.ModelPPM();
|
||||
if (compress)
|
||||
throw new NotImplementedException();
|
||||
else
|
||||
modelH.decodeInit(null, properties.ModelOrder, properties.AllocatorSize);
|
||||
decoder = new Decoder();
|
||||
decoder.Init(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return !compress; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return compress; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
if (isDisposing)
|
||||
{
|
||||
if (compress)
|
||||
model.EncodeBlock(stream, new MemoryStream(), true);
|
||||
}
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return position;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (compress)
|
||||
return 0;
|
||||
int size = 0;
|
||||
if (properties.Version == PpmdVersion.I1)
|
||||
size = model.DecodeBlock(stream, buffer, offset, count);
|
||||
if (properties.Version == PpmdVersion.H)
|
||||
{
|
||||
int c;
|
||||
while (size < count && (c = modelH.decodeChar()) >= 0)
|
||||
{
|
||||
buffer[offset++] = (byte)c;
|
||||
size++;
|
||||
}
|
||||
}
|
||||
if (properties.Version == PpmdVersion.H7z)
|
||||
{
|
||||
int c;
|
||||
while (size < count && (c = modelH.decodeChar(decoder)) >= 0)
|
||||
{
|
||||
buffer[offset++] = (byte)c;
|
||||
size++;
|
||||
}
|
||||
}
|
||||
position += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (origin != SeekOrigin.Current)
|
||||
throw new NotImplementedException();
|
||||
|
||||
byte[] tmpBuff = new byte[1024];
|
||||
long sizeToGo = offset;
|
||||
while (sizeToGo > 0)
|
||||
{
|
||||
int sizenow = sizeToGo > 1024 ? 1024 : (int)sizeToGo;
|
||||
Read(tmpBuff, 0, sizenow);
|
||||
sizeToGo -= sizenow;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (compress)
|
||||
model.EncodeBlock(stream, new MemoryStream(buffer, offset, count), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
467
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/Utility.cs
vendored
Normal file
467
SabreTools.Library/External/Compress/SevenZip/Compress/PPmd/Utility.cs
vendored
Normal file
@@ -0,0 +1,467 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Compress.SevenZip.Compress.PPmd
|
||||
{
|
||||
internal static class Utility
|
||||
{
|
||||
public static ReadOnlyCollection<T> ToReadOnly<T>(this IEnumerable<T> items)
|
||||
{
|
||||
return new ReadOnlyCollection<T>(items.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an unsigned bitwise right shift with the specified number
|
||||
/// </summary>
|
||||
/// <param name="number">Number to operate on</param>
|
||||
/// <param name="bits">Ammount of bits to shift</param>
|
||||
/// <returns>The resulting number from the shift operation</returns>
|
||||
public static int URShift(int number, int bits)
|
||||
{
|
||||
if (number >= 0)
|
||||
return number >> bits;
|
||||
else
|
||||
return (number >> bits) + (2 << ~bits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an unsigned bitwise right shift with the specified number
|
||||
/// </summary>
|
||||
/// <param name="number">Number to operate on</param>
|
||||
/// <param name="bits">Ammount of bits to shift</param>
|
||||
/// <returns>The resulting number from the shift operation</returns>
|
||||
public static int URShift(int number, long bits)
|
||||
{
|
||||
return URShift(number, (int)bits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an unsigned bitwise right shift with the specified number
|
||||
/// </summary>
|
||||
/// <param name="number">Number to operate on</param>
|
||||
/// <param name="bits">Ammount of bits to shift</param>
|
||||
/// <returns>The resulting number from the shift operation</returns>
|
||||
public static long URShift(long number, int bits)
|
||||
{
|
||||
if (number >= 0)
|
||||
return number >> bits;
|
||||
else
|
||||
return (number >> bits) + (2L << ~bits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an unsigned bitwise right shift with the specified number
|
||||
/// </summary>
|
||||
/// <param name="number">Number to operate on</param>
|
||||
/// <param name="bits">Ammount of bits to shift</param>
|
||||
/// <returns>The resulting number from the shift operation</returns>
|
||||
public static long URShift(long number, long bits)
|
||||
{
|
||||
return URShift(number, (int)bits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the array with an specific value from an specific index to an specific index.
|
||||
/// </summary>
|
||||
/// <param name="array">The array to be filled.</param>
|
||||
/// <param name="fromindex">The first index to be filled.</param>
|
||||
/// <param name="toindex">The last index to be filled.</param>
|
||||
/// <param name="val">The value to fill the array with.</param>
|
||||
public static void Fill<T>(T[] array, int fromindex, int toindex, T val) where T : struct
|
||||
{
|
||||
if (array.Length == 0)
|
||||
{
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
if (fromindex > toindex)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
if ((fromindex < 0) || ((System.Array)array).Length < toindex)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
for (int index = (fromindex > 0) ? fromindex-- : fromindex; index < toindex; index++)
|
||||
{
|
||||
array[index] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the array with an specific value.
|
||||
/// </summary>
|
||||
/// <param name="array">The array to be filled.</param>
|
||||
/// <param name="val">The value to fill the array with.</param>
|
||||
public static void Fill<T>(T[] array, T val) where T : struct
|
||||
{
|
||||
Fill(array, 0, array.Length, val);
|
||||
}
|
||||
|
||||
public static void SetSize(this List<byte> list, int count)
|
||||
{
|
||||
if (count > list.Count)
|
||||
{
|
||||
for (int i = list.Count; i < count; i++)
|
||||
{
|
||||
list.Add(0x0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] temp = new byte[count];
|
||||
list.CopyTo(temp, 0);
|
||||
list.Clear();
|
||||
list.AddRange(temp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Read a int value from the byte array at the given position (Big Endian)
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="array">the array to read from
|
||||
/// </param>
|
||||
/// <param name="pos">the offset
|
||||
/// </param>
|
||||
/// <returns> the value
|
||||
/// </returns>
|
||||
public static int readIntBigEndian(byte[] array, int pos)
|
||||
{
|
||||
int temp = 0;
|
||||
temp |= array[pos] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 1] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 2] & 0xff;
|
||||
temp <<= 8;
|
||||
temp |= array[pos + 3] & 0xff;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/// <summary> Read a short value from the byte array at the given position (little
|
||||
/// Endian)
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="array">the array to read from
|
||||
/// </param>
|
||||
/// <param name="pos">the offset
|
||||
/// </param>
|
||||
/// <returns> the value
|
||||
/// </returns>
|
||||
public static short readShortLittleEndian(byte[] array, int pos)
|
||||
{
|
||||
return BitConverter.ToInt16(array, pos);
|
||||
}
|
||||
|
||||
/// <summary> Read an int value from the byte array at the given position (little
|
||||
/// Endian)
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="array">the array to read from
|
||||
/// </param>
|
||||
/// <param name="pos">the offset
|
||||
/// </param>
|
||||
/// <returns> the value
|
||||
/// </returns>
|
||||
public static int readIntLittleEndian(byte[] array, int pos)
|
||||
{
|
||||
return BitConverter.ToInt32(array, pos);
|
||||
}
|
||||
|
||||
/// <summary> Write an int value into the byte array at the given position (Big endian)
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="array">the array
|
||||
/// </param>
|
||||
/// <param name="pos">the offset
|
||||
/// </param>
|
||||
/// <param name="value">the value to write
|
||||
/// </param>
|
||||
public static void writeIntBigEndian(byte[] array, int pos, int value)
|
||||
{
|
||||
array[pos] = (byte)((Utility.URShift(value, 24)) & 0xff);
|
||||
array[pos + 1] = (byte)((Utility.URShift(value, 16)) & 0xff);
|
||||
array[pos + 2] = (byte)((Utility.URShift(value, 8)) & 0xff);
|
||||
array[pos + 3] = (byte)((value) & 0xff);
|
||||
}
|
||||
|
||||
/// <summary> Write a short value into the byte array at the given position (little
|
||||
/// endian)
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="array">the array
|
||||
/// </param>
|
||||
/// <param name="pos">the offset
|
||||
/// </param>
|
||||
/// <param name="value">the value to write
|
||||
/// </param>
|
||||
public static void WriteLittleEndian(byte[] array, int pos, short value)
|
||||
{
|
||||
byte[] newBytes = BitConverter.GetBytes(value);
|
||||
Array.Copy(newBytes, 0, array, pos, newBytes.Length);
|
||||
}
|
||||
|
||||
/// <summary> Increment a short value at the specified position by the specified amount
|
||||
/// (little endian).
|
||||
/// </summary>
|
||||
public static void incShortLittleEndian(byte[] array, int pos, short incrementValue)
|
||||
{
|
||||
short existingValue = BitConverter.ToInt16(array, pos);
|
||||
existingValue += incrementValue;
|
||||
WriteLittleEndian(array, pos, existingValue);
|
||||
//int c = Utility.URShift(((array[pos] & 0xff) + (dv & 0xff)), 8);
|
||||
//array[pos] = (byte)(array[pos] + (dv & 0xff));
|
||||
//if ((c > 0) || ((dv & 0xff00) != 0))
|
||||
//{
|
||||
// array[pos + 1] = (byte)(array[pos + 1] + ((Utility.URShift(dv, 8)) & 0xff) + c);
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary> Write an int value into the byte array at the given position (little
|
||||
/// endian)
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="array">the array
|
||||
/// </param>
|
||||
/// <param name="pos">the offset
|
||||
/// </param>
|
||||
/// <param name="value">the value to write
|
||||
/// </param>
|
||||
public static void WriteLittleEndian(byte[] array, int pos, int value)
|
||||
{
|
||||
byte[] newBytes = BitConverter.GetBytes(value);
|
||||
Array.Copy(newBytes, 0, array, pos, newBytes.Length);
|
||||
}
|
||||
|
||||
public static void Initialize<T>(this T[] array, Func<T> func)
|
||||
{
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = func();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddRange<T>(this ICollection<T> destination, IEnumerable<T> source)
|
||||
{
|
||||
foreach (T item in source)
|
||||
{
|
||||
destination.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
|
||||
{
|
||||
foreach (T item in items)
|
||||
{
|
||||
action(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<T> AsEnumerable<T>(this T item)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
|
||||
public static void CheckNotNull(this object obj, string name)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckNotNullOrEmpty(this string obj, string name)
|
||||
{
|
||||
obj.CheckNotNull(name);
|
||||
if (obj.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("String is empty.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Skip(this Stream source, long advanceAmount)
|
||||
{
|
||||
byte[] buffer = new byte[32 * 1024];
|
||||
int read = 0;
|
||||
int readCount = 0;
|
||||
do
|
||||
{
|
||||
readCount = buffer.Length;
|
||||
if (readCount > advanceAmount)
|
||||
{
|
||||
readCount = (int)advanceAmount;
|
||||
}
|
||||
read = source.Read(buffer, 0, readCount);
|
||||
if (read < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
advanceAmount -= read;
|
||||
if (advanceAmount == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
public static void SkipAll(this Stream source)
|
||||
{
|
||||
byte[] buffer = new byte[32 * 1024];
|
||||
do
|
||||
{
|
||||
} while (source.Read(buffer, 0, buffer.Length) == buffer.Length);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] UInt32ToBigEndianBytes(uint x)
|
||||
{
|
||||
return new byte[] {
|
||||
(byte)((x >> 24) & 0xff),
|
||||
(byte)((x >> 16) & 0xff),
|
||||
(byte)((x >> 8) & 0xff),
|
||||
(byte)(x & 0xff) };
|
||||
}
|
||||
|
||||
public static DateTime DosDateToDateTime(UInt16 iDate, UInt16 iTime)
|
||||
{
|
||||
int year = iDate / 512 + 1980;
|
||||
int month = iDate % 512 / 32;
|
||||
int day = iDate % 512 % 32;
|
||||
int hour = iTime / 2048;
|
||||
int minute = iTime % 2048 / 32;
|
||||
int second = iTime % 2048 % 32 * 2;
|
||||
|
||||
if (iDate == UInt16.MaxValue || month == 0 || day == 0)
|
||||
{
|
||||
year = 1980;
|
||||
month = 1;
|
||||
day = 1;
|
||||
}
|
||||
|
||||
if (iTime == UInt16.MaxValue)
|
||||
{
|
||||
hour = minute = second = 0;
|
||||
}
|
||||
|
||||
DateTime dt;
|
||||
try
|
||||
{
|
||||
dt = new DateTime(year, month, day, hour, minute, second);
|
||||
}
|
||||
catch
|
||||
{
|
||||
dt = new DateTime();
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
||||
public static uint DateTimeToDosTime(this DateTime? dateTime)
|
||||
{
|
||||
if (dateTime == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (uint)(
|
||||
(dateTime.Value.Second / 2) | (dateTime.Value.Minute << 5) | (dateTime.Value.Hour << 11) |
|
||||
(dateTime.Value.Day << 16) | (dateTime.Value.Month << 21) | ((dateTime.Value.Year - 1980) << 25));
|
||||
}
|
||||
|
||||
|
||||
public static DateTime DosDateToDateTime(UInt32 iTime)
|
||||
{
|
||||
return DosDateToDateTime((UInt16)(iTime / 65536),
|
||||
(UInt16)(iTime % 65536));
|
||||
}
|
||||
|
||||
public static DateTime DosDateToDateTime(Int32 iTime)
|
||||
{
|
||||
return DosDateToDateTime((UInt32)iTime);
|
||||
}
|
||||
|
||||
public static long TransferTo(this Stream source, Stream destination)
|
||||
{
|
||||
byte[] array = new byte[4096];
|
||||
int count;
|
||||
long total = 0;
|
||||
while ((count = source.Read(array, 0, array.Length)) != 0)
|
||||
{
|
||||
total += count;
|
||||
destination.Write(array, 0, count);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static bool ReadFully(this Stream stream, byte[] buffer)
|
||||
{
|
||||
int total = 0;
|
||||
int read;
|
||||
while ((read = stream.Read(buffer, total, buffer.Length - total)) > 0)
|
||||
{
|
||||
total += read;
|
||||
if (total >= buffer.Length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return (total >= buffer.Length);
|
||||
}
|
||||
|
||||
public static string TrimNulls(this string source)
|
||||
{
|
||||
return source.Replace('\0', ' ').Trim();
|
||||
}
|
||||
|
||||
public static bool BinaryEquals(this byte[] source, byte[] target)
|
||||
{
|
||||
if (source.Length != target.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < source.Length; ++i)
|
||||
{
|
||||
if (source[i] != target[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if PORTABLE
|
||||
public static void CopyTo(this byte[] array, byte[] destination, int index)
|
||||
{
|
||||
Array.Copy(array, 0, destination, index, array.Length);
|
||||
}
|
||||
|
||||
public static long HostToNetworkOrder(long host)
|
||||
{
|
||||
return (int)((long)HostToNetworkOrder((int)host)
|
||||
& unchecked((long)(unchecked((ulong)-1))) << 32
|
||||
| ((long)HostToNetworkOrder((int)((int)host >> 32)) & unchecked((long)(unchecked((ulong)-1)))));
|
||||
}
|
||||
public static int HostToNetworkOrder(int host)
|
||||
{
|
||||
return (int)((int)(HostToNetworkOrder((short)host) & -1) << 16 | (HostToNetworkOrder((short)(host >> 16)) & -1));
|
||||
}
|
||||
public static short HostToNetworkOrder(short host)
|
||||
{
|
||||
return (short)((int)(host & 255) << 8 | ((int)host >> 8 & 255));
|
||||
}
|
||||
public static long NetworkToHostOrder(long network)
|
||||
{
|
||||
return HostToNetworkOrder(network);
|
||||
}
|
||||
public static int NetworkToHostOrder(int network)
|
||||
{
|
||||
return HostToNetworkOrder(network);
|
||||
}
|
||||
public static short NetworkToHostOrder(short network)
|
||||
{
|
||||
return HostToNetworkOrder(network);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
247
SabreTools.Library/External/Compress/SevenZip/Compress/RangeCoder/RangeCoder.cs
vendored
Normal file
247
SabreTools.Library/External/Compress/SevenZip/Compress/RangeCoder/RangeCoder.cs
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
using System;
|
||||
|
||||
namespace Compress.SevenZip.Compress.RangeCoder
|
||||
{
|
||||
internal class Encoder
|
||||
{
|
||||
public const uint kTopValue = (1 << 24);
|
||||
|
||||
System.IO.Stream Stream;
|
||||
|
||||
public UInt64 Low;
|
||||
public uint Range;
|
||||
uint _cacheSize;
|
||||
byte _cache;
|
||||
|
||||
//long StartPosition;
|
||||
|
||||
public void SetStream(System.IO.Stream stream)
|
||||
{
|
||||
Stream = stream;
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
//StartPosition = Stream.Position;
|
||||
|
||||
Low = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
_cacheSize = 1;
|
||||
_cache = 0;
|
||||
}
|
||||
|
||||
public void FlushData()
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
ShiftLow();
|
||||
}
|
||||
|
||||
public void FlushStream()
|
||||
{
|
||||
Stream.Flush();
|
||||
}
|
||||
|
||||
public void CloseStream()
|
||||
{
|
||||
Stream.Dispose();
|
||||
}
|
||||
|
||||
public void Encode(uint start, uint size, uint total)
|
||||
{
|
||||
Low += start * (Range /= total);
|
||||
Range *= size;
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
public void ShiftLow()
|
||||
{
|
||||
if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1)
|
||||
{
|
||||
byte temp = _cache;
|
||||
do
|
||||
{
|
||||
Stream.WriteByte((byte)(temp + (Low >> 32)));
|
||||
temp = 0xFF;
|
||||
}
|
||||
while (--_cacheSize != 0);
|
||||
_cache = (byte)(((uint)Low) >> 24);
|
||||
}
|
||||
_cacheSize++;
|
||||
Low = ((uint)Low) << 8;
|
||||
}
|
||||
|
||||
public void EncodeDirectBits(uint v, int numTotalBits)
|
||||
{
|
||||
for (int i = numTotalBits - 1; i >= 0; i--)
|
||||
{
|
||||
Range >>= 1;
|
||||
if (((v >> i) & 1) == 1)
|
||||
Low += Range;
|
||||
if (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EncodeBit(uint size0, int numTotalBits, uint symbol)
|
||||
{
|
||||
uint newBound = (Range >> numTotalBits) * size0;
|
||||
if (symbol == 0)
|
||||
Range = newBound;
|
||||
else
|
||||
{
|
||||
Low += newBound;
|
||||
Range -= newBound;
|
||||
}
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
public long GetProcessedSizeAdd()
|
||||
{
|
||||
return -1;
|
||||
//return _cacheSize + Stream.Position - StartPosition + 4;
|
||||
// (long)Stream.GetProcessedSize();
|
||||
}
|
||||
}
|
||||
|
||||
internal class Decoder
|
||||
{
|
||||
public const uint kTopValue = (1 << 24);
|
||||
public uint Range;
|
||||
public uint Code = 0;
|
||||
// public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);
|
||||
public System.IO.Stream Stream;
|
||||
public long Total;
|
||||
|
||||
public void Init(System.IO.Stream stream)
|
||||
{
|
||||
// Stream.Init(stream);
|
||||
Stream = stream;
|
||||
|
||||
Code = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
for (int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | (byte)Stream.ReadByte();
|
||||
Total = 5;
|
||||
}
|
||||
|
||||
public void ReleaseStream()
|
||||
{
|
||||
// Stream.ReleaseStream();
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
public void CloseStream()
|
||||
{
|
||||
Stream.Dispose();
|
||||
}
|
||||
|
||||
public void Normalize()
|
||||
{
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Code = (Code << 8) | (byte)Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
Total++;
|
||||
}
|
||||
}
|
||||
|
||||
public void Normalize2()
|
||||
{
|
||||
if (Range < kTopValue)
|
||||
{
|
||||
Code = (Code << 8) | (byte)Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
Total++;
|
||||
}
|
||||
}
|
||||
|
||||
public uint GetThreshold(uint total)
|
||||
{
|
||||
return Code / (Range /= total);
|
||||
}
|
||||
|
||||
public void Decode(uint start, uint size)
|
||||
{
|
||||
Code -= start * Range;
|
||||
Range *= size;
|
||||
Normalize();
|
||||
}
|
||||
|
||||
public uint DecodeDirectBits(int numTotalBits)
|
||||
{
|
||||
uint range = Range;
|
||||
uint code = Code;
|
||||
uint result = 0;
|
||||
for (int i = numTotalBits; i > 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
/*
|
||||
result <<= 1;
|
||||
if (code >= range)
|
||||
{
|
||||
code -= range;
|
||||
result |= 1;
|
||||
}
|
||||
*/
|
||||
uint t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if (range < kTopValue)
|
||||
{
|
||||
code = (code << 8) | (byte)Stream.ReadByte();
|
||||
range <<= 8;
|
||||
Total++;
|
||||
}
|
||||
}
|
||||
Range = range;
|
||||
Code = code;
|
||||
return result;
|
||||
}
|
||||
|
||||
public uint DecodeBit(uint size0, int numTotalBits)
|
||||
{
|
||||
uint newBound = (Range >> numTotalBits) * size0;
|
||||
uint symbol;
|
||||
if (Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
Range = newBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = 1;
|
||||
Code -= newBound;
|
||||
Range -= newBound;
|
||||
}
|
||||
Normalize();
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public bool IsFinished
|
||||
{
|
||||
get
|
||||
{
|
||||
return Code == 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ulong GetProcessedSize() {return Stream.GetProcessedSize(); }
|
||||
}
|
||||
}
|
||||
119
SabreTools.Library/External/Compress/SevenZip/Compress/RangeCoder/RangeCoderBit.cs
vendored
Normal file
119
SabreTools.Library/External/Compress/SevenZip/Compress/RangeCoder/RangeCoderBit.cs
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
|
||||
namespace Compress.SevenZip.Compress.RangeCoder
|
||||
{
|
||||
internal struct BitEncoder
|
||||
{
|
||||
public const int kNumBitModelTotalBits = 11;
|
||||
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
const int kNumMoveBits = 5;
|
||||
const int kNumMoveReducingBits = 2;
|
||||
public const int kNumBitPriceShiftBits = 6;
|
||||
|
||||
uint Prob;
|
||||
|
||||
public void Init() { Prob = kBitModelTotal >> 1; }
|
||||
|
||||
public void UpdateModel(uint symbol)
|
||||
{
|
||||
if (symbol == 0)
|
||||
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
|
||||
else
|
||||
Prob -= (Prob) >> kNumMoveBits;
|
||||
}
|
||||
|
||||
public void Encode(Encoder encoder, uint symbol)
|
||||
{
|
||||
// encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
|
||||
// UpdateModel(symbol);
|
||||
uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob;
|
||||
if (symbol == 0)
|
||||
{
|
||||
encoder.Range = newBound;
|
||||
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder.Low += newBound;
|
||||
encoder.Range -= newBound;
|
||||
Prob -= (Prob) >> kNumMoveBits;
|
||||
}
|
||||
if (encoder.Range < Encoder.kTopValue)
|
||||
{
|
||||
encoder.Range <<= 8;
|
||||
encoder.ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits];
|
||||
|
||||
static BitEncoder()
|
||||
{
|
||||
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for (int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
UInt32 start = (UInt32)1 << (kNumBits - i - 1);
|
||||
UInt32 end = (UInt32)1 << (kNumBits - i);
|
||||
for (UInt32 j = start; j < end; j++)
|
||||
ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
public uint GetPrice(uint symbol)
|
||||
{
|
||||
return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
}
|
||||
public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; }
|
||||
public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; }
|
||||
}
|
||||
|
||||
internal struct BitDecoder
|
||||
{
|
||||
public const int kNumBitModelTotalBits = 11;
|
||||
public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
uint Prob;
|
||||
|
||||
public void UpdateModel(int numMoveBits, uint symbol)
|
||||
{
|
||||
if (symbol == 0)
|
||||
Prob += (kBitModelTotal - Prob) >> numMoveBits;
|
||||
else
|
||||
Prob -= (Prob) >> numMoveBits;
|
||||
}
|
||||
|
||||
public void Init() { Prob = kBitModelTotal >> 1; }
|
||||
|
||||
public uint Decode(RangeCoder.Decoder rangeDecoder)
|
||||
{
|
||||
uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob;
|
||||
if (rangeDecoder.Code < newBound)
|
||||
{
|
||||
rangeDecoder.Range = newBound;
|
||||
Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
|
||||
if (rangeDecoder.Range < Decoder.kTopValue)
|
||||
{
|
||||
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
|
||||
rangeDecoder.Range <<= 8;
|
||||
rangeDecoder.Total++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeDecoder.Range -= newBound;
|
||||
rangeDecoder.Code -= newBound;
|
||||
Prob -= (Prob) >> kNumMoveBits;
|
||||
if (rangeDecoder.Range < Decoder.kTopValue)
|
||||
{
|
||||
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
|
||||
rangeDecoder.Range <<= 8;
|
||||
rangeDecoder.Total++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
157
SabreTools.Library/External/Compress/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs
vendored
Normal file
157
SabreTools.Library/External/Compress/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
|
||||
namespace Compress.SevenZip.Compress.RangeCoder
|
||||
{
|
||||
internal struct BitTreeEncoder
|
||||
{
|
||||
BitEncoder[] Models;
|
||||
int NumBitLevels;
|
||||
|
||||
public BitTreeEncoder(int numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new BitEncoder[1 << numBitLevels];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
for (uint i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
|
||||
public void Encode(Encoder rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UInt32 m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex > 0; )
|
||||
{
|
||||
bitIndex--;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
Models[m].Encode(rangeEncoder, bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UInt32 m = 1;
|
||||
for (UInt32 i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[m].Encode(rangeEncoder, bit);
|
||||
m = (m << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
public UInt32 GetPrice(UInt32 symbol)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex > 0; )
|
||||
{
|
||||
bitIndex--;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
price += Models[m].GetPrice(bit);
|
||||
m = (m << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public UInt32 ReverseGetPrice(UInt32 symbol)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 m = 1;
|
||||
for (int i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[m].GetPrice(bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,
|
||||
int NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 m = 1;
|
||||
for (int i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[startIndex + m].GetPrice(bit);
|
||||
m = (m << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,
|
||||
Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
UInt32 m = 1;
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[startIndex + m].Encode(rangeEncoder, bit);
|
||||
m = (m << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal struct BitTreeDecoder
|
||||
{
|
||||
BitDecoder[] Models;
|
||||
int NumBitLevels;
|
||||
|
||||
public BitTreeDecoder(int numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new BitDecoder[1 << numBitLevels];
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
for (uint i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
|
||||
public uint Decode(RangeCoder.Decoder rangeDecoder)
|
||||
{
|
||||
uint m = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
m = (m << 1) + Models[m].Decode(rangeDecoder);
|
||||
return m - ((uint)1 << NumBitLevels);
|
||||
}
|
||||
|
||||
public uint ReverseDecode(RangeCoder.Decoder rangeDecoder)
|
||||
{
|
||||
uint m = 1;
|
||||
uint symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
uint bit = Models[m].Decode(rangeDecoder);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
|
||||
RangeCoder.Decoder rangeDecoder, int NumBitLevels)
|
||||
{
|
||||
uint m = 1;
|
||||
uint symbol = 0;
|
||||
for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
uint bit = Models[startIndex + m].Decode(rangeDecoder);
|
||||
m <<= 1;
|
||||
m += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
204
SabreTools.Library/External/Compress/SevenZip/Filters/BCJ2Filter.cs
vendored
Normal file
204
SabreTools.Library/External/Compress/SevenZip/Filters/BCJ2Filter.cs
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Compress.SevenZip.Filters
|
||||
{
|
||||
public class BCJ2Filter : Stream
|
||||
{
|
||||
private Stream baseStream;
|
||||
|
||||
private long position = 0;
|
||||
private byte[] output = new byte[4];
|
||||
private int outputOffset = 0;
|
||||
private int outputCount = 0;
|
||||
|
||||
private Stream control;
|
||||
private Stream data1;
|
||||
private Stream data2;
|
||||
|
||||
private ushort[] p = new ushort[256 + 2];
|
||||
private uint range, code;
|
||||
private byte prevByte = 0;
|
||||
|
||||
private const int kNumTopBits = 24;
|
||||
private const int kTopValue = 1 << kNumTopBits;
|
||||
|
||||
private const int kNumBitModelTotalBits = 11;
|
||||
private const int kBitModelTotal = 1 << kNumBitModelTotalBits;
|
||||
private const int kNumMoveBits = 5;
|
||||
|
||||
private static bool IsJ(byte b0, byte b1)
|
||||
{
|
||||
return (b1 & 0xFE) == 0xE8 || IsJcc(b0, b1);
|
||||
}
|
||||
|
||||
private static bool IsJcc(byte b0, byte b1)
|
||||
{
|
||||
return b0 == 0x0F && (b1 & 0xF0) == 0x80;
|
||||
}
|
||||
|
||||
public BCJ2Filter(Stream baseStream, Stream data1, Stream data2, Stream control)
|
||||
{
|
||||
this.control = control;
|
||||
this.data1 = data1;
|
||||
this.data2 = data2;
|
||||
this.baseStream = baseStream;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < p.Length; i++)
|
||||
p[i] = kBitModelTotal >> 1;
|
||||
|
||||
code = 0;
|
||||
range = 0xFFFFFFFF;
|
||||
|
||||
byte[] controlbuf=new byte[5];
|
||||
control.Read(controlbuf, 0, 5);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
code = (code << 8) | controlbuf[i];
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { return baseStream.Length + data1.Length + data2.Length; }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return position;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int size = 0;
|
||||
byte b = 0;
|
||||
|
||||
while (size < count)
|
||||
{
|
||||
while (outputOffset < outputCount)
|
||||
{
|
||||
b = output[outputOffset++];
|
||||
buffer[offset++] = b;
|
||||
size++;
|
||||
position++;
|
||||
|
||||
prevByte = b;
|
||||
if (size == count)
|
||||
return size;
|
||||
}
|
||||
|
||||
b = (byte)baseStream.ReadByte();
|
||||
buffer[offset++] = b;
|
||||
size++;
|
||||
position++;
|
||||
|
||||
if (!IsJ(prevByte, b))
|
||||
prevByte = b;
|
||||
else
|
||||
{
|
||||
int prob;
|
||||
if (b == 0xE8)
|
||||
prob = prevByte;
|
||||
else if (b == 0xE9)
|
||||
prob = 256;
|
||||
else
|
||||
prob = 257;
|
||||
|
||||
uint bound = (range >> kNumBitModelTotalBits) * p[prob];
|
||||
if (code < bound)
|
||||
{
|
||||
range = bound;
|
||||
p[prob] += (ushort)((kBitModelTotal - p[prob]) >> kNumMoveBits);
|
||||
if (range < kTopValue)
|
||||
{
|
||||
range <<= 8;
|
||||
code = (code << 8) | (byte)control.ReadByte();
|
||||
}
|
||||
prevByte = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
range -= bound;
|
||||
code -= bound;
|
||||
p[prob] -= (ushort)(p[prob] >> kNumMoveBits);
|
||||
if (range < kTopValue)
|
||||
{
|
||||
range <<= 8;
|
||||
code = (code << 8) | (byte)control.ReadByte();
|
||||
}
|
||||
|
||||
uint dest;
|
||||
if (b == 0xE8)
|
||||
dest = (uint)((data1.ReadByte() << 24) | (data1.ReadByte() << 16) | (data1.ReadByte() << 8) | data1.ReadByte());
|
||||
else
|
||||
dest = (uint)((data2.ReadByte() << 24) | (data2.ReadByte() << 16) | (data2.ReadByte() << 8) | data2.ReadByte());
|
||||
dest -= (uint)(position + 4);
|
||||
|
||||
output[0] = (byte)dest;
|
||||
output[1] = (byte)(dest >> 8);
|
||||
output[2] = (byte)(dest >> 16);
|
||||
output[3] = (byte)(dest >> 24);
|
||||
outputOffset = 0;
|
||||
outputCount = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (origin != SeekOrigin.Current)
|
||||
throw new NotImplementedException();
|
||||
|
||||
const int bufferSize = 10240;
|
||||
byte[] seekBuffer = new byte[bufferSize];
|
||||
long seekToGo = offset;
|
||||
while (seekToGo > 0)
|
||||
{
|
||||
long get = seekToGo > bufferSize ? bufferSize : seekToGo;
|
||||
Read(seekBuffer, 0, (int)get);
|
||||
seekToGo -= get;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
90
SabreTools.Library/External/Compress/SevenZip/Filters/BCJFilter.cs
vendored
Normal file
90
SabreTools.Library/External/Compress/SevenZip/Filters/BCJFilter.cs
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Compress.SevenZip.Filters
|
||||
{
|
||||
public class BCJFilter : Filter
|
||||
{
|
||||
private static readonly bool[] MASK_TO_ALLOWED_STATUS = new bool[] {true, true, true, false, true, false, false, false};
|
||||
private static readonly int[] MASK_TO_BIT_NUMBER = new int[] { 0, 1, 2, 2, 3, 3, 3, 3 };
|
||||
|
||||
private int pos;
|
||||
private int prevMask = 0;
|
||||
|
||||
public BCJFilter(bool isEncoder, Stream baseStream) : base(isEncoder, baseStream, 5)
|
||||
{
|
||||
pos = 5;
|
||||
}
|
||||
|
||||
private static bool test86MSByte(byte b)
|
||||
{
|
||||
return b == 0x00 || b == 0xFF;
|
||||
}
|
||||
|
||||
protected override int Transform(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int prevPos = offset - 1;
|
||||
int end = offset + count - 5;
|
||||
int i;
|
||||
|
||||
for (i = offset; i <= end; ++i) {
|
||||
if ((buffer[i] & 0xFE) != 0xE8)
|
||||
continue;
|
||||
|
||||
prevPos = i - prevPos;
|
||||
if ((prevPos & ~3) != 0) { // (unsigned)prevPos > 3
|
||||
prevMask = 0;
|
||||
} else {
|
||||
prevMask = (prevMask << (prevPos - 1)) & 7;
|
||||
if (prevMask != 0) {
|
||||
if (!MASK_TO_ALLOWED_STATUS[prevMask] || test86MSByte(
|
||||
buffer[i + 4 - MASK_TO_BIT_NUMBER[prevMask]])) {
|
||||
prevPos = i;
|
||||
prevMask = (prevMask << 1) | 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevPos = i;
|
||||
|
||||
if (test86MSByte(buffer[i + 4])) {
|
||||
int src = buffer[i + 1]
|
||||
| (buffer[i + 2] << 8)
|
||||
| (buffer[i + 3] << 16)
|
||||
| (buffer[i + 4] << 24);
|
||||
int dest;
|
||||
while (true) {
|
||||
if (isEncoder)
|
||||
dest = src + (pos + i - offset);
|
||||
else
|
||||
dest = src - (pos + i - offset);
|
||||
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
|
||||
int index = MASK_TO_BIT_NUMBER[prevMask] * 8;
|
||||
if (!test86MSByte((byte)(dest >> (24 - index))))
|
||||
break;
|
||||
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
|
||||
buffer[i + 1] = (byte)dest;
|
||||
buffer[i + 2] = (byte)(dest >> 8);
|
||||
buffer[i + 3] = (byte)(dest >> 16);
|
||||
buffer[i + 4] = (byte)(~(((dest >> 24) & 1) - 1));
|
||||
i += 4;
|
||||
} else {
|
||||
prevMask = (prevMask << 1) | 1;
|
||||
}
|
||||
}
|
||||
|
||||
prevPos = i - prevPos;
|
||||
prevMask = ((prevPos & ~3) != 0) ? 0 : prevMask << (prevPos - 1);
|
||||
|
||||
i -= offset;
|
||||
pos += i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
100
SabreTools.Library/External/Compress/SevenZip/Filters/Delta.cs
vendored
Normal file
100
SabreTools.Library/External/Compress/SevenZip/Filters/Delta.cs
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Compress.SevenZip.Filters
|
||||
{
|
||||
public class Delta : Stream
|
||||
{
|
||||
private readonly Stream _baseStream;
|
||||
private long _position;
|
||||
private readonly byte[] _bVal;
|
||||
private readonly int _dSize;
|
||||
private int _bIndex;
|
||||
|
||||
// properties values are 0,1,3
|
||||
public Delta(byte[] properties, Stream inputStream)
|
||||
{
|
||||
_dSize = properties[0] + 1;
|
||||
_bVal = new byte[_dSize];
|
||||
|
||||
_baseStream = inputStream;
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (origin != SeekOrigin.Current)
|
||||
throw new NotImplementedException();
|
||||
|
||||
const int bufferSize = 10240;
|
||||
byte[] seekBuffer = new byte[bufferSize];
|
||||
long seekToGo = offset;
|
||||
while (seekToGo > 0)
|
||||
{
|
||||
long get = seekToGo > bufferSize ? bufferSize : seekToGo;
|
||||
Read(seekBuffer, 0, (int)get);
|
||||
seekToGo -= get;
|
||||
}
|
||||
return _position;
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int read = _baseStream.Read(buffer, offset, count);
|
||||
|
||||
for (int i = 0; i < read; i++)
|
||||
{
|
||||
buffer[i] = _bVal[_bIndex] = (byte)(buffer[i] + _bVal[_bIndex]);
|
||||
_bIndex = (_bIndex + 1) % _dSize;
|
||||
}
|
||||
|
||||
_position += read;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
public override long Length
|
||||
{
|
||||
get { return _baseStream.Length; }
|
||||
}
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return _position;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
171
SabreTools.Library/External/Compress/SevenZip/Filters/Filter.cs
vendored
Normal file
171
SabreTools.Library/External/Compress/SevenZip/Filters/Filter.cs
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Compress.SevenZip.Filters
|
||||
{
|
||||
public abstract class Filter : Stream
|
||||
{
|
||||
protected bool isEncoder;
|
||||
protected Stream baseStream;
|
||||
|
||||
private byte[] tail;
|
||||
private byte[] window;
|
||||
private int transformed = 0;
|
||||
private int read = 0;
|
||||
private bool endReached = false;
|
||||
private long position = 0;
|
||||
|
||||
protected Filter(bool isEncoder, Stream baseStream, int lookahead)
|
||||
{
|
||||
this.isEncoder = isEncoder;
|
||||
this.baseStream = baseStream;
|
||||
tail = new byte[lookahead - 1];
|
||||
window = new byte[tail.Length * 2];
|
||||
}
|
||||
|
||||
public Stream BaseStream
|
||||
{ get { return baseStream; } }
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return !isEncoder; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return isEncoder; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { return baseStream.Length; }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return position;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
if (transformed > 0)
|
||||
{
|
||||
int copySize = transformed;
|
||||
if (copySize > count)
|
||||
copySize = count;
|
||||
Buffer.BlockCopy(tail, 0, buffer, offset, copySize);
|
||||
transformed -= copySize;
|
||||
read -= copySize;
|
||||
offset += copySize;
|
||||
count -= copySize;
|
||||
size += copySize;
|
||||
Buffer.BlockCopy(tail, copySize, tail, 0, read);
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
position += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
int inSize = read;
|
||||
if (inSize > count)
|
||||
inSize = count;
|
||||
Buffer.BlockCopy(tail, 0, buffer, offset, inSize);
|
||||
read -= inSize;
|
||||
Buffer.BlockCopy(tail, inSize, tail, 0, read);
|
||||
while (!endReached && inSize < count)
|
||||
{
|
||||
int baseRead = baseStream.Read(buffer, offset + inSize, count - inSize);
|
||||
inSize += baseRead;
|
||||
if (baseRead == 0)
|
||||
endReached = true;
|
||||
}
|
||||
while (!endReached && read < tail.Length)
|
||||
{
|
||||
int baseRead = baseStream.Read(tail, read, tail.Length - read);
|
||||
read += baseRead;
|
||||
if (baseRead == 0)
|
||||
endReached = true;
|
||||
}
|
||||
|
||||
if (inSize > tail.Length)
|
||||
{
|
||||
transformed = Transform(buffer, offset, inSize);
|
||||
offset += transformed;
|
||||
count -= transformed;
|
||||
size += transformed;
|
||||
inSize -= transformed;
|
||||
transformed = 0;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
position += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(buffer, offset, window, 0, inSize);
|
||||
Buffer.BlockCopy(tail, 0, window, inSize, read);
|
||||
if (inSize + read > tail.Length)
|
||||
transformed = Transform(window, 0, inSize + read);
|
||||
else
|
||||
transformed = inSize + read;
|
||||
Buffer.BlockCopy(window, 0, buffer, offset, inSize);
|
||||
Buffer.BlockCopy(window, inSize, tail, 0, read);
|
||||
size += inSize;
|
||||
transformed -= inSize;
|
||||
|
||||
position += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (origin != SeekOrigin.Current)
|
||||
throw new NotImplementedException();
|
||||
|
||||
const int bufferSize = 10240;
|
||||
byte[] seekBuffer = new byte[bufferSize];
|
||||
long seekToGo = offset;
|
||||
while (seekToGo > 0)
|
||||
{
|
||||
long get = seekToGo > bufferSize ? bufferSize : seekToGo;
|
||||
Read(seekBuffer, 0, (int) get);
|
||||
seekToGo -= get;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Transform(buffer, offset, count);
|
||||
baseStream.Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
protected abstract int Transform(byte[] buffer, int offset, int count);
|
||||
}
|
||||
}
|
||||
1082
SabreTools.Library/External/Compress/SevenZip/SevenZip.cs
vendored
Normal file
1082
SabreTools.Library/External/Compress/SevenZip/SevenZip.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
30
SabreTools.Library/External/Compress/SevenZip/Structure/BindPair.cs
vendored
Normal file
30
SabreTools.Library/External/Compress/SevenZip/Structure/BindPair.cs
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public class BindPair
|
||||
{
|
||||
public ulong InIndex;
|
||||
public ulong OutIndex;
|
||||
|
||||
public void Read(BinaryReader br)
|
||||
{
|
||||
InIndex = br.ReadEncodedUInt64();
|
||||
OutIndex = br.ReadEncodedUInt64();
|
||||
}
|
||||
|
||||
public void Write(BinaryWriter bw)
|
||||
{
|
||||
bw.WriteEncodedUInt64(InIndex);
|
||||
bw.WriteEncodedUInt64(OutIndex);
|
||||
}
|
||||
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine(" InIndex = " + InIndex);
|
||||
sb.AppendLine(" OutIndex = " + OutIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
159
SabreTools.Library/External/Compress/SevenZip/Structure/Coder.cs
vendored
Normal file
159
SabreTools.Library/External/Compress/SevenZip/Structure/Coder.cs
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Compress.Utils;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public enum InStreamSource
|
||||
{
|
||||
Unknown,
|
||||
FileStream,
|
||||
CompStreamOutput
|
||||
}
|
||||
|
||||
|
||||
public class InStreamSourceInfo
|
||||
{
|
||||
public InStreamSource InStreamSource = InStreamSource.Unknown;
|
||||
public ulong InStreamIndex;
|
||||
}
|
||||
|
||||
public enum DecompressType
|
||||
{
|
||||
Unknown,
|
||||
Stored,
|
||||
Delta,
|
||||
LZMA,
|
||||
BCJ,
|
||||
BCJ2,
|
||||
PPMd,
|
||||
BZip2,
|
||||
LZMA2
|
||||
}
|
||||
|
||||
|
||||
public class Coder
|
||||
{
|
||||
public byte[] Method;
|
||||
public ulong NumInStreams;
|
||||
public ulong NumOutStreams;
|
||||
public byte[] Properties;
|
||||
|
||||
/************Local Variables***********/
|
||||
public DecompressType DecoderType;
|
||||
public bool OutputUsedInternally = false;
|
||||
public InStreamSourceInfo[] InputStreamsSourceInfo;
|
||||
public Stream DecoderStream;
|
||||
|
||||
public void Read(BinaryReader br)
|
||||
{
|
||||
byte flags = br.ReadByte();
|
||||
int decompressionMethodIdSize = flags & 0xf;
|
||||
Method = br.ReadBytes(decompressionMethodIdSize);
|
||||
if ((flags & 0x10) != 0)
|
||||
{
|
||||
NumInStreams = br.ReadEncodedUInt64();
|
||||
NumOutStreams = br.ReadEncodedUInt64();
|
||||
}
|
||||
else
|
||||
{
|
||||
NumInStreams = 1;
|
||||
NumOutStreams = 1;
|
||||
}
|
||||
|
||||
if ((flags & 0x20) != 0)
|
||||
{
|
||||
ulong propSize = br.ReadEncodedUInt64();
|
||||
Properties = br.ReadBytes((int)propSize);
|
||||
}
|
||||
|
||||
if ((flags & 0x80) != 0)
|
||||
{
|
||||
throw new NotSupportedException("External flag");
|
||||
}
|
||||
|
||||
if ((Method.Length == 1) && (Method[0] == 0))
|
||||
{
|
||||
DecoderType = DecompressType.Stored;
|
||||
}
|
||||
else if ((Method.Length == 1) && (Method[0] == 3))
|
||||
{
|
||||
DecoderType = DecompressType.Delta;
|
||||
}
|
||||
else if ((Method.Length == 3) && (Method[0] == 3) && (Method[1] == 1) && (Method[2] == 1))
|
||||
{
|
||||
DecoderType = DecompressType.LZMA;
|
||||
}
|
||||
else if ((Method.Length == 4) && (Method[0] == 3) && (Method[1] == 3) && (Method[2] == 1) &&
|
||||
(Method[3] == 3))
|
||||
{
|
||||
DecoderType = DecompressType.BCJ;
|
||||
}
|
||||
else if ((Method.Length == 4) && (Method[0] == 3) && (Method[1] == 3) && (Method[2] == 1) &&
|
||||
(Method[3] == 27))
|
||||
{
|
||||
DecoderType = DecompressType.BCJ2;
|
||||
}
|
||||
else if ((Method.Length == 3) && (Method[0] == 3) && (Method[1] == 4) && (Method[2] == 1))
|
||||
{
|
||||
DecoderType = DecompressType.PPMd;
|
||||
}
|
||||
else if ((Method.Length == 3) && (Method[0] == 4) && (Method[1] == 2) && (Method[2] == 2))
|
||||
{
|
||||
DecoderType = DecompressType.BZip2;
|
||||
}
|
||||
else if ((Method.Length == 1) && (Method[0] == 33))
|
||||
{
|
||||
DecoderType = DecompressType.LZMA2;
|
||||
}
|
||||
|
||||
InputStreamsSourceInfo = new InStreamSourceInfo[NumInStreams];
|
||||
for (uint i = 0; i < NumInStreams; i++)
|
||||
{
|
||||
InputStreamsSourceInfo[i] = new InStreamSourceInfo();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(BinaryWriter bw)
|
||||
{
|
||||
byte flags = (byte)Method.Length;
|
||||
if ((NumInStreams != 1) || (NumOutStreams != 1))
|
||||
{
|
||||
flags = (byte)(flags | 0x10);
|
||||
}
|
||||
|
||||
if ((Properties != null) && (Properties.Length > 0))
|
||||
{
|
||||
flags = (byte)(flags | 0x20);
|
||||
}
|
||||
|
||||
bw.Write(flags);
|
||||
|
||||
bw.Write(Method);
|
||||
|
||||
if ((NumInStreams != 1) || (NumOutStreams != 1))
|
||||
{
|
||||
bw.WriteEncodedUInt64(NumInStreams);
|
||||
bw.WriteEncodedUInt64(NumOutStreams);
|
||||
}
|
||||
|
||||
if ((Properties != null) && (Properties.Length > 0))
|
||||
{
|
||||
bw.WriteEncodedUInt64((ulong)Properties.Length);
|
||||
bw.Write(Properties);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine($" Method[] = {Method.ToArrayString()} : {DecoderType}");
|
||||
sb.AppendLine($" NumInStreams = {NumInStreams}");
|
||||
sb.AppendLine($" NumOutStreams = {NumOutStreams}");
|
||||
sb.AppendLine($" Properties[] = {Properties.ToArrayString()}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
140
SabreTools.Library/External/Compress/SevenZip/Structure/FileInfo.cs
vendored
Normal file
140
SabreTools.Library/External/Compress/SevenZip/Structure/FileInfo.cs
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public class FileInfo
|
||||
{
|
||||
public string[] Names;
|
||||
public bool[] EmptyStreamFlags;
|
||||
public bool[] EmptyFileFlags;
|
||||
public uint[] Attributes;
|
||||
|
||||
public void Read(BinaryReader br)
|
||||
{
|
||||
ulong size = br.ReadEncodedUInt64();
|
||||
Names = new string[size];
|
||||
|
||||
ulong numEmptyFiles = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HeaderProperty hp = (HeaderProperty) br.ReadByte();
|
||||
if (hp == HeaderProperty.kEnd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ulong bytessize = br.ReadEncodedUInt64();
|
||||
switch (hp)
|
||||
{
|
||||
case HeaderProperty.kName:
|
||||
if (br.ReadByte() != 0)
|
||||
{
|
||||
throw new Exception("Cannot be external");
|
||||
}
|
||||
|
||||
for (ulong i = 0; i < size; i++)
|
||||
{
|
||||
Names[i] = br.ReadName();
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kEmptyStream:
|
||||
EmptyStreamFlags = Util.ReadBoolFlags(br, (ulong) Names.Length);
|
||||
for (ulong i = 0; i < size; i++)
|
||||
{
|
||||
if (EmptyStreamFlags[i])
|
||||
{
|
||||
numEmptyFiles++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kEmptyFile:
|
||||
EmptyFileFlags = Util.ReadBoolFlags(br, numEmptyFiles);
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kWinAttributes:
|
||||
Attributes = Util.ReadUInt32Def(br, size);
|
||||
continue;
|
||||
|
||||
// don't know what this is.
|
||||
case HeaderProperty.kAnti:
|
||||
br.ReadBytes((int)bytessize);
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kCreationTime:
|
||||
case HeaderProperty.kLastAccessTime:
|
||||
case HeaderProperty.kLastWriteTime:
|
||||
br.ReadBytes((int) bytessize);
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kDummy:
|
||||
br.ReadBytes((int) bytessize);
|
||||
continue;
|
||||
|
||||
default:
|
||||
throw new Exception(hp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(BinaryWriter bw)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kFilesInfo);
|
||||
bw.WriteEncodedUInt64((ulong) Names.Length);
|
||||
|
||||
|
||||
byte[] namebyte;
|
||||
using (MemoryStream nameMem = new MemoryStream())
|
||||
{
|
||||
using (BinaryWriter nameBw = new BinaryWriter(nameMem,Encoding.UTF8,true))
|
||||
{
|
||||
nameBw.Write((byte) 0); //not external
|
||||
foreach (string name in Names)
|
||||
{
|
||||
nameBw.WriteName(name);
|
||||
}
|
||||
|
||||
namebyte = new byte[nameMem.Length];
|
||||
nameMem.Position = 0;
|
||||
nameMem.Read(namebyte, 0, namebyte.Length);
|
||||
}
|
||||
}
|
||||
|
||||
bw.Write((byte) HeaderProperty.kName);
|
||||
bw.WriteEncodedUInt64((ulong) namebyte.Length);
|
||||
bw.Write(namebyte);
|
||||
|
||||
if (EmptyStreamFlags != null)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kEmptyStream);
|
||||
Util.WriteBoolFlags(bw, EmptyStreamFlags);
|
||||
}
|
||||
|
||||
if (EmptyFileFlags != null)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kEmptyFile);
|
||||
Util.WriteBoolFlags(bw, EmptyFileFlags);
|
||||
}
|
||||
|
||||
if (Attributes != null)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kWinAttributes);
|
||||
Util.WriteUint32Def(bw, Attributes);
|
||||
}
|
||||
|
||||
bw.Write((byte) HeaderProperty.kEnd);
|
||||
}
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine(" FileInfo");
|
||||
sb.AppendLine(" ------");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
434
SabreTools.Library/External/Compress/SevenZip/Structure/Folder.cs
vendored
Normal file
434
SabreTools.Library/External/Compress/SevenZip/Structure/Folder.cs
vendored
Normal file
@@ -0,0 +1,434 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Compress.Utils;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public class Folder
|
||||
{
|
||||
public Coder[] Coders;
|
||||
public BindPair[] BindPairs;
|
||||
public ulong PackedStreamIndexBase;
|
||||
public ulong[] PackedStreamIndices;
|
||||
public ulong[] UnpackedStreamSizes;
|
||||
public uint? UnpackCRC;
|
||||
public UnpackedStreamInfo[] UnpackedStreamInfo;
|
||||
|
||||
|
||||
private void ReadFolder(BinaryReader br)
|
||||
{
|
||||
ulong numCoders = br.ReadEncodedUInt64();
|
||||
|
||||
Coders = new Coder[numCoders];
|
||||
|
||||
int numInStreams = 0;
|
||||
int numOutStreams = 0;
|
||||
|
||||
for (ulong i = 0; i < numCoders; i++)
|
||||
{
|
||||
Coders[i] = new Coder();
|
||||
Coders[i].Read(br);
|
||||
|
||||
numInStreams += (int) Coders[i].NumInStreams;
|
||||
numOutStreams += (int) Coders[i].NumOutStreams;
|
||||
}
|
||||
|
||||
int numBindPairs = numOutStreams - 1;
|
||||
BindPairs = new BindPair[numBindPairs];
|
||||
for (int i = 0; i < numBindPairs; i++)
|
||||
{
|
||||
BindPairs[i] = new BindPair();
|
||||
BindPairs[i].Read(br);
|
||||
}
|
||||
|
||||
if (numInStreams < numBindPairs)
|
||||
{
|
||||
throw new NotSupportedException("Error");
|
||||
}
|
||||
|
||||
int numPackedStreams = numInStreams - numBindPairs;
|
||||
|
||||
PackedStreamIndices = new ulong[numPackedStreams];
|
||||
|
||||
if (numPackedStreams == 1)
|
||||
{
|
||||
uint pi = 0;
|
||||
for (uint j = 0; j < numInStreams; j++)
|
||||
{
|
||||
for (uint k = 0; k < BindPairs.Length; k++)
|
||||
{
|
||||
if (BindPairs[k].InIndex == j)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PackedStreamIndices[pi++] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint i = 0; i < numPackedStreams; i++)
|
||||
{
|
||||
PackedStreamIndices[i] = br.ReadEncodedUInt64();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadUnpackedStreamSize(BinaryReader br)
|
||||
{
|
||||
ulong outStreams = 0;
|
||||
foreach (Coder c in Coders)
|
||||
{
|
||||
outStreams += c.NumOutStreams;
|
||||
}
|
||||
|
||||
UnpackedStreamSizes = new ulong[outStreams];
|
||||
for (uint j = 0; j < outStreams; j++)
|
||||
{
|
||||
UnpackedStreamSizes[j] = br.ReadEncodedUInt64();
|
||||
}
|
||||
}
|
||||
|
||||
private ulong GetUnpackSize()
|
||||
{
|
||||
ulong outStreams = 0;
|
||||
foreach (Coder coder in Coders)
|
||||
{
|
||||
outStreams += coder.NumInStreams;
|
||||
}
|
||||
|
||||
for (ulong j = 0; j < outStreams; j++)
|
||||
{
|
||||
bool found = false;
|
||||
foreach (BindPair bindPair in BindPairs)
|
||||
{
|
||||
if (bindPair.OutIndex != j)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
return UnpackedStreamSizes[j];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static void ReadUnPackInfo(BinaryReader br, out Folder[] Folders)
|
||||
{
|
||||
Folders = null;
|
||||
for (;;)
|
||||
{
|
||||
HeaderProperty hp = (HeaderProperty) br.ReadByte();
|
||||
switch (hp)
|
||||
{
|
||||
case HeaderProperty.kFolder:
|
||||
{
|
||||
ulong numFolders = br.ReadEncodedUInt64();
|
||||
|
||||
Folders = new Folder[numFolders];
|
||||
|
||||
byte external = br.ReadByte();
|
||||
switch (external)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ulong folderIndex = 0;
|
||||
for (uint i = 0; i < numFolders; i++)
|
||||
{
|
||||
Folders[i] = new Folder();
|
||||
Folders[i].ReadFolder(br);
|
||||
Folders[i].PackedStreamIndexBase = folderIndex;
|
||||
folderIndex += (ulong) Folders[i].PackedStreamIndices.Length;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
throw new NotSupportedException("External flag");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
case HeaderProperty.kCodersUnPackSize:
|
||||
{
|
||||
for (uint i = 0; i < Folders.Length; i++)
|
||||
{
|
||||
Folders[i].ReadUnpackedStreamSize(br);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
case HeaderProperty.kCRC:
|
||||
{
|
||||
uint?[] crcs;
|
||||
Util.UnPackCRCs(br, (ulong) Folders.Length, out crcs);
|
||||
for (int i = 0; i < Folders.Length; i++)
|
||||
{
|
||||
Folders[i].UnpackCRC = crcs[i];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
case HeaderProperty.kEnd:
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new Exception(hp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReadSubStreamsInfo(BinaryReader br, ref Folder[] Folders)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
HeaderProperty hp = (HeaderProperty) br.ReadByte();
|
||||
switch (hp)
|
||||
{
|
||||
case HeaderProperty.kNumUnPackStream:
|
||||
{
|
||||
for (int f = 0; f < Folders.Length; f++)
|
||||
{
|
||||
int numStreams = (int) br.ReadEncodedUInt64();
|
||||
Folders[f].UnpackedStreamInfo = new UnpackedStreamInfo[numStreams];
|
||||
for (int i = 0; i < numStreams; i++)
|
||||
{
|
||||
Folders[f].UnpackedStreamInfo[i] = new UnpackedStreamInfo();
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
case HeaderProperty.kSize:
|
||||
{
|
||||
for (int f = 0; f < Folders.Length; f++)
|
||||
{
|
||||
Folder folder = Folders[f];
|
||||
|
||||
if (folder.UnpackedStreamInfo.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ulong sum = 0;
|
||||
for (int i = 0; i < folder.UnpackedStreamInfo.Length - 1; i++)
|
||||
{
|
||||
ulong size = br.ReadEncodedUInt64();
|
||||
folder.UnpackedStreamInfo[i].UnpackedSize = size;
|
||||
sum += size;
|
||||
}
|
||||
|
||||
folder.UnpackedStreamInfo[folder.UnpackedStreamInfo.Length - 1].UnpackedSize =
|
||||
folder.GetUnpackSize() - sum;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
case HeaderProperty.kCRC:
|
||||
{
|
||||
ulong numCRC = 0;
|
||||
foreach (Folder folder in Folders)
|
||||
{
|
||||
if (folder.UnpackedStreamInfo == null)
|
||||
{
|
||||
folder.UnpackedStreamInfo = new UnpackedStreamInfo[1];
|
||||
folder.UnpackedStreamInfo[0] = new UnpackedStreamInfo();
|
||||
folder.UnpackedStreamInfo[0].UnpackedSize = folder.GetUnpackSize();
|
||||
}
|
||||
|
||||
if ((folder.UnpackedStreamInfo.Length != 1) || !folder.UnpackCRC.HasValue)
|
||||
{
|
||||
numCRC += (ulong) folder.UnpackedStreamInfo.Length;
|
||||
}
|
||||
}
|
||||
|
||||
int crcIndex = 0;
|
||||
uint?[] crc;
|
||||
Util.UnPackCRCs(br, numCRC, out crc);
|
||||
for (uint i = 0; i < Folders.Length; i++)
|
||||
{
|
||||
Folder folder = Folders[i];
|
||||
if ((folder.UnpackedStreamInfo.Length == 1) && folder.UnpackCRC.HasValue)
|
||||
{
|
||||
folder.UnpackedStreamInfo[0].Crc = folder.UnpackCRC;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint j = 0; j < folder.UnpackedStreamInfo.Length; j++, crcIndex++)
|
||||
{
|
||||
folder.UnpackedStreamInfo[j].Crc = crc[crcIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
case HeaderProperty.kEnd:
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new Exception(hp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteFolder(BinaryWriter bw)
|
||||
{
|
||||
ulong numCoders = (ulong) Coders.Length;
|
||||
bw.WriteEncodedUInt64(numCoders);
|
||||
for (ulong i = 0; i < numCoders; i++)
|
||||
{
|
||||
Coders[i].Write(bw);
|
||||
}
|
||||
|
||||
ulong numBindingPairs = BindPairs == null ? 0 : (ulong) BindPairs.Length;
|
||||
for (ulong i = 0; i < numBindingPairs; i++)
|
||||
{
|
||||
BindPairs[i].Write(bw);
|
||||
}
|
||||
|
||||
//need to look at PAckedStreamIndices but don't need them for basic writing I am doing
|
||||
}
|
||||
|
||||
private void WriteUnpackedStreamSize(BinaryWriter bw)
|
||||
{
|
||||
ulong numUnpackedStreamSizes = (ulong) UnpackedStreamSizes.Length;
|
||||
for (ulong i = 0; i < numUnpackedStreamSizes; i++)
|
||||
{
|
||||
bw.WriteEncodedUInt64(UnpackedStreamSizes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteUnPackInfo(BinaryWriter bw, Folder[] Folders)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kUnPackInfo);
|
||||
|
||||
bw.Write((byte) HeaderProperty.kFolder);
|
||||
ulong numFolders = (ulong) Folders.Length;
|
||||
bw.WriteEncodedUInt64(numFolders);
|
||||
bw.Write((byte) 0); //External Flag
|
||||
for (ulong i = 0; i < numFolders; i++)
|
||||
{
|
||||
Folders[i].WriteFolder(bw);
|
||||
}
|
||||
|
||||
|
||||
bw.Write((byte) HeaderProperty.kCodersUnPackSize);
|
||||
for (ulong i = 0; i < numFolders; i++)
|
||||
{
|
||||
Folders[i].WriteUnpackedStreamSize(bw);
|
||||
}
|
||||
|
||||
if (Folders[0].UnpackCRC != null)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kCRC);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bw.Write((byte) HeaderProperty.kEnd);
|
||||
}
|
||||
|
||||
public static void WriteSubStreamsInfo(BinaryWriter bw, Folder[] Folders)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kSubStreamsInfo);
|
||||
|
||||
bw.Write((byte) HeaderProperty.kNumUnPackStream);
|
||||
for (int f = 0; f < Folders.Length; f++)
|
||||
{
|
||||
ulong numStreams = (ulong) Folders[f].UnpackedStreamInfo.Length;
|
||||
bw.WriteEncodedUInt64(numStreams);
|
||||
}
|
||||
|
||||
bw.Write((byte) HeaderProperty.kSize);
|
||||
|
||||
for (int f = 0; f < Folders.Length; f++)
|
||||
{
|
||||
Folder folder = Folders[f];
|
||||
for (int i = 0; i < folder.UnpackedStreamInfo.Length - 1; i++)
|
||||
{
|
||||
bw.WriteEncodedUInt64(folder.UnpackedStreamInfo[i].UnpackedSize);
|
||||
}
|
||||
}
|
||||
|
||||
bw.Write((byte) HeaderProperty.kCRC);
|
||||
bw.Write((byte) 1); // crc flags default to true
|
||||
for (int f = 0; f < Folders.Length; f++)
|
||||
{
|
||||
Folder folder = Folders[f];
|
||||
for (int i = 0; i < folder.UnpackedStreamInfo.Length; i++)
|
||||
{
|
||||
bw.Write(Util.uinttobytes(folder.UnpackedStreamInfo[i].Crc));
|
||||
}
|
||||
}
|
||||
|
||||
bw.Write((byte) HeaderProperty.kEnd);
|
||||
}
|
||||
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
if (Coders == null)
|
||||
{
|
||||
sb.AppendLine(" Coders[] = null");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($" Coders[] = ({Coders.Length})");
|
||||
foreach (Coder c in Coders)
|
||||
{
|
||||
c.Report(ref sb);
|
||||
}
|
||||
}
|
||||
if (BindPairs == null)
|
||||
{
|
||||
sb.AppendLine(" BindPairs[] = null");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($" BindPairs[] = ({BindPairs.Length})");
|
||||
foreach (BindPair bp in BindPairs)
|
||||
{
|
||||
bp.Report(ref sb);
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine($" PackedStreamIndexBase = {PackedStreamIndexBase}");
|
||||
sb.AppendLine($" PackedStreamIndices[] = {PackedStreamIndices.ToArrayString()}");
|
||||
sb.AppendLine($" UnpackedStreamSizes[] = {UnpackedStreamSizes.ToArrayString()}");
|
||||
sb.AppendLine($" UnpackCRC = {UnpackCRC.ToHex()}");
|
||||
|
||||
if (UnpackedStreamInfo == null)
|
||||
{
|
||||
sb.AppendLine(" UnpackedStreamInfo[] = null");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($" UnpackedStreamInfo[{UnpackedStreamInfo.Length}]");
|
||||
foreach (UnpackedStreamInfo usi in UnpackedStreamInfo)
|
||||
{
|
||||
usi.Report(ref sb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
133
SabreTools.Library/External/Compress/SevenZip/Structure/Header.cs
vendored
Normal file
133
SabreTools.Library/External/Compress/SevenZip/Structure/Header.cs
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Compress.SevenZip.Compress.LZMA;
|
||||
using Compress.Utils;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public class Header
|
||||
{
|
||||
public StreamsInfo StreamsInfo;
|
||||
public FileInfo FileInfo;
|
||||
|
||||
public void Read(BinaryReader br)
|
||||
{
|
||||
for (; ; )
|
||||
{
|
||||
HeaderProperty hp = (HeaderProperty)br.ReadByte();
|
||||
switch (hp)
|
||||
{
|
||||
case HeaderProperty.kMainStreamsInfo:
|
||||
StreamsInfo = new StreamsInfo();
|
||||
StreamsInfo.Read(br);
|
||||
break;
|
||||
|
||||
case HeaderProperty.kFilesInfo:
|
||||
FileInfo = new FileInfo();
|
||||
FileInfo.Read(br);
|
||||
break;
|
||||
|
||||
case HeaderProperty.kEnd:
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new Exception(hp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Write(BinaryWriter bw)
|
||||
{
|
||||
bw.Write((byte)HeaderProperty.kHeader);
|
||||
StreamsInfo.Write(bw);
|
||||
FileInfo.Write(bw);
|
||||
bw.Write((byte)HeaderProperty.kEnd);
|
||||
}
|
||||
|
||||
public void WriteHeader(BinaryWriter bw)
|
||||
{
|
||||
Write(bw);
|
||||
}
|
||||
|
||||
public static ZipReturn ReadHeaderOrPackedHeader(Stream stream, long baseOffset, out Header header)
|
||||
{
|
||||
header = null;
|
||||
|
||||
using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true))
|
||||
{
|
||||
HeaderProperty hp = (HeaderProperty)br.ReadByte();
|
||||
switch (hp)
|
||||
{
|
||||
case HeaderProperty.kEncodedHeader:
|
||||
{
|
||||
StreamsInfo streamsInfo = new StreamsInfo();
|
||||
streamsInfo.Read(br);
|
||||
|
||||
if (streamsInfo.Folders.Length > 1)
|
||||
{
|
||||
return ZipReturn.ZipUnsupportedCompression;
|
||||
}
|
||||
|
||||
Folder firstFolder = streamsInfo.Folders[0];
|
||||
if (firstFolder.Coders.Length > 1)
|
||||
{
|
||||
return ZipReturn.ZipUnsupportedCompression;
|
||||
}
|
||||
|
||||
byte[] method = firstFolder.Coders[0].Method;
|
||||
if (!((method.Length == 3) && (method[0] == 3) && (method[1] == 1) && (method[2] == 1))) // LZMA
|
||||
{
|
||||
return ZipReturn.ZipUnsupportedCompression;
|
||||
}
|
||||
|
||||
stream.Seek(baseOffset + (long)streamsInfo.PackPosition, SeekOrigin.Begin);
|
||||
using (LzmaStream decoder = new LzmaStream(firstFolder.Coders[0].Properties, stream))
|
||||
{
|
||||
ZipReturn zr = ReadHeaderOrPackedHeader(decoder, baseOffset, out header);
|
||||
if (zr != ZipReturn.ZipGood)
|
||||
{
|
||||
return zr;
|
||||
}
|
||||
}
|
||||
|
||||
return ZipReturn.ZipGood;
|
||||
}
|
||||
|
||||
case HeaderProperty.kHeader:
|
||||
{
|
||||
header = new Header();
|
||||
header.Read(br);
|
||||
return ZipReturn.ZipGood;
|
||||
}
|
||||
}
|
||||
|
||||
return ZipReturn.ZipCentralDirError;
|
||||
}
|
||||
}
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine("Header");
|
||||
sb.AppendLine("------");
|
||||
if (StreamsInfo == null)
|
||||
{
|
||||
sb.AppendLine("StreamsInfo == null");
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamsInfo.Report(ref sb);
|
||||
}
|
||||
|
||||
if (FileInfo == null)
|
||||
{
|
||||
sb.AppendLine("FileInfo == null");
|
||||
}
|
||||
else
|
||||
{
|
||||
FileInfo.Report(ref sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
SabreTools.Library/External/Compress/SevenZip/Structure/PackedStreamInfo.cs
vendored
Normal file
98
SabreTools.Library/External/Compress/SevenZip/Structure/PackedStreamInfo.cs
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Compress.Utils;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public class PackedStreamInfo
|
||||
{
|
||||
public ulong PackedSize;
|
||||
public ulong? Crc;
|
||||
public ulong StreamPosition;
|
||||
public Stream PackedStream;
|
||||
|
||||
public static void Read(BinaryReader br, out ulong packPosition, out PackedStreamInfo[] packedStreams)
|
||||
{
|
||||
packPosition = br.ReadEncodedUInt64();
|
||||
|
||||
ulong numPackStreams = br.ReadEncodedUInt64();
|
||||
|
||||
packedStreams = new PackedStreamInfo[numPackStreams];
|
||||
for (ulong i = 0; i < numPackStreams; i++)
|
||||
{
|
||||
packedStreams[i] = new PackedStreamInfo();
|
||||
}
|
||||
|
||||
ulong streamPosition = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HeaderProperty hp = (HeaderProperty) br.ReadByte();
|
||||
switch (hp)
|
||||
{
|
||||
case HeaderProperty.kSize:
|
||||
for (ulong i = 0; i < numPackStreams; i++)
|
||||
{
|
||||
packedStreams[i].StreamPosition = streamPosition;
|
||||
packedStreams[i].PackedSize = br.ReadEncodedUInt64();
|
||||
streamPosition += packedStreams[i].PackedSize;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kCRC:
|
||||
for (ulong i = 0; i < numPackStreams; i++)
|
||||
{
|
||||
packedStreams[i].Crc = br.ReadEncodedUInt64();
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kEnd:
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new Exception(hp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write(BinaryWriter bw, ulong packPosition, PackedStreamInfo[] packedStreams)
|
||||
{
|
||||
ulong numPackStreams = (ulong) packedStreams.Length;
|
||||
bw.Write((byte) HeaderProperty.kPackInfo);
|
||||
bw.WriteEncodedUInt64(packPosition);
|
||||
bw.WriteEncodedUInt64(numPackStreams);
|
||||
|
||||
bw.Write((byte) HeaderProperty.kSize);
|
||||
ulong streamPosition = 0;
|
||||
for (ulong i = 0; i < numPackStreams; i++)
|
||||
{
|
||||
packedStreams[i].StreamPosition = streamPosition;
|
||||
bw.WriteEncodedUInt64(packedStreams[i].PackedSize);
|
||||
streamPosition += packedStreams[i].PackedSize;
|
||||
}
|
||||
|
||||
// Only checking the first CRC assuming all the reset will be the same
|
||||
if (packedStreams[0].Crc != null)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kCRC);
|
||||
for (ulong i = 0; i < numPackStreams; i++)
|
||||
{
|
||||
bw.WriteEncodedUInt64(packedStreams[i].Crc ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
bw.Write((byte) HeaderProperty.kEnd);
|
||||
}
|
||||
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine($" PackedSize = {PackedSize}");
|
||||
sb.AppendLine($" Crc = {Crc.ToHex()}");
|
||||
sb.AppendLine($" StreamPosition = {StreamPosition}");
|
||||
}
|
||||
}
|
||||
}
|
||||
110
SabreTools.Library/External/Compress/SevenZip/Structure/SignatureHeader.cs
vendored
Normal file
110
SabreTools.Library/External/Compress/SevenZip/Structure/SignatureHeader.cs
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
internal class SignatureHeader
|
||||
{
|
||||
private static readonly byte[] Signature = {(byte) '7', (byte) 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
|
||||
private byte _major;
|
||||
private byte _minor;
|
||||
|
||||
private uint _startHeaderCRC;
|
||||
|
||||
public ulong NextHeaderOffset;
|
||||
public ulong NextHeaderSize;
|
||||
public uint NextHeaderCRC;
|
||||
|
||||
|
||||
private long _crcOffset;
|
||||
public long BaseOffset { get; private set; }
|
||||
|
||||
public bool Read(Stream stream)
|
||||
{
|
||||
using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true))
|
||||
{
|
||||
byte[] signatureBytes = br.ReadBytes(6);
|
||||
if (!signatureBytes.Compare(Signature))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_major = br.ReadByte();
|
||||
_minor = br.ReadByte();
|
||||
|
||||
_startHeaderCRC = br.ReadUInt32();
|
||||
|
||||
long pos = br.BaseStream.Position;
|
||||
byte[] mainHeader = new byte[8 + 8 + 4];
|
||||
br.BaseStream.Read(mainHeader, 0, mainHeader.Length);
|
||||
if (!Utils.CRC.VerifyDigest(_startHeaderCRC, mainHeader, 0, (uint) mainHeader.Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
br.BaseStream.Seek(pos, SeekOrigin.Begin);
|
||||
|
||||
NextHeaderOffset = br.ReadUInt64();
|
||||
NextHeaderSize = br.ReadUInt64();
|
||||
NextHeaderCRC = br.ReadUInt32();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(BinaryWriter bw)
|
||||
{
|
||||
//SignatureHeader
|
||||
//~~~~~~~~~~~~~~~
|
||||
|
||||
bw.Write(Signature);
|
||||
|
||||
//ArchiveVersion
|
||||
//{
|
||||
bw.Write((byte) 0); // BYTE Major
|
||||
bw.Write((byte) 3); // BYTE Minor
|
||||
//};
|
||||
|
||||
_crcOffset = bw.BaseStream.Position;
|
||||
bw.Write((uint) 0); //HeaderCRC
|
||||
|
||||
//StartHeader
|
||||
//{
|
||||
bw.Write((ulong) 0); //NextHeaderOffset
|
||||
bw.Write((ulong) 0); //NextHeaderSize
|
||||
bw.Write((uint) 0); //NextHeaderCRC
|
||||
//}
|
||||
|
||||
BaseOffset = bw.BaseStream.Position;
|
||||
}
|
||||
|
||||
public void WriteFinal(BinaryWriter bw, ulong headerpos, ulong headerLength, uint headerCRC)
|
||||
{
|
||||
long fileEnd = bw.BaseStream.Position;
|
||||
|
||||
|
||||
byte[] sigHeaderBytes;
|
||||
using (MemoryStream sigHeaderMem = new MemoryStream())
|
||||
{
|
||||
using (BinaryWriter sigHeaderBw = new BinaryWriter(sigHeaderMem,Encoding.UTF8,true))
|
||||
{
|
||||
sigHeaderBw.Write((ulong) ((long) headerpos - BaseOffset)); //NextHeaderOffset
|
||||
sigHeaderBw.Write(headerLength); //NextHeaderSize
|
||||
sigHeaderBw.Write(headerCRC); //NextHeaderCRC
|
||||
|
||||
sigHeaderBytes = new byte[sigHeaderMem.Length];
|
||||
sigHeaderMem.Position = 0;
|
||||
sigHeaderMem.Read(sigHeaderBytes, 0, sigHeaderBytes.Length);
|
||||
}
|
||||
}
|
||||
|
||||
uint sigHeaderCRC = Utils.CRC.CalculateDigest(sigHeaderBytes, 0, (uint) sigHeaderBytes.Length);
|
||||
|
||||
bw.BaseStream.Position = _crcOffset;
|
||||
bw.Write(sigHeaderCRC); //Header CRC
|
||||
bw.Write(sigHeaderBytes);
|
||||
|
||||
bw.BaseStream.Seek(fileEnd, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
SabreTools.Library/External/Compress/SevenZip/Structure/StreamsInfo.cs
vendored
Normal file
84
SabreTools.Library/External/Compress/SevenZip/Structure/StreamsInfo.cs
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using Compress.Utils;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public class StreamsInfo
|
||||
{
|
||||
public ulong PackPosition;
|
||||
public PackedStreamInfo[] PackedStreams;
|
||||
public Folder[] Folders;
|
||||
|
||||
public void Read(BinaryReader br)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
HeaderProperty hp = (HeaderProperty) br.ReadByte();
|
||||
switch (hp)
|
||||
{
|
||||
case HeaderProperty.kPackInfo:
|
||||
PackedStreamInfo.Read(br, out PackPosition, out PackedStreams);
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kUnPackInfo:
|
||||
Folder.ReadUnPackInfo(br, out Folders);
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kSubStreamsInfo:
|
||||
Folder.ReadSubStreamsInfo(br, ref Folders);
|
||||
continue;
|
||||
|
||||
case HeaderProperty.kEnd:
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new Exception(hp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(BinaryWriter bw)
|
||||
{
|
||||
bw.Write((byte) HeaderProperty.kMainStreamsInfo);
|
||||
PackedStreamInfo.Write(bw, PackPosition, PackedStreams);
|
||||
Folder.WriteUnPackInfo(bw, Folders);
|
||||
Folder.WriteSubStreamsInfo(bw, Folders);
|
||||
bw.Write((byte) HeaderProperty.kEnd);
|
||||
}
|
||||
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine(" StreamsInfo");
|
||||
sb.AppendLine(" -----------");
|
||||
sb.AppendLine($" PackPosition = {PackPosition}");
|
||||
if (PackedStreams == null)
|
||||
{
|
||||
sb.AppendLine($" PackedStreams[] = null");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($" PackedStreams[] = ({PackedStreams.Length})");
|
||||
foreach (PackedStreamInfo psi in PackedStreams)
|
||||
{
|
||||
psi.Report(ref sb);
|
||||
}
|
||||
}
|
||||
if (Folders == null)
|
||||
{
|
||||
sb.AppendLine($" Folders[] = null");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($" Folders[] = ({Folders.Length})");
|
||||
foreach (Folder f in Folders)
|
||||
{
|
||||
f.Report(ref sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
SabreTools.Library/External/Compress/SevenZip/Structure/UnpackedStreamInfo.cs
vendored
Normal file
16
SabreTools.Library/External/Compress/SevenZip/Structure/UnpackedStreamInfo.cs
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Text;
|
||||
using Compress.Utils;
|
||||
|
||||
namespace Compress.SevenZip.Structure
|
||||
{
|
||||
public class UnpackedStreamInfo
|
||||
{
|
||||
public ulong UnpackedSize;
|
||||
public uint? Crc;
|
||||
|
||||
public void Report(ref StringBuilder sb)
|
||||
{
|
||||
sb.AppendLine($" Crc = {Crc.ToHex()} , Size = {UnpackedSize}");
|
||||
}
|
||||
}
|
||||
}
|
||||
351
SabreTools.Library/External/Compress/SevenZip/Util.cs
vendored
Normal file
351
SabreTools.Library/External/Compress/SevenZip/Util.cs
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Compress.SevenZip
|
||||
{
|
||||
public enum HeaderProperty
|
||||
{
|
||||
kEnd,
|
||||
kHeader,
|
||||
|
||||
kArchiveProperties,
|
||||
|
||||
kAdditionalStreamsInfo,
|
||||
kMainStreamsInfo,
|
||||
kFilesInfo,
|
||||
|
||||
kPackInfo,
|
||||
kUnPackInfo,
|
||||
kSubStreamsInfo,
|
||||
|
||||
kSize,
|
||||
kCRC,
|
||||
|
||||
kFolder,
|
||||
|
||||
kCodersUnPackSize,
|
||||
kNumUnPackStream,
|
||||
|
||||
kEmptyStream,
|
||||
kEmptyFile,
|
||||
kAnti,
|
||||
|
||||
kName,
|
||||
kCreationTime,
|
||||
kLastAccessTime,
|
||||
kLastWriteTime,
|
||||
kWinAttributes,
|
||||
kComment,
|
||||
|
||||
kEncodedHeader,
|
||||
|
||||
kStartPos,
|
||||
kDummy
|
||||
}
|
||||
|
||||
public static class Util
|
||||
{
|
||||
public static readonly Encoding Enc = Encoding.GetEncoding(28591);
|
||||
|
||||
public static void memset(byte[] buffer, int start, byte val, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
buffer[start + i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
public static void memcpyr(byte[] destBuffer, int destPoint, byte[] sourceBuffer, int sourcePoint, int len)
|
||||
{
|
||||
for (int i = len - 1; i >= 0; i--)
|
||||
{
|
||||
destBuffer[destPoint + i] = sourceBuffer[sourcePoint + i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool memcmp(byte[] buffer1, int offset, byte[] buffer2, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (buffer1[offset + i] != buffer2[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static bool Compare(this byte[] b1, byte[] b2)
|
||||
{
|
||||
if ((b1 == null) || (b2 == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (b1.Length != b2.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < b1.Length; i++)
|
||||
{
|
||||
if (b1[i] != b2[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static ulong ReadEncodedUInt64(this BinaryReader br)
|
||||
{
|
||||
byte mask = 0x80;
|
||||
int i;
|
||||
byte firstByte = br.ReadByte();
|
||||
ulong value = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if ((firstByte & mask) == 0)
|
||||
{
|
||||
ulong highPart = (ulong) (firstByte & (mask - 1));
|
||||
value += highPart << (8*i);
|
||||
return value;
|
||||
}
|
||||
byte b = br.ReadByte();
|
||||
value |= (ulong) b << (8*i);
|
||||
mask >>= 1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void WriteEncodedUInt64(this BinaryWriter bw, ulong value)
|
||||
{
|
||||
byte firstByte = 0;
|
||||
byte mask = 0x80;
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (value < (ulong) 1 << (7*(i + 1)))
|
||||
{
|
||||
firstByte |= (byte) (value >> (8*i));
|
||||
break;
|
||||
}
|
||||
firstByte |= mask;
|
||||
mask >>= 1;
|
||||
}
|
||||
bw.Write(firstByte);
|
||||
for (; i > 0; i--)
|
||||
{
|
||||
bw.Write((byte) value);
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadName(this BinaryReader br)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (;;)
|
||||
{
|
||||
char c = (char) br.ReadUInt16();
|
||||
if (c == 0)
|
||||
{
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteName(this BinaryWriter bw, string name)
|
||||
{
|
||||
char[] chars = name.ToCharArray();
|
||||
for (int i = 0; i < chars.Length; i++)
|
||||
{
|
||||
bw.Write((ushort) chars[i]);
|
||||
}
|
||||
bw.Write((ushort) 0);
|
||||
}
|
||||
|
||||
|
||||
public static void UnPackCRCs(BinaryReader br, ulong numItems, out uint?[] digests)
|
||||
{
|
||||
bool[] digestsDefined = ReadBoolFlagsDefaultTrue(br, numItems);
|
||||
digests = new uint?[numItems];
|
||||
for (ulong i = 0; i < numItems; i++)
|
||||
{
|
||||
if (digestsDefined[i])
|
||||
{
|
||||
digests[i] = br.ReadUInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool[] ReadBoolFlagsDefaultTrue(BinaryReader br, ulong numItems)
|
||||
{
|
||||
byte allAreDefined = br.ReadByte();
|
||||
if (allAreDefined == 0)
|
||||
{
|
||||
return ReadBoolFlags(br, numItems);
|
||||
}
|
||||
bool[] flags = new bool[numItems];
|
||||
for (ulong i = 0; i < numItems; i++)
|
||||
{
|
||||
flags[i] = true;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static bool[] ReadBoolFlags(BinaryReader br, ulong numItems)
|
||||
{
|
||||
byte b = 0;
|
||||
byte mask = 0;
|
||||
|
||||
bool[] flags = new bool[numItems];
|
||||
for (ulong i = 0; i < numItems; i++)
|
||||
{
|
||||
if (mask == 0)
|
||||
{
|
||||
b = br.ReadByte();
|
||||
mask = 0x80;
|
||||
}
|
||||
|
||||
flags[i] = (b & mask) != 0;
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static bool[] ReadBoolFlags2(BinaryReader br, ulong numItems)
|
||||
{
|
||||
byte allAreDefined = br.ReadByte();
|
||||
if (allAreDefined == 0)
|
||||
{
|
||||
return ReadBoolFlags(br, numItems);
|
||||
}
|
||||
|
||||
|
||||
bool[] flags = new bool[numItems];
|
||||
for (ulong i = 0; i < numItems; i++)
|
||||
{
|
||||
flags[i] = true;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static void WriteUint32Def(BinaryWriter br, uint[] values)
|
||||
{
|
||||
br.WriteEncodedUInt64((ulong) (values.Length*4 + 2));
|
||||
br.Write((byte) 1);
|
||||
br.Write((byte) 0);
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
br.Write(values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint[] ReadUInt32Def(BinaryReader br, ulong numItems)
|
||||
{
|
||||
uint[] v = new uint[numItems];
|
||||
bool[] defs = ReadBoolFlags2(br, numItems);
|
||||
byte tmp = br.ReadByte();
|
||||
for (ulong i = 0; i < numItems; i++)
|
||||
{
|
||||
v[i] = defs[i] ? br.ReadUInt32() : 0;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public static ulong[] ReadUInt64Def(BinaryReader br, ulong numItems)
|
||||
{
|
||||
ulong[] v = new ulong[numItems];
|
||||
bool[] defs = ReadBoolFlags2(br, numItems);
|
||||
byte tmp = br.ReadByte();
|
||||
for (ulong i = 0; i < numItems; i++)
|
||||
{
|
||||
v[i] = defs[i] ? br.ReadUInt64() : 0;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public static void WriteBoolFlags(BinaryWriter bw, bool[] bArray)
|
||||
{
|
||||
bw.WriteEncodedUInt64((ulong) ((bArray.Length + 7)/8));
|
||||
byte mask = 0x80;
|
||||
byte tmpOut = 0;
|
||||
for (int i = 0; i < bArray.Length; i++)
|
||||
{
|
||||
if (bArray[i])
|
||||
{
|
||||
tmpOut |= mask;
|
||||
}
|
||||
|
||||
mask >>= 1;
|
||||
if (mask != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bw.Write(tmpOut);
|
||||
mask = 0x80;
|
||||
tmpOut = 0;
|
||||
}
|
||||
if (mask != 0x80)
|
||||
{
|
||||
bw.Write(tmpOut);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] uinttobytes(uint? crc)
|
||||
{
|
||||
if (crc == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
uint c = (uint) crc;
|
||||
|
||||
byte[] b = new byte[4];
|
||||
b[0] = (byte) ((c >> 24) & 0xff);
|
||||
b[1] = (byte) ((c >> 16) & 0xff);
|
||||
b[2] = (byte) ((c >> 8) & 0xff);
|
||||
b[3] = (byte) ((c >> 0) & 0xff);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static uint? bytestouint(byte[] crc)
|
||||
{
|
||||
if (crc == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return (uint?) ((crc[0] << 24) | (crc[1] << 16) | (crc[2] << 8) | (crc[3] << 0));
|
||||
}
|
||||
|
||||
public static bool ByteArrCompare(byte[] b0, byte[] b1)
|
||||
{
|
||||
if ((b0 == null) || (b1 == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (b0.Length != b1.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < b0.Length; i++)
|
||||
{
|
||||
if (b0[i] != b1[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user