From 439f71ef5cfee417cf83132094c4425997116125 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 31 May 2022 16:34:40 -0700 Subject: [PATCH] Migrate to external libmspack --- .gitmodules | 3 + BurnOutSharp.sln | 6 + BurnOutSharp/BurnOutSharp.csproj | 10 +- .../External/libmspack/BaseDecompressState.cs | 36 - .../External/libmspack/BaseDecompressor.cs | 32 - BurnOutSharp/External/libmspack/BaseHeader.cs | 16 - .../External/libmspack/CAB/Cabinet.cs | 145 -- .../External/libmspack/CAB/Compressor.cs | 24 - .../External/libmspack/CAB/DecompressState.cs | 95 -- .../External/libmspack/CAB/Decompressor.cs | 1500 ----------------- BurnOutSharp/External/libmspack/CAB/Enums.cs | 112 -- BurnOutSharp/External/libmspack/CAB/Folder.cs | 60 - .../External/libmspack/CAB/FolderData.cs | 29 - .../External/libmspack/CAB/InternalFile.cs | 54 - .../External/libmspack/CAB/_CabinetHeader.cs | 204 --- .../libmspack/CAB/_DataBlockHeader.cs | 66 - .../External/libmspack/CAB/_FileHeader.cs | 122 -- .../External/libmspack/CAB/_FolderHeader.cs | 72 - BurnOutSharp/External/libmspack/CHM/CHM.cs | 85 - .../External/libmspack/CHM/CompressFile.cs | 53 - .../External/libmspack/CHM/Compressor.cs | 149 -- .../External/libmspack/CHM/DecompressFile.cs | 52 - .../External/libmspack/CHM/DecompressState.cs | 36 - .../External/libmspack/CHM/Decompressor.cs | 1470 ---------------- BurnOutSharp/External/libmspack/CHM/Enums.cs | 83 - .../libmspack/CHM/MSCompressedSection.cs | 47 - .../External/libmspack/CHM/Section.cs | 41 - .../libmspack/CHM/UncompressedSection.cs | 31 - .../External/libmspack/CHM/_CHMHeader.cs | 118 -- .../External/libmspack/CHM/_HeaderSection0.cs | 85 - .../External/libmspack/CHM/_HeaderSection1.cs | 184 -- .../libmspack/CHM/_HeaderSectionTable.cs | 104 -- .../External/libmspack/CHM/_LZXControlData.cs | 155 -- .../External/libmspack/CHM/_LZXResetTable.cs | 94 -- .../External/libmspack/CHM/_PMGHeader.cs | 118 -- BurnOutSharp/External/libmspack/Checksum.cs | 111 -- .../Compression/CompressionStream.ReadBits.cs | 294 ---- .../Compression/CompressionStream.ReadHuff.cs | 342 ---- .../Compression/CompressionStream.cs | 56 - .../libmspack/Compression/Constants.cs | 281 --- .../External/libmspack/Compression/DES.cs | 15 - .../External/libmspack/Compression/Enums.cs | 39 - .../Compression/LZHKWAJ.Decompress.cs | 293 ---- .../libmspack/Compression/LZHKWAJ.ReadBits.cs | 64 - .../libmspack/Compression/LZHKWAJ.ReadHuff.cs | 17 - .../External/libmspack/Compression/LZHKWAJ.cs | 37 - .../External/libmspack/Compression/LZSS.cs | 177 -- .../libmspack/Compression/LZX.Decompress.cs | 847 ---------- .../libmspack/Compression/LZX.ReadBits.cs | 34 - .../libmspack/Compression/LZX.ReadHuff.cs | 132 -- .../External/libmspack/Compression/LZX.cs | 133 -- .../libmspack/Compression/MSZIP.Decompress.cs | 613 ------- .../libmspack/Compression/MSZIP.ReadBits.cs | 27 - .../libmspack/Compression/MSZIP.ReadHuff.cs | 20 - .../External/libmspack/Compression/MSZIP.cs | 47 - .../libmspack/Compression/None.Decompress.cs | 46 - .../External/libmspack/Compression/None.cs | 21 - .../libmspack/Compression/QTM.Decompress.cs | 542 ------ .../libmspack/Compression/QTM.ReadBits.cs | 34 - .../libmspack/Compression/QTM.ReadHuff.cs | 22 - .../External/libmspack/Compression/QTM.cs | 123 -- .../libmspack/Compression/QTMDModel.cs | 23 - .../libmspack/Compression/QTMDModelSym.cs | 21 - BurnOutSharp/External/libmspack/Constants.cs | 158 -- BurnOutSharp/External/libmspack/Enums.cs | 293 ---- .../External/libmspack/HLP/Compressor.cs | 24 - .../External/libmspack/HLP/Decompressor.cs | 23 - .../External/libmspack/KWAJ/Compressor.cs | 119 -- .../External/libmspack/KWAJ/Decompressor.cs | 352 ---- BurnOutSharp/External/libmspack/KWAJ/Enums.cs | 88 - .../External/libmspack/KWAJ/Header.cs | 68 - .../External/libmspack/KWAJ/_KWAJHeader.cs | 85 - .../External/libmspack/LIT/Compressor.cs | 24 - .../External/libmspack/LIT/Decompressor.cs | 23 - BurnOutSharp/External/libmspack/Library.cs | 499 ------ .../External/libmspack/OAB/Compressor.cs | 78 - .../External/libmspack/OAB/Decompressor.cs | 502 ------ BurnOutSharp/External/libmspack/OAB/Enums.cs | 19 - .../External/libmspack/OAB/InternalFile.cs | 31 - .../External/libmspack/SZDD/Compressor.cs | 118 -- .../External/libmspack/SZDD/Decompressor.cs | 226 --- BurnOutSharp/External/libmspack/SZDD/Enums.cs | 32 - .../External/libmspack/SZDD/Header.cs | 49 - BurnOutSharp/External/libmspack/SystemImpl.cs | 274 --- LibMSPackSharp | 1 + 85 files changed, 11 insertions(+), 12977 deletions(-) delete mode 100644 BurnOutSharp/External/libmspack/BaseDecompressState.cs delete mode 100644 BurnOutSharp/External/libmspack/BaseDecompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/BaseHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/Cabinet.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/Compressor.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/DecompressState.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/Decompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/Enums.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/Folder.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/FolderData.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/InternalFile.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/_CabinetHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/_DataBlockHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/_FileHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/CAB/_FolderHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/CHM.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/CompressFile.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/Compressor.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/DecompressFile.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/DecompressState.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/Decompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/Enums.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/MSCompressedSection.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/Section.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/UncompressedSection.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/_CHMHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/_HeaderSection0.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/_HeaderSection1.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/_HeaderSectionTable.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/_LZXControlData.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/_LZXResetTable.cs delete mode 100644 BurnOutSharp/External/libmspack/CHM/_PMGHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/Checksum.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadBits.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadHuff.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/CompressionStream.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/Constants.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/DES.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/Enums.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZHKWAJ.Decompress.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadBits.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadHuff.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZSS.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZX.Decompress.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZX.ReadBits.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZX.ReadHuff.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/LZX.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/MSZIP.Decompress.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/MSZIP.ReadBits.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/MSZIP.ReadHuff.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/MSZIP.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/None.Decompress.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/None.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/QTM.Decompress.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/QTM.ReadBits.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/QTM.ReadHuff.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/QTM.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/QTMDModel.cs delete mode 100644 BurnOutSharp/External/libmspack/Compression/QTMDModelSym.cs delete mode 100644 BurnOutSharp/External/libmspack/Constants.cs delete mode 100644 BurnOutSharp/External/libmspack/Enums.cs delete mode 100644 BurnOutSharp/External/libmspack/HLP/Compressor.cs delete mode 100644 BurnOutSharp/External/libmspack/HLP/Decompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/KWAJ/Compressor.cs delete mode 100644 BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/KWAJ/Enums.cs delete mode 100644 BurnOutSharp/External/libmspack/KWAJ/Header.cs delete mode 100644 BurnOutSharp/External/libmspack/KWAJ/_KWAJHeader.cs delete mode 100644 BurnOutSharp/External/libmspack/LIT/Compressor.cs delete mode 100644 BurnOutSharp/External/libmspack/LIT/Decompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/Library.cs delete mode 100644 BurnOutSharp/External/libmspack/OAB/Compressor.cs delete mode 100644 BurnOutSharp/External/libmspack/OAB/Decompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/OAB/Enums.cs delete mode 100644 BurnOutSharp/External/libmspack/OAB/InternalFile.cs delete mode 100644 BurnOutSharp/External/libmspack/SZDD/Compressor.cs delete mode 100644 BurnOutSharp/External/libmspack/SZDD/Decompressor.cs delete mode 100644 BurnOutSharp/External/libmspack/SZDD/Enums.cs delete mode 100644 BurnOutSharp/External/libmspack/SZDD/Header.cs delete mode 100644 BurnOutSharp/External/libmspack/SystemImpl.cs create mode 160000 LibMSPackSharp diff --git a/.gitmodules b/.gitmodules index 6661a5b6..88d56198 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "HLLibSharp"] path = HLLibSharp url = https://github.com/mnadareski/HLLibSharp +[submodule "LibMSPackSharp"] + path = LibMSPackSharp + url = https://github.com/mnadareski/LibMSPackSharp.git diff --git a/BurnOutSharp.sln b/BurnOutSharp.sln index ad744faa..bec94b07 100644 --- a/BurnOutSharp.sln +++ b/BurnOutSharp.sln @@ -22,6 +22,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Dtf.Compression. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HLLibSharp", "HLLibSharp\HLLibSharp\HLLibSharp.csproj", "{14E9764A-A8BF-44C0-A1A8-2C95EA307040}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibMSPackSharp", "LibMSPackSharp\LibMSPackSharp\LibMSPackSharp.csproj", "{BD8144B8-4857-47E6-9717-E9F2DB374A89}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -52,6 +54,10 @@ Global {14E9764A-A8BF-44C0-A1A8-2C95EA307040}.Debug|Any CPU.Build.0 = Debug|Any CPU {14E9764A-A8BF-44C0-A1A8-2C95EA307040}.Release|Any CPU.ActiveCfg = Release|Any CPU {14E9764A-A8BF-44C0-A1A8-2C95EA307040}.Release|Any CPU.Build.0 = Release|Any CPU + {BD8144B8-4857-47E6-9717-E9F2DB374A89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD8144B8-4857-47E6-9717-E9F2DB374A89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD8144B8-4857-47E6-9717-E9F2DB374A89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD8144B8-4857-47E6-9717-E9F2DB374A89}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/BurnOutSharp/BurnOutSharp.csproj b/BurnOutSharp/BurnOutSharp.csproj index c98dcd1f..7dbd59c7 100644 --- a/BurnOutSharp/BurnOutSharp.csproj +++ b/BurnOutSharp/BurnOutSharp.csproj @@ -37,9 +37,6 @@ $(DefaultItemExcludes); **\AssemblyInfo.cs; - External\hllib\HLExtract\**\*; - External\hllib\HLExtract.Net\Program.cs; - External\hllib\HLLib\**\*; External\stormlibsharp\lib\**; External\stormlibsharp\TestConsole\** @@ -59,15 +56,10 @@ - - + all - - - - diff --git a/BurnOutSharp/External/libmspack/BaseDecompressState.cs b/BurnOutSharp/External/libmspack/BaseDecompressState.cs deleted file mode 100644 index 2cfc4c5e..00000000 --- a/BurnOutSharp/External/libmspack/BaseDecompressState.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System.IO; - -namespace LibMSPackSharp -{ - public abstract class BaseDecompressState - { - /// - /// System wrapper for I/O operations - /// - public SystemImpl System { get; set; } - - /// - /// Persistent error state of the state - /// - public Error Error { get; set; } - - /// - /// Input file handle - /// - public FileStream InputFileHandle { get; set; } - - /// - /// Output file handle - /// - public FileStream OutputFileHandle { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/BaseDecompressor.cs b/BurnOutSharp/External/libmspack/BaseDecompressor.cs deleted file mode 100644 index 42c7f477..00000000 --- a/BurnOutSharp/External/libmspack/BaseDecompressor.cs +++ /dev/null @@ -1,32 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp -{ - /// - /// Set of common fields shared by all decompressors - /// - public abstract class BaseDecompressor - { - /// - /// System wrapper for I/O operations - /// - public SystemImpl System { get; set; } - - /// - /// Persistent error state of the decompressor - /// - public Error Error { get; set; } - - /// - /// Size of the internal buffer - /// - public int BufferSize { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/BaseHeader.cs b/BurnOutSharp/External/libmspack/BaseHeader.cs deleted file mode 100644 index 458d7540..00000000 --- a/BurnOutSharp/External/libmspack/BaseHeader.cs +++ /dev/null @@ -1,16 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp -{ - /// - /// Base class for decompressor-used objects - /// - public abstract class BaseHeader { } -} diff --git a/BurnOutSharp/External/libmspack/CAB/Cabinet.cs b/BurnOutSharp/External/libmspack/CAB/Cabinet.cs deleted file mode 100644 index d7c6a57a..00000000 --- a/BurnOutSharp/External/libmspack/CAB/Cabinet.cs +++ /dev/null @@ -1,145 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -/* Cabinet (.CAB) files are a form of file archive. Each cabinet contains - * "folders", which are compressed spans of data. Each cabinet has - * "files", whose metadata is in the cabinet header, but whose actual data - * is stored compressed in one of the "folders". Cabinets can span more - * than one physical file on disk, in which case they are a "cabinet set", - * and usually the last folder of each cabinet extends into the next - * cabinet. - * - * For a complete description of the format, see the MSDN site: - * http://msdn.microsoft.com/en-us/library/bb267310.aspx - */ - -/* Notes on compliance with cabinet specification: - * - * One of the main changes between cabextract 0.6 and libmspack's cab - * decompressor is the move from block-oriented decompression to - * stream-oriented decompression. - * - * cabextract would read one data block from disk, decompress it with the - * appropriate method, then write the decompressed data. The CAB - * specification is specifically designed to work like this, as it ensures - * compression matches do not span the maximum decompressed block size - * limit of 32kb. - * - * However, the compression algorithms used are stream oriented, with - * specific hacks added to them to enforce the "individual 32kb blocks" - * rule in CABs. In other file formats, they do not have this limitation. - * - * In order to make more generalised decompressors, libmspack's CAB - * decompressor has moved from being block-oriented to more stream - * oriented. This also makes decompression slightly faster. - * - * However, this leads to incompliance with the CAB specification. The - * CAB controller can no longer ensure each block of input given to the - * decompressors is matched with their output. The "decompressed size" of - * each individual block is thrown away. - * - * Each CAB block is supposed to be seen as individually compressed. This - * means each consecutive data block can have completely different - * "uncompressed" sizes, ranging from 1 to 32768 bytes. However, in - * reality, all data blocks in a folder decompress to exactly 32768 bytes, - * excepting the final block. - * - * Given this situation, the decompression algorithms are designed to - * realign their input bitstreams on 32768 output-byte boundaries, and - * various other special cases have been made. libmspack will not - * correctly decompress LZX or Quantum compressed folders where the blocks - * do not follow this "32768 bytes until last block" pattern. It could be - * implemented if needed, but hopefully this is not necessary -- it has - * not been seen in over 3Gb of CAB archives. - */ - -namespace LibMSPackSharp.CAB -{ - /// - /// A structure which represents a single cabinet file. - /// - /// All fields are READ ONLY. - /// - /// If this cabinet is part of a merged cabinet set, the #files and #folders - /// fields are common to all cabinets in the set, and will be identical. - /// - /// - /// - /// - public class Cabinet : BaseHeader - { - #region Internal - - /// - /// Cabinet header information - /// - internal _CabinetHeader Header { get; set; } - - #endregion - - /// - /// The next cabinet in a chained list, if this cabinet was opened with - /// mscab_decompressor::search(). May be NULL to mark the end of the - /// list. - /// - public Cabinet Next { get; set; } - - /// - /// The filename of the cabinet. More correctly, the filename of the - /// physical file that the cabinet resides in. This is given by the - /// library user and may be in any format. - /// - public string Filename { get; set; } - - /// - /// The file offset of cabinet within the physical file it resides in. - /// - public long BaseOffset { get; set; } - - /// - /// The previous cabinet in a cabinet set, or NULL. - /// - public Cabinet PreviousCabinet { get; set; } - - /// - /// The next cabinet in a cabinet set, or NULL. - /// - public Cabinet NextCabinet { get; set; } - - /// - /// The filename of the previous cabinet in a cabinet set, or NULL. - /// - public string PreviousName { get; set; } - - /// - /// The filename of the next cabinet in a cabinet set, or NULL. - /// - public string NextName { get; set; } - - /// - /// The name of the disk containing the previous cabinet in a cabinet, or NULL. - /// - public string PreviousInfo { get; set; } - - /// - /// The name of the disk containing the next cabinet in a cabinet set, or NULL. - /// - public string NextInfo { get; set; } - - /// - /// A list of all files in the cabinet or cabinet set. - /// - public InternalFile Files { get; set; } - - /// - /// A list of all folders in the cabinet or cabinet set. - /// - public Folder Folders { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/Compressor.cs b/BurnOutSharp/External/libmspack/CAB/Compressor.cs deleted file mode 100644 index b1e069e2..00000000 --- a/BurnOutSharp/External/libmspack/CAB/Compressor.cs +++ /dev/null @@ -1,24 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CAB -{ - // TODO - public class Compressor - { - public SystemImpl System { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/DecompressState.cs b/BurnOutSharp/External/libmspack/CAB/DecompressState.cs deleted file mode 100644 index 984aa47b..00000000 --- a/BurnOutSharp/External/libmspack/CAB/DecompressState.cs +++ /dev/null @@ -1,95 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using LibMSPackSharp.Compression; - -namespace LibMSPackSharp.CAB -{ - public class DecompressState : BaseDecompressState - { - /// - /// Current folder we're extracting from - /// - public Folder Folder { get; set; } - - /// - /// Current folder split we're in - /// - public FolderData Data { get; set; } - - /// - /// Uncompressed offset within folder - /// - public uint Offset { get; set; } - - /// - /// Which block are we decompressing? - /// - public uint Block { get; set; } - - /// - /// Cumulative sum of block output sizes - /// - public long Outlen { get; set; } - - /// - /// Type of compression used by folder - /// - public CompressionType CompressionType { get; set; } - - /// - /// Decompressor state - /// - public BaseDecompressState DecompressorState { get; set; } - - /// - /// Cabinet where input data comes from - /// - public Cabinet InputCabinet { get; set; } - - /// - /// Input data consumed - /// - public int InputPointer { get; set; } - - /// - /// Input data end - /// - public int InputEnd { get; set; } - - /// - /// One input block of data - /// - public byte[] Input { get; set; } = new byte[Constants.CAB_INPUTBUF]; - - /// - /// Decompressor code - /// - public Error Decompress(object o, long bytes) - { - switch (CompressionType & CompressionType.COMPTYPE_MASK) - { - case CompressionType.COMPTYPE_NONE: - return (o as None)?.Decompress(bytes) ?? Error.MSPACK_ERR_ARGS; - - case CompressionType.COMPTYPE_MSZIP: - return (o as MSZIP)?.Decompress(bytes) ?? Error.MSPACK_ERR_ARGS; - - case CompressionType.COMPTYPE_QUANTUM: - return (o as QTM)?.Decompress(bytes) ?? Error.MSPACK_ERR_ARGS; - - case CompressionType.COMPTYPE_LZX: - return (o as LZX)?.Decompress(bytes) ?? Error.MSPACK_ERR_ARGS; - - default: - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/Decompressor.cs b/BurnOutSharp/External/libmspack/CAB/Decompressor.cs deleted file mode 100644 index 4af2daf2..00000000 --- a/BurnOutSharp/External/libmspack/CAB/Decompressor.cs +++ /dev/null @@ -1,1500 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; -using System.IO; -using System.Text; -using LibMSPackSharp.Compression; -using static LibMSPackSharp.Constants; - -namespace LibMSPackSharp.CAB -{ - /// - /// A decompressor for .CAB (Microsoft Cabinet) files - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Decompressor : BaseDecompressor - { - #region Fields - - public DecompressState State { get; set; } - - public int SearchBufferSize { get; set; } - - public bool FixMSZip { get; set; } - - public bool Salvage { get; set; } - - public Error ReadError { get; set; } - - #endregion - - #region Public Functionality - - /// - /// Opens a cabinet file and reads its contents. - /// - /// If the file opened is a valid cabinet file, all headers will be read - /// and a Cabinet structure will be returned, with a full list of - /// folders and files. - /// - /// In the case of an error occuring, null is returned and the error code - /// is available from last_error(). - /// - /// The filename pointer should be considered "in use" until close() is - /// called on the cabinet. - /// - /// The filename of the cabinet file. This is passed directly to SystemImpl::open(). - /// A pointer to a Cabinet structure, or null on failure - /// - /// - /// - public Cabinet Open(string filename) - { - FileStream fileHandle = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (fileHandle == null) - { - Error = Error.MSPACK_ERR_OPEN; - return null; - } - - Cabinet cab = new Cabinet() { Filename = filename }; - Error error = ReadHeaders(fileHandle, cab, 0, Salvage, false); - if (error != Error.MSPACK_ERR_OK) - { - Close(cab); - cab = null; - } - - Error = error; - System.Close(fileHandle); - return cab; - } - - /// - /// Closes a previously opened cabinet or cabinet set. - /// - /// This closes a cabinet, all cabinets associated with it via the - /// Cabinet::next, Cabinet::prevcab and - /// Cabinet::nextcab pointers, and all folders and files. All - /// memory used by these entities is freed. - /// - /// The cabinet pointer is now invalid and cannot be used again. All - /// Folder and InternalFile pointers from that cabinet or cabinet - /// set are also now invalid, and cannot be used again. - /// - /// If the cabinet pointer given was created using search(), it MUST be - /// the cabinet pointer returned by search() and not one of the later - /// cabinet pointers further along the Cabinet::next chain. - /// - /// If extra cabinets have been added using append() or prepend(), these - /// will all be freed, even if the cabinet pointer given is not the first - /// cabinet in the set. Do NOT close() more than one cabinet in the set. - /// - /// The Cabinet::filename is not freed by the library, as it is - /// not allocated by the library. The caller should free this itself if - /// necessary, before it is lost forever. - /// - /// The cabinet to close - /// - /// - /// - /// - public void Close(Cabinet cabinet) - { - Error = Error.MSPACK_ERR_OK; - while (cabinet != null) - { - // Free folders - for (Folder fol = cabinet.Folders; fol != null; fol = fol.Next) - { - // Free folder decompression state if it has been decompressed - if (State != null && (State.Folder == fol)) - { - System.Close(State.InputFileHandle); - System.Close(State.OutputFileHandle); - - FreeDecompressionState(); - State = null; - } - } - - // Repeat full procedure again with the cab.Next pointer (if set) - cabinet = cabinet.Next; - } - } - - /// - /// Searches a regular file for embedded cabinets. - /// - /// This opens a normal file with the given filename and will search the - /// entire file for embedded cabinet files - /// - /// If any cabinets are found, the equivalent of open() is called on each - /// potential cabinet file at the offset it was found. All successfully - /// open()ed cabinets are kept in a list. - /// - /// The first cabinet found will be returned directly as the result of - /// this method. Any further cabinets found will be chained in a list - /// using the Cabinet::next field. - /// - /// In the case of an error occuring anywhere other than the simulated - /// open(), null is returned and the error code is available from - /// last_error(). - /// - /// If no error occurs, but no cabinets can be found in the file, null is - /// returned and last_error() returns MSPACK_ERR_OK. - /// - /// The filename pointer should be considered in use until close() is - /// called on the cabinet. - /// - /// close() should only be called on the result of search(), not on any - /// subsequent cabinets in the Cabinet::next chain. - /// - /// The filename of the file to search for cabinets. This is passed directly to SystemImpl.Open(). - /// A pointer to a Cabinet structure, or null - /// - /// - /// - public Cabinet Search(string filename) - { - // Allocate a search buffer - byte[] searchBuffer = new byte[SearchBufferSize]; - - // Attempt to open the file - FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (fh == null) - { - Error = Error.MSPACK_ERR_OPEN; - return null; - } - - // Get its full file length - long firstlen = 0; - if ((Error = System.GetFileLength(fh, out long filelen)) != Error.MSPACK_ERR_OK) - return null; - - // Attempt to to find the cabinet - Error = Find(searchBuffer, fh, filename, filelen, ref firstlen, out Cabinet cab); - - // Truncated / extraneous data warning: - if (firstlen != 0 && (firstlen != filelen) && (cab == null || cab.BaseOffset == 0)) - { - if (firstlen < filelen) - System.Message(fh, $"WARNING; possible {filelen - firstlen} extra bytes at end of file."); - else - System.Message(fh, $"WARNING; file possibly truncated by {firstlen - filelen} bytes."); - } - - System.Close(fh); - return cab; - } - - /// - /// Appends one Cabinet to another, forming or extending a cabinet - /// set. - /// - /// This will attempt to append one cabinet to another such that - /// (cab->nextcab == nextcab) && (nextcab->prevcab == cab) and - /// any folders split between the two cabinets are merged. - /// - /// The cabinets MUST be part of a cabinet set -- a cabinet set is a - /// cabinet that spans more than one physical cabinet file on disk -- and - /// must be appropriately matched. - /// - /// It can be determined if a cabinet has further parts to load by - /// examining the Cabinet::flags field: - /// - /// - if (flags & MSCAB_HDR_PREVCAB) is non-zero, there is a - /// predecessor cabinet to open() and prepend(). Its MS-DOS - /// case-insensitive filename is Cabinet::prevname - /// - if (flags & MSCAB_HDR_NEXTCAB) is non-zero, there is a - /// successor cabinet to open() and append(). Its MS-DOS case-insensitive - /// filename is Cabinet::nextname - /// - /// If the cabinets do not match, an error code will be returned. Neither - /// cabinet has been altered, and both should be closed seperately. - /// - /// Files and folders in a cabinet set are a single entity. All cabinets - /// in a set use the same file list, which is updated as cabinets in the - /// set are added. All pointers to Folder and InternalFile - /// structures in either cabinet must be discarded and re-obtained after - /// merging. - /// - /// The cabinet which will be appended to, predecessor of nextcab - /// The cabinet which will be appended, successor of cab - /// an error code, or MSPACK_ERR_OK if successful - /// - /// - /// - public Error Append(Cabinet cab, Cabinet nextcab) => Merge(cab, nextcab); - - /// - /// Prepends one Cabinet to another, forming or extending a - /// cabinet set. - /// - /// This will attempt to prepend one cabinet to another, such that - /// (cab->prevcab == prevcab) && (prevcab->nextcab == cab). In - /// all other respects, it is identical to append(). See append() for the - /// full documentation. - /// - /// The cabinet which will be prepended to, successor of prevcab - /// The cabinet which will be prepended, predecessor of cab - /// an error code, or MSPACK_ERR_OK if successful - /// - /// - /// - public Error Prepend(Cabinet cab, Cabinet prevcab) => Merge(prevcab, cab); - - /// - /// - /// Extracts a file from a cabinet or cabinet set. - /// - /// This extracts a compressed file in a cabinet and writes it to the given - /// filename. - /// - /// The MS-DOS filename of the file, InternalFile::filename, is NOT USED - /// by extract(). The caller must examine this MS-DOS filename, copy and - /// change it as necessary, create directories as necessary, and provide - /// the correct filename as a parameter, which will be passed unchanged - /// to the decompressor's SystemImpl::open() - /// - /// If the file belongs to a split folder in a multi-part cabinet set, - /// and not enough parts of the cabinet set have been loaded and appended - /// or prepended, an error will be returned immediately. - /// - /// the file to be decompressed - /// the filename of the file being written to - /// an error code, or MSPACK_ERR_OK if successful - public Error Extract(InternalFile file, string filename) - { - if (file == null) - return Error = Error.MSPACK_ERR_ARGS; - - // If offset is beyond 2GB, nothing can be extracted - if (file.Header.FolderOffset > CAB_LENGTHMAX) - return Error = Error.MSPACK_ERR_DATAFORMAT; - - // If file claims to go beyond 2GB either error out, - // or in salvage mode reduce file length so it fits 2GB limit - long filelen = file.Header.UncompressedSize; - if (filelen > CAB_LENGTHMAX || (file.Header.FolderOffset + filelen) > CAB_LENGTHMAX) - { - if (Salvage) - filelen = CAB_LENGTHMAX - file.Header.FolderOffset; - else - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - // Extraction impossible if no folder, or folder needs predecessor - if (file.Folder == null || file.Folder.MergePrev != null) - { - System.Message(null, $"ERROR; file \"{file.Filename}\" cannot be extracted, cabinet set is incomplete"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - // If file goes beyond what can be decoded, given an error. - // In salvage mode, don't assume block sizes, just try decoding - if (!Salvage) - { - long maxlen = file.Folder.Header.NumBlocks * CAB_BLOCKMAX; - if ((file.Header.FolderOffset + filelen) > maxlen) - { - System.Message(null, $"ERROR; file \"{file.Filename}\" cannot be extracted, cabinet set is incomplete"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - } - - // Close existing output file handle in case of error - System.Close(State?.OutputFileHandle); - - // Allocate generic decompression state - if (State == null) - { - State = new DecompressState() - { - Folder = null, - Data = null, - System = System, - DecompressorState = null, - InputFileHandle = null, - InputCabinet = null, - }; - - State.System.Read = SysRead; - State.System.Write = SysWrite; - } - - // Do we need to change folder or reset the current folder? - if (State.Folder != file.Folder || State.Offset > file.Header.FolderOffset || State.DecompressorState == null) - { - // Do we need to open a new cab file? - if (State.InputFileHandle == null || file.Folder.Data.Cab != State.InputCabinet) - { - // Close previous file handle if from a different cab - System.Close(State?.InputFileHandle); - - State.InputCabinet = file.Folder.Data.Cab; - State.InputFileHandle = System.Open(file.Folder.Data.Cab.Filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (State.InputFileHandle == null) - return Error = Error.MSPACK_ERR_OPEN; - } - - // Seek to start of data blocks - if (!System.Seek(State.InputFileHandle, file.Folder.Data.Offset, SeekMode.MSPACK_SYS_SEEK_START)) - return Error = Error.MSPACK_ERR_SEEK; - - // Set up decompressor - if (InitDecompressionState(file.Folder.Header.CompType) != Error.MSPACK_ERR_OK) - return Error; - - // Initialize new folder state - State.Folder = file.Folder; - State.Data = file.Folder.Data; - State.Offset = 0; - State.Block = 0; - State.Outlen = 0; - State.InputPointer = 0; // State.Input[0] - State.InputEnd = 0; // State.Input[0] - - // ReadError lasts for the lifetime of a decompressor - ReadError = Error.MSPACK_ERR_OK; - } - - Error = Error.MSPACK_ERR_OK; - - // If file has more than 0 bytes - if (filelen > 0) - { - // Set the output file handle to null - State.OutputFileHandle = null; - UpdateDecompressionState(); - - // Get to correct offset. - // - Use null fh to say 'no writing' to cabd_sys_write() - // - If SysRead() has an error, it will set self.ReadError - // and pass back MSPACK_ERR_READ - long bytes = file.Header.FolderOffset - State.Offset; - if (bytes > 0) - { - Error error = State.Decompress(State.DecompressorState, bytes); - Error = (error == Error.MSPACK_ERR_READ) ? ReadError : error; - } - - // Open the output file handle - State.OutputFileHandle = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE); - if (State.OutputFileHandle == null) - return Error = Error.MSPACK_ERR_OPEN; - - // If getting to the correct offset was error free, unpack file - if (Error == Error.MSPACK_ERR_OK) - { - UpdateDecompressionState(); - Error error = State.Decompress(State.DecompressorState, filelen); - Error = (error == Error.MSPACK_ERR_READ) ? ReadError : error; - } - } - - // Close output file - System.Close(State.OutputFileHandle); - State.OutputFileHandle = null; - - return Error; - } - - /// - /// Sets a CAB decompression engine parameter. - /// - /// The following parameters are defined: - /// - #MSCABD_PARAM_SEARCHBUF: How many bytes should be allocated as a - /// buffer when using search()? The minimum value is 4. The default - /// value is 32768. - /// - #MSCABD_PARAM_FIXMSZIP: If non-zero, extract() will ignore bad - /// checksums and recover from decompression errors in MS-ZIP - /// compressed folders. The default value is 0 (don't recover). - /// - #MSCABD_PARAM_DECOMPBUF: How many bytes should be used as an input - /// bit buffer by decompressors? The minimum value is 4. The default - /// value is 4096. - /// - /// the parameter to set - /// the value to set the parameter to - /// - /// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there - /// is a problem with either parameter or value. - /// - /// - /// - public Error SetParam(Parameters param, int value) - { - switch (param) - { - case Parameters.MSCABD_PARAM_SEARCHBUF: - if (value < 4) - return Error.MSPACK_ERR_ARGS; - - SearchBufferSize = value; - break; - - case Parameters.MSCABD_PARAM_FIXMSZIP: - FixMSZip = value != 0; - break; - - case Parameters.MSCABD_PARAM_DECOMPBUF: - if (value < 4) - return Error.MSPACK_ERR_ARGS; - - BufferSize = value; - break; - - case Parameters.MSCABD_PARAM_SALVAGE: - Salvage = value != 0; - break; - - default: - return Error.MSPACK_ERR_ARGS; - } - - return Error.MSPACK_ERR_OK; - } - - #endregion - - #region Decompression State - - /// - /// Initialises decompression state, according to which - /// decompression method was used. relies on self.State.Folder being the same - /// as when initialised. - /// - internal Error InitDecompressionState(CompressionType ct) - { - State.CompressionType = ct; - switch (ct & CompressionType.COMPTYPE_MASK) - { - case CompressionType.COMPTYPE_NONE: - State.DecompressorState = None.Init(State.System, State.InputFileHandle, State.OutputFileHandle, BufferSize); - break; - - case CompressionType.COMPTYPE_MSZIP: - State.DecompressorState = MSZIP.Init(State.System, State.InputFileHandle, State.OutputFileHandle, BufferSize, FixMSZip); - break; - - case CompressionType.COMPTYPE_QUANTUM: - State.DecompressorState = QTM.Init(State.System, State.InputFileHandle, State.OutputFileHandle, ((ushort)ct >> 8) & 0x1f, BufferSize); - break; - - case CompressionType.COMPTYPE_LZX: - State.DecompressorState = LZX.Init(State.System, State.InputFileHandle, State.OutputFileHandle, ((ushort)ct >> 8) & 0x1f, 0, BufferSize, 0, false); - break; - - default: - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - return Error = (State.DecompressorState != null) ? Error.MSPACK_ERR_OK : Error.MSPACK_ERR_NOMEMORY; - } - - /// - /// Updates the decompression state with a new output - /// - internal Error UpdateDecompressionState() - { - switch (State.CompressionType & CompressionType.COMPTYPE_MASK) - { - case CompressionType.COMPTYPE_NONE: - case CompressionType.COMPTYPE_MSZIP: - case CompressionType.COMPTYPE_QUANTUM: - case CompressionType.COMPTYPE_LZX: - State.DecompressorState.OutputFileHandle = State.OutputFileHandle; - break; - - default: - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - return Error = (State.DecompressorState != null) ? Error.MSPACK_ERR_OK : Error.MSPACK_ERR_NOMEMORY; - } - - /// - /// Frees decompression state, according to which method was used. - /// - /// - internal void FreeDecompressionState() - { - if (State?.DecompressorState == null) - return; - - State.DecompressorState = null; - } - - #endregion - - #region I/O Methods - - /// - /// The internal reader function which the decompressors - /// use. will read data blocks (and merge split blocks) from the cabinet - /// and serve the read bytes to the decompressors - /// - internal int SysRead(object file, byte[] buffer, int pointer, int bytes) - { - int avail, todo, outlen = 0; - - bool ignore_cksum = Salvage || - (FixMSZip && - ((State.CompressionType & CompressionType.COMPTYPE_MASK) == CompressionType.COMPTYPE_MSZIP)); - bool ignore_blocksize = Salvage; - - todo = bytes; - while (todo > 0) - { - avail = State.InputEnd - State.InputPointer; - - // If out of input data, read a new block - if (avail > 0) - { - // Copy as many input bytes available as possible - if (avail > todo) - avail = todo; - - Array.Copy(State.Input, State.InputPointer, buffer, pointer, avail); - State.InputPointer += avail; - pointer += avail; - todo -= avail; - } - else - { - // Out of data, read a new block - - // Check if we're out of input blocks, advance block counter - if (State.Block++ >= State.Folder.Header.NumBlocks) - { - if (!Salvage) - ReadError = Error.MSPACK_ERR_DATAFORMAT; - else - Console.WriteLine("Ran out of CAB input blocks prematurely"); - - break; - } - - // Read a block - ReadError = SysReadBlock(ref outlen, ignore_cksum, ignore_blocksize); - if (ReadError != Error.MSPACK_ERR_OK) - return -1; - - State.Outlen += outlen; - - // Special Quantum hack -- trailer byte to allow the decompressor - // to realign itself. CAB Quantum blocks, unlike LZX blocks, can have - // anything from 0 to 4 trailing null bytes. - if ((State.CompressionType & CompressionType.COMPTYPE_MASK) == CompressionType.COMPTYPE_QUANTUM) - State.Input[State.InputEnd++] = 0xFF; - - // Is this the last block? - if (State.Block >= State.Folder.Header.NumBlocks) - { - if ((State.CompressionType & CompressionType.COMPTYPE_MASK) == CompressionType.COMPTYPE_LZX) - { - // Special LZX hack -- on the last block, inform LZX of the - // size of the output data stream. - (State.DecompressorState as LZX).SetOutputLength(State.Outlen); - } - } - } - } - - return bytes - todo; - } - - /// - /// The internal writer function which the decompressors - /// use. it either writes data to disk (self.State.OutputFileHandle) with the real - /// sys.write() function, or does nothing with the data when - /// self.State.OutputFileHandle == null. advances self.State.Offset - /// - internal int SysWrite(object file, byte[] buffer, int pointer, int bytes) - { - State.Offset += (uint)bytes; - if (State.OutputFileHandle != null) - return SystemImpl.DefaultSystem.Write(State.OutputFileHandle, buffer, pointer, bytes); - - return bytes; - } - - /// - /// Reads a whole data block from a cab file. The block may span more than - /// one cab file, if it does then the fragments will be reassembled - /// - private Error SysReadBlock(ref int output, bool ignore_cksum, bool ignore_blocksize) - { - byte[] hdr = new byte[_DataBlockHeader.Size]; - int full_len; - - // Reset the input block pointer and end of block pointer - State.InputPointer = State.InputEnd = 0; - - do - { - // Read the block header - if (SystemImpl.DefaultSystem.Read(State.InputFileHandle, hdr, 0, _DataBlockHeader.Size) != _DataBlockHeader.Size) - return Error.MSPACK_ERR_READ; - - // Skip any reserved block headers - if (State.Data.Cab.Header.DataReserved != 0 && !System.Seek(State.InputFileHandle, State.Data.Cab.Header.DataReserved, SeekMode.MSPACK_SYS_SEEK_CUR)) - return Error.MSPACK_ERR_SEEK; - - // Create a block header from the data - Error err = _DataBlockHeader.Create(hdr, out _DataBlockHeader dataBlockHeader); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Blocks must not be over CAB_INPUTMAX in size - full_len = (State.InputEnd - State.InputPointer) + dataBlockHeader.CompressedSize; // Include cab-spanning blocks - if (full_len > CAB_INPUTMAX) - { - Console.WriteLine($"Block size ({full_len}) > {CAB_INPUTMAX}"); - - // In salvage mode, blocks can be 65535 bytes but no more than that - if (!ignore_blocksize || full_len > CAB_INPUTMAX_SALVAGE) - return Error.MSPACK_ERR_DATAFORMAT; - } - - // Blocks must not expand to more than CAB_BLOCKMAX - if (dataBlockHeader.UncompressedSize > CAB_BLOCKMAX) - { - Console.WriteLine($"Block size ({dataBlockHeader.UncompressedSize}) > {CAB_BLOCKMAX}"); - if (!ignore_blocksize) - return Error.MSPACK_ERR_DATAFORMAT; - } - - // Read the block data - if (SystemImpl.DefaultSystem.Read(State.InputFileHandle, State.Input, State.InputEnd, dataBlockHeader.CompressedSize) != dataBlockHeader.CompressedSize) - return Error.MSPACK_ERR_READ; - - // Perform checksum test on the block (if one is stored) - if (dataBlockHeader.CheckSum > 0) - { - uint sum2 = Checksum(State.Input, State.InputEnd, dataBlockHeader.CompressedSize, 0); - if (Checksum(hdr, 4, 4, sum2) != dataBlockHeader.CheckSum) - { - if (!ignore_cksum) - return Error.MSPACK_ERR_CHECKSUM; - - System.Message(State.InputFileHandle, "WARNING; bad block checksum found"); - } - } - - // Advance end of block pointer to include newly read data - State.InputEnd += dataBlockHeader.CompressedSize; - - // Uncompressed size == 0 means this block was part of a split block - // and it continues as the first block of the next cabinet in the set. - // Otherwise, this is the last part of the block, and no more block - // reading needs to be done. - - // EXIT POINT OF LOOP -- uncompressed size > 0 - if ((output = dataBlockHeader.UncompressedSize) > 0) - return Error.MSPACK_ERR_OK; - - // Otherwise, advance to next cabinet - - // Close current file handle - System.Close(State.InputFileHandle); - State.InputFileHandle = null; - - // Advance to next member in the cabinet set - if ((State.Data = State.Data.Next) == null) - { - System.Message(State.InputFileHandle, "WARNING; ran out of cabinets in set. Are any missing?"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - // Open next cab file - State.InputCabinet = State.Data.Cab; - if ((State.InputFileHandle = System.Open(State.InputCabinet.Filename, OpenMode.MSPACK_SYS_OPEN_READ)) == null) - return Error.MSPACK_ERR_OPEN; - - // Seek to start of data blocks - if (!System.Seek(State.InputFileHandle, State.Data.Offset, SeekMode.MSPACK_SYS_SEEK_START)) - return Error.MSPACK_ERR_SEEK; - } while (true); - } - - private static uint Checksum(byte[] data, int pointer, uint bytes, uint cksum) - { - uint len, ul = 0; - - for (len = bytes >> 2; len-- != 0; pointer += 4) - { - cksum ^= (uint)((data[pointer + 0]) | (data[pointer + 1] << 8) | (data[pointer + 2] << 16) | (data[pointer + 3] << 24)); - } - - switch (bytes & 3) - { - case 3: - ul |= (uint)(data[pointer++] << 16); - ul |= (uint)(data[pointer++] << 8); - ul |= data[pointer]; - break; - - case 2: - ul |= (uint)(data[pointer++] << 8); - ul |= data[pointer]; - break; - - case 1: - ul |= data[pointer]; - break; - } - - cksum ^= ul; - return cksum; - } - - #endregion - - #region Helpers - - /// - /// Decides if two folders are OK to merge - /// - private bool CanMergeFolders(Folder lfol, Folder rfol) - { - bool matching = true; - - // Check that both folders use the same compression method/settings - if (lfol.Header.CompType != rfol.Header.CompType) - { - Console.WriteLine("Folder merge: compression type mismatch"); - return false; - } - - // Check there are not too many data blocks after merging - if ((lfol.Header.NumBlocks + rfol.Header.NumBlocks) > CAB_FOLDERMAX) - { - Console.WriteLine("Folder merge: too many data blocks in merged folders"); - return false; - } - - // Assign the merge next and previous values - InternalFile lfi = lfol.MergeNext; - InternalFile rfi = rfol.MergePrev; - - // Check that we can merge the two cabinets - if (lfi == null || rfi == null) - { - Console.WriteLine("Folder merge: one cabinet has no files to merge"); - return false; - } - - // For all files in lfol (which is the last folder in whichever cab and - // only has files to merge), compare them to the files from rfol. They - // should be identical in number and order. to verify this, check the - // offset and length of each file. - for (InternalFile l = lfi, r = rfi; l != null; l = l.Next, r = r.Next) - { - if (r == null || (l.Header.FolderOffset != r.Header.FolderOffset) || (l.Header.UncompressedSize != r.Header.UncompressedSize)) - { - matching = false; - break; - } - } - - if (matching) - return true; - - // If rfol does not begin with an identical copy of the files in lfol, make - // make a judgement call; if at least ONE file from lfol is in rfol, allow - // the merge with a warning about missing files. - matching = false; - for (InternalFile l = lfi; l != null; l = l.Next) - { - InternalFile r = rfi; - for (; r != null; r = r.Next) - { - if (l.Header.FolderOffset == r.Header.FolderOffset && l.Header.UncompressedSize == r.Header.UncompressedSize) - break; - } - - if (r != null) - matching = true; - else - System.Message(null, $"WARNING; merged file {l.Filename} not listed in both cabinets"); - } - - return matching; - } - - /// - /// The inner loop of , to make it easier to - /// break out of the loop and be sure that all resources are freed - /// - private Error Find(byte[] buf, FileStream fh, string filename, long flen, ref long firstlen, out Cabinet firstcab) - { - firstcab = null; - Cabinet cab, link = null; - long caboff, offset, length; - long p, pend; - byte state = 0; - uint cablen_u32 = 0, foffset_u32 = 0; - int false_cabs = 0; - - // Search through the full file length - for (offset = 0; offset < flen; offset += length) - { - // Search length is either the full length of the search buffer, or the - // amount of data remaining to the end of the file, whichever is less. - length = flen - offset; - if (length > SearchBufferSize) - length = SearchBufferSize; - - // Fill the search buffer with data from disk - if (System.Read(fh, buf, 0, (int)length) != (int)length) - return Error.MSPACK_ERR_READ; - - // FAQ avoidance strategy - if (offset == 0 && BitConverter.ToUInt32(buf, 0) == 0x28635349) - System.Message(fh, "WARNING; found InstallShield header. Use unshield (https://github.com/twogood/unshield) to unpack this file"); - - // Read through the entire buffer. - for (p = 0, pend = length; p < pend;) - { - switch (state) - { - // Starting state - case 0: - // We spend most of our time in this while loop, looking for - // a leading 'M' of the 'MSCF' signature - while (p < pend && buf[p] != 0x4D) - { - p++; - } - - // If we found that 'M', advance state - if (p++ < pend) - state = 1; - - break; - - // Verify that the next 3 bytes are 'S', 'C' and 'F' - case 1: - state = (byte)(buf[p++] == 0x53 ? 2 : 0); - break; - case 2: - state = (byte)(buf[p++] == 0x43 ? 3 : 0); - break; - case 3: - state = (byte)(buf[p++] == 0x46 ? 4 : 0); - break; - - // We don't care about bytes 4-7 (see default: for action) - - // Bytes 8-11 are the overall length of the cabinet - case 8: - cablen_u32 = buf[p++]; - state++; - break; - case 9: - cablen_u32 |= (uint)buf[p++] << 8; - state++; - break; - case 10: - cablen_u32 |= (uint)buf[p++] << 16; - state++; - break; - case 11: - cablen_u32 |= (uint)buf[p++] << 24; - state++; - break; - - // We don't care about bytes 12-15 (see default: for action) - - // Bytes 16-19 are the offset within the cabinet of the filedata */ - case 16: - foffset_u32 = buf[p++]; - state++; - break; - case 17: - foffset_u32 |= (uint)buf[p++] << 8; - state++; - break; - case 18: - foffset_u32 |= (uint)buf[p++] << 16; - state++; - break; - case 19: - foffset_u32 |= (uint)buf[p++] << 24; - - // Now we have recieved 20 bytes of potential cab header. work out - // the offset in the file of this potential cabinet - caboff = offset + p - 20; - - // Should reading cabinet fail, restart search just after 'MSCF' - offset = caboff + 4; - - // Vapture the "length of cabinet" field if there is a cabinet at - // offset 0 in the file, regardless of whether the cabinet can be - // read correctly or not - if (caboff == 0) - firstlen = cablen_u32; - - // Check that the files offset is less than the alleged length of - // the cabinet, and that the offset + the alleged length are - // 'roughly' within the end of overall file length. In salvage - // mode, don't check the alleged length, allow it to be garbage */ - if ((foffset_u32 < cablen_u32) && - ((caboff + foffset_u32) < (flen + 32)) && - (((caboff + cablen_u32) < (flen + 32)) || Salvage)) - { - // Likely cabinet found -- try reading it - cab = new Cabinet() { Filename = filename }; - - if (ReadHeaders(fh, cab, caboff, Salvage, quiet: true) != Error.MSPACK_ERR_OK) - { - // Destroy the failed cabinet - Close(cab); - false_cabs++; - } - else - { - // Cabinet read correctly! - - // Link the cab into the list - if (link == null) - firstcab = cab; - else - link.Next = cab; - - link = cab; - - // Cause the search to restart after this cab's data. - offset = caboff + cablen_u32; - } - } - - // Restart search - if (offset >= flen) - return Error.MSPACK_ERR_OK; - - if (!System.Seek(fh, offset, SeekMode.MSPACK_SYS_SEEK_START)) - return Error.MSPACK_ERR_SEEK; - - length = 0; - p = pend; - state = 0; - break; - - // For bytes 4-7 and 12-15, just advance state/pointer - default: - p++; - state++; - break; - } - } - } - - if (false_cabs > 0) - Console.WriteLine($"{false_cabs} false cabinets found"); - - return Error.MSPACK_ERR_OK; - } - - /// - /// Joins cabinets together, also merges split folders between these two - /// cabinets only. This includes freeing the duplicate folder and file(s) - /// and allocating a further mscabd_folder_data structure to append to the - /// merged folder's data parts list. - /// - private Error Merge(Cabinet lcab, Cabinet rcab) - { - InternalFile rfi, lfi; - - // Basic args check - if (lcab == null || rcab == null || (lcab == rcab)) - { - Console.WriteLine("lcab null, rcab null or lcab = rcab"); - return Error = Error.MSPACK_ERR_ARGS; - } - - // Check there's not already a cabinet attached - if (lcab.NextCabinet != null || rcab.PreviousCabinet != null) - { - Console.WriteLine("Cabs already joined"); - return Error = Error.MSPACK_ERR_ARGS; - } - - // Do not create circular cabinet chains - for (Cabinet cab = lcab.PreviousCabinet; cab != null; cab = cab.PreviousCabinet) - { - if (cab == rcab) - { - Console.WriteLine("circular!"); - return Error = Error.MSPACK_ERR_ARGS; - } - } - - for (Cabinet cab = rcab.NextCabinet; cab != null; cab = cab.NextCabinet) - { - if (cab == lcab) - { - Console.WriteLine("circular!"); - return Error = Error.MSPACK_ERR_ARGS; - } - } - - // Warn about odd set IDs or indices - if (lcab.Header.SetID != rcab.Header.SetID) - System.Message(null, "WARNING; merged cabinets with differing Set IDs."); - - if (lcab.Header.CabinetIndex > rcab.Header.CabinetIndex) - System.Message(null, "WARNING; merged cabinets with odd order."); - - // Merging the last folder in lcab with the first folder in rcab - Folder lfol = lcab.Folders; - Folder rfol = rcab.Folders; - while (lfol.Next != null) - { - lfol = lfol.Next; - } - - // Do we need to merge folders? - if (lfol.MergeNext == null && rfol.MergePrev == null) - { - // No, at least one of the folders is not for merging - - // Attach cabs - lcab.NextCabinet = rcab; - rcab.PreviousCabinet = lcab; - - // Attach folders - lfol.Next = rfol; - - // Attach files - InternalFile fi = lcab.Files; - while (fi.Next != null) - { - fi = fi.Next; - } - - fi.Next = rcab.Files; - } - else - { - // Folder merge required - do the files match? - if (!CanMergeFolders(lfol, rfol)) - return Error = Error.MSPACK_ERR_DATAFORMAT; - - // Allocate a new folder data structure - FolderData data = new FolderData(); - - // Attach cabs - lcab.NextCabinet = rcab; - rcab.PreviousCabinet = lcab; - - // Append rfol's data to lfol - FolderData ndata = lfol.Data; - while (ndata.Next != null) - { - ndata = ndata.Next; - } - - ndata.Next = data; - data = rfol.Data; - rfol.Data.Next = null; - - // lfol becomes rfol. - // NOTE: special case, don't merge if rfol is merge prev and next, - // rfol.MergeNext is going to be deleted, so keep lfol's version - // instead - lfol.Header.NumBlocks += (ushort)(rfol.Header.NumBlocks - 1); - if ((rfol.MergeNext == null) || (rfol.MergeNext.Folder != rfol)) - lfol.MergeNext = rfol.MergeNext; - - // Attach the rfol's folder (except the merge folder) - while (lfol.Next != null) - { - lfol = lfol.Next; - } - - lfol.Next = rfol.Next; - - // Attach rfol's files - InternalFile fi = lcab.Files; - while (fi.Next != null) - { - fi = fi.Next; - } - - fi.Next = rcab.Files; - - // Delete all files from rfol's merge folder - lfi = null; - for (fi = lcab.Files; fi != null; fi = rfi) - { - rfi = fi.Next; - - // If file's folder matches the merge folder, unlink and free it - if (fi.Folder == rfol) - { - if (lfi != null) - lfi.Next = rfi; - else - lcab.Files = rfi; - } - else - { - lfi = fi; - } - } - } - - // All done! fix files and folders pointers in alsl cabs so they all - // point to the same list - for (Cabinet cab = lcab.PreviousCabinet; cab != null; cab = cab.PreviousCabinet) - { - cab.Files = lcab.Files; - cab.Folders = lcab.Folders; - } - - for (Cabinet cab = lcab.NextCabinet; cab != null; cab = cab.NextCabinet) - { - cab.Files = lcab.Files; - cab.Folders = lcab.Folders; - } - - return Error = Error.MSPACK_ERR_OK; - } - - /// - /// Reads the cabinet file header, folder list and file list. - /// Fills out a pre-existing Cabinet structure, allocates memory - /// for folders and files as necessary - /// - private Error ReadHeaders(FileStream fh, Cabinet cab, long offset, bool salvage, bool quiet) - { - Error err = Error.MSPACK_ERR_OK; - Folder linkfol = null; - InternalFile linkfile = null; - - // Initialise pointers - if (cab == null) - cab = new Cabinet(); - - cab.Next = null; - cab.Files = null; - cab.Folders = null; - cab.PreviousCabinet = cab.NextCabinet = null; - cab.PreviousName = cab.NextName = null; - cab.PreviousInfo = cab.NextInfo = null; - - cab.BaseOffset = offset; - - #region Cabinet Header - - // Seek to CFHEADER - if (!System.Seek(fh, offset, SeekMode.MSPACK_SYS_SEEK_START)) - return Error = Error.MSPACK_ERR_SEEK; - - // Read in the CFHEADER - byte[] buf = new byte[_CabinetHeader.Size]; - if (System.Read(fh, buf, 0, _CabinetHeader.Size) != _CabinetHeader.Size) - return Error = Error.MSPACK_ERR_READ; - - // Create a new header based on that - err = _CabinetHeader.Create(buf, out _CabinetHeader cabinetHeader); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - // Assign the header - cab.Header = cabinetHeader; - - // Check for the extended header - if (cab.Header.Flags.HasFlag(HeaderFlags.MSCAB_HDR_RESV)) - { - buf = new byte[_CabinetHeader.ExtendedSize]; - if (System.Read(fh, buf, 0, _CabinetHeader.ExtendedSize) != _CabinetHeader.ExtendedSize) - return Error = Error.MSPACK_ERR_READ; - - // Populate the extended header - cabinetHeader.PopulateExtendedHeader(buf); - - // Skip the reserved header - if (cab.Header.HeaderReserved > 0) - { - if (!System.Seek(fh, cab.Header.HeaderReserved, SeekMode.MSPACK_SYS_SEEK_CUR)) - return Error = Error.MSPACK_ERR_SEEK; - } - } - - // Read name and info of preceeding cabinet in set, if present - if (cab.Header.Flags.HasFlag(HeaderFlags.MSCAB_HDR_PREVCAB)) - { - cab.PreviousName = ReadString(fh, false, ref err); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - cab.PreviousInfo = ReadString(fh, true, ref err); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - } - - // Read name and info of next cabinet in set, if present - if (cab.Header.Flags.HasFlag(HeaderFlags.MSCAB_HDR_NEXTCAB)) - { - cab.NextName = ReadString(fh, false, ref err); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - cab.NextInfo = ReadString(fh, true, ref err); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - } - - #endregion - - #region Folder and File Pointers - - // Read folders - for (int i = 0; i < cab.Header.NumFolders; i++) - { - err = ReadSingleFolder(fh, cab, offset, ref linkfol); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - } - - // Read files - for (int i = 0; i < cab.Header.NumFiles; i++) - { - err = ReadSingleFile(fh, cab, salvage, ref linkfile); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - } - - if (cab.Files == null) - { - // We never actually added any files to the file list. Something went wrong. - // The file header may have been invalid - Console.WriteLine($"No files found, even though header claimed to have {cab.Header.NumFiles} files"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - #endregion - - return Error.MSPACK_ERR_OK; - } - - /// - /// Read and process a single file - /// - private Error ReadSingleFile(FileStream fh, Cabinet cab, bool salvage, ref InternalFile linkfile) - { - // Read in the FIHEADER - byte[] buf = new byte[64]; - if (System.Read(fh, buf, 0, _FileHeader.Size) != _FileHeader.Size) - return Error.MSPACK_ERR_READ; - - InternalFile file = new InternalFile() { Next = null }; - - // Create a new header based on that - Error err = _FileHeader.Create(buf, out _FileHeader fileHeader); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Assign the header - file.Header = fileHeader; - - // Set folder pointer - if (file.Header.FolderIndex < FileFlags.CONTINUED_FROM_PREV) - { - // Normal folder index; count up to the correct folder - if ((int)file.Header.FolderIndex < cab.Header.NumFolders) - { - Folder ifol = cab.Folders; - while (file.Header.FolderIndex-- > 0) - { - if (ifol != null) - ifol = ifol.Next; - } - - file.Folder = ifol; - } - else - { - Console.WriteLine("Invalid folder index"); - file.Folder = null; - } - } - else - { - // Either CONTINUED_TO_NEXT, CONTINUED_FROM_PREV or CONTINUED_PREV_AND_NEXT - if (file.Header.FolderIndex == FileFlags.CONTINUED_TO_NEXT || file.Header.FolderIndex == FileFlags.CONTINUED_PREV_AND_NEXT) - { - // Get last folder - Folder ifol = cab.Folders; - while (ifol.Next != null) - { - ifol = ifol.Next; - } - - file.Folder = ifol; - - // Set "merge next" pointer - Folder fol = ifol; - if (fol.MergeNext == null) - fol.MergeNext = file; - } - - if (file.Header.FolderIndex == FileFlags.CONTINUED_FROM_PREV || file.Header.FolderIndex == FileFlags.CONTINUED_PREV_AND_NEXT) - { - // Get first folder - file.Folder = cab.Folders; - - // Set "merge prev" pointer - Folder fol = file.Folder; - if (fol.MergePrev == null) - fol.MergePrev = file; - } - } - - // Get filename - file.Filename = ReadString(fh, false, ref err); - - // If folder index or filename are bad, either skip it or fail - if (err != Error.MSPACK_ERR_OK || file.Folder == null) - { - if (salvage) - return Error.MSPACK_ERR_OK; - - return err != Error.MSPACK_ERR_OK ? err : Error.MSPACK_ERR_DATAFORMAT; - } - - // Link file entry into file list - if (linkfile == null) - cab.Files = file; - else - linkfile.Next = file; - - linkfile = file; - return Error.MSPACK_ERR_OK; - } - - /// - /// Read and process a single folder - /// - private Error ReadSingleFolder(FileStream fh, Cabinet cab, long offset, ref Folder linkfol) - { - // Read in the FOHEADER - byte[] buf = new byte[64]; - if (System.Read(fh, buf, 0, _FolderHeader.Size) != _FolderHeader.Size) - return Error.MSPACK_ERR_READ; - - if (cab.Header.FolderReserved > 0) - { - if (!System.Seek(fh, cab.Header.FolderReserved, SeekMode.MSPACK_SYS_SEEK_CUR)) - return Error.MSPACK_ERR_SEEK; - } - - // Create an empty folder - Folder fol = new Folder() - { - Next = null, - MergePrev = null, - MergeNext = null, - }; - - // Create a new header based on that - Error err = _FolderHeader.Create(buf, out _FolderHeader folderHeader); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Assign the header - fol.Header = folderHeader; - - // Set the folder data fields - fol.Data = new FolderData() - { - Next = null, - Cab = cab, - Offset = offset + fol.Header.DataOffset, - }; - - // Link folder into list of folders - if (linkfol == null) - cab.Folders = fol; - else - linkfol.Next = fol; - - linkfol = fol; - - return Error.MSPACK_ERR_OK; - } - - /// - /// Read a possibly empty string from the input - /// - private string ReadString(FileStream fh, bool permitEmpty, ref Error error) - { - long position = System.Tell(fh); - byte[] buf = new byte[256]; - int len, i; - - // Read up to 256 bytes - if ((len = System.Read(fh, buf, 0, 256)) <= 0) - { - error = Error.MSPACK_ERR_READ; - return null; - } - - // Search for a null terminator in the buffer - bool ok = false; - for (i = 0; i < len; i++) - { - if (buf[i] == 0x00) - { - ok = true; - break; - } - } - - // Optionally reject empty strings - if (i == 0 && !permitEmpty) - ok = false; - - if (!ok) - { - error = Error.MSPACK_ERR_DATAFORMAT; - return null; - } - - len = i + 1; - - // Set the data stream to just after the string and return - if (!System.Seek(fh, position + len, SeekMode.MSPACK_SYS_SEEK_START)) - { - error = Error.MSPACK_ERR_SEEK; - return null; - } - - error = Error.MSPACK_ERR_OK; - return Encoding.ASCII.GetString(buf, 0, len); - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/Enums.cs b/BurnOutSharp/External/libmspack/CAB/Enums.cs deleted file mode 100644 index 1279523b..00000000 --- a/BurnOutSharp/External/libmspack/CAB/Enums.cs +++ /dev/null @@ -1,112 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CAB -{ - [Flags] - public enum CompressionType : ushort - { - COMPTYPE_MASK = 0x000f, - - COMPTYPE_NONE = 0x0000, - COMPTYPE_MSZIP = 0x0001, - COMPTYPE_QUANTUM = 0x0002, - COMPTYPE_LZX = 0x0003, - } - - [Flags] - public enum FileAttributes : byte - { - /// - /// Indicates the file is write protected. - /// - MSCAB_ATTRIB_RDONLY = 0x01, - - /// - /// Indicates the file is hidden. - /// - MSCAB_ATTRIB_HIDDEN = 0x02, - - /// - /// Indicates the file is a operating system file. - /// - MSCAB_ATTRIB_SYSTEM = 0x04, - - /// - /// Indicates the file is "archived". - /// - MSCAB_ATTRIB_ARCH = 0x20, - - /// - /// Indicates the file is an executable program. - /// - MSCAB_ATTRIB_EXEC = 0x40, - - /// - /// Indicates the filename is in UTF8 format rather than ISO-8859-1. - /// - MSCAB_ATTRIB_UTF_NAME = 0x80, - } - - [Flags] - public enum FileFlags : ushort - { - CONTINUED_FROM_PREV = 0xFFFD, - CONTINUED_TO_NEXT = 0xFFFE, - CONTINUED_PREV_AND_NEXT = 0xFFFF, - } - - [Flags] - public enum HeaderFlags : ushort - { - /// - /// Indicates the cabinet is part of a cabinet set, and has a predecessor cabinet. - /// - MSCAB_HDR_PREVCAB = 0x0001, - - /// - /// Indicates the cabinet is part of a cabinet set, and has a successor cabinet. - /// - MSCAB_HDR_NEXTCAB = 0x0002, - - /// - /// Indicates the cabinet has reserved header space. - /// - MSCAB_HDR_RESV = 0x0004, - } - - public enum Parameters - { - /// - /// Search buffer size. - /// - MSCABD_PARAM_SEARCHBUF = 0, - - /// - /// Repair MS-ZIP streams? - /// - MSCABD_PARAM_FIXMSZIP = 1, - - /// - /// Size of decompression buffer - /// - MSCABD_PARAM_DECOMPBUF = 2, - - /// - /// salvage data from bad cabinets? - /// If enabled, open() will skip file with bad folder indices or filenames - /// rather than reject the whole cabinet, and extract() will limit rather than - /// reject files with invalid offsets and lengths, and bad data block checksums - /// will be ignored. Available only in CAB decoder version 2 and above. - /// - MSCABD_PARAM_SALVAGE = 3, - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/Folder.cs b/BurnOutSharp/External/libmspack/CAB/Folder.cs deleted file mode 100644 index 4c6ec590..00000000 --- a/BurnOutSharp/External/libmspack/CAB/Folder.cs +++ /dev/null @@ -1,60 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CAB -{ - /// - /// A structure which represents a single folder in a cabinet or cabinet set. - /// - /// All fields are READ ONLY. - /// - /// A folder is a single compressed stream of data. When uncompressed, it - /// holds the data of one or more files. A folder may be split across more - /// than one cabinet. - /// - public class Folder - { - #region Internal - - /// - /// Folder header information - /// - internal _FolderHeader Header { get; set; } - - #endregion - - /// - /// A pointer to the next folder in this cabinet or cabinet set, or NULL - /// if this is the final folder. - /// - public Folder Next { get; set; } - - /// - /// Where are the data blocks? - /// - public FolderData Data { get; set; } - - /// - /// First file needing backwards merge - /// - public InternalFile MergePrev { get; set; } - - /// - /// First file needing forwards merge - /// - public InternalFile MergeNext { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/FolderData.cs b/BurnOutSharp/External/libmspack/CAB/FolderData.cs deleted file mode 100644 index 1849f4bf..00000000 --- a/BurnOutSharp/External/libmspack/CAB/FolderData.cs +++ /dev/null @@ -1,29 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.CAB -{ - /// - /// There is one of these for every cabinet a folder spans - /// - public class FolderData - { - public FolderData Next { get; set; } - - /// - /// Cabinet file of this folder span - /// - public Cabinet Cab { get; set; } - - /// - /// Cabinet offset of first datablock - /// - public long Offset { get; set; } - }; -} diff --git a/BurnOutSharp/External/libmspack/CAB/InternalFile.cs b/BurnOutSharp/External/libmspack/CAB/InternalFile.cs deleted file mode 100644 index 85dd5df8..00000000 --- a/BurnOutSharp/External/libmspack/CAB/InternalFile.cs +++ /dev/null @@ -1,54 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CAB -{ - /// - /// A structure which represents a single file in a cabinet or cabinet set. - /// - /// All fields are READ ONLY. - /// - public class InternalFile - { - #region Internal - - /// - /// File header information - /// - internal _FileHeader Header { get; set; } - - #endregion - - /// - /// The next file in the cabinet or cabinet set, or NULL if this is the final file. - /// - public InternalFile Next { get; set; } - - /// - /// The filename of the file. - /// - /// A null terminated string of up to 255 bytes in length, it may be in - /// either ISO-8859-1 or UTF8 format, depending on the file attributes. - /// - /// - public string Filename { get; set; } - - /// - /// A pointer to the folder that contains this file. - /// - public Folder Folder { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/_CabinetHeader.cs b/BurnOutSharp/External/libmspack/CAB/_CabinetHeader.cs deleted file mode 100644 index 16917cd1..00000000 --- a/BurnOutSharp/External/libmspack/CAB/_CabinetHeader.cs +++ /dev/null @@ -1,204 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CAB -{ - internal class _CabinetHeader - { - #region Normal Header - - /// - /// "MSCF" - /// - /// 0x00 - public uint Signature { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x04 - public uint Reserved0 { get; private set; } - - /// - /// The length of the cabinet file in bytes. - /// - /// 0x08 - public uint CabinetSize { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0C - public uint Reserved1 { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x10 - public uint FileOffset { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x14 - public uint Reserved2 { get; private set; } - - /// - /// Minor cabinet version - /// - /// 0x18 - public byte MinorVersion { get; private set; } - - /// - /// Major cabinet version - /// - /// 0x19 - public byte MajorVersion { get; private set; } - - /// - /// Number of internal folders - /// - /// 0x1A - public ushort NumFolders { get; private set; } - - /// - /// Number of internal files - /// - /// 0x1C - public ushort NumFiles { get; private set; } - - /// - /// Header flags. - /// - /// 0x1E - /// - /// - /// - /// - /// - public HeaderFlags Flags { get; private set; } - - /// - /// The set ID of the cabinet. All cabinets in the same set should have - /// the same set ID. - /// - /// 0x20 - public ushort SetID { get; private set; } - - /// - /// The index number of the cabinet within the set. Numbering should - /// start from 0 for the first cabinet in the set, and increment by 1 for - /// each following cabinet. - /// - /// 0x22 - public ushort CabinetIndex { get; private set; } - - /// - /// Total size of the normal Cabinet header in bytes - /// - public const int Size = 0x24; - - #endregion - - #region Extended Header - - /// - /// The number of bytes reserved in the header area of the cabinet. - /// - /// If this is non-zero and flags has MSCAB_HDR_RESV set, this data can - /// be read by the calling application. It is of the given length, - /// located at offset (base_offset + MSCAB_HDR_RESV_OFFSET) in the - /// cabinet file. - /// - /// 0x24 - /// - public ushort HeaderReserved { get; private set; } - - /// - /// The number of bytes reserved in the folder area of the cabinet - /// - /// 0x26 - public byte FolderReserved { get; private set; } - - /// - /// The number of bytes reserved in the data area of the cabinet - /// - /// 0x27 - public byte DataReserved { get; private set; } - - /// - /// Total size of the extended Cabinet header in bytes - /// - public const int ExtendedSize = 0x04; - - #endregion - - /// - /// Private constructor - /// - private _CabinetHeader() { } - - /// - /// Create a _CabinetHeader from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _CabinetHeader header) - { - header = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - header = new _CabinetHeader(); - - header.Signature = BitConverter.ToUInt32(buffer, 0x00); - if (header.Signature != 0x4643534D) - return Error.MSPACK_ERR_SIGNATURE; - - header.Reserved0 = BitConverter.ToUInt32(buffer, 0x04); - header.CabinetSize = BitConverter.ToUInt32(buffer, 0x08); - header.Reserved1 = BitConverter.ToUInt32(buffer, 0x0C); - header.FileOffset = BitConverter.ToUInt32(buffer, 0x10); - header.Reserved2 = BitConverter.ToUInt32(buffer, 0x14); - - // Expect version 1.3, but don't validate - header.MinorVersion = buffer[0x18]; - header.MajorVersion = buffer[0x19]; - - header.NumFolders = BitConverter.ToUInt16(buffer, 0x1A); - if (header.NumFolders == 0) - return Error.MSPACK_ERR_DATAFORMAT; - - header.NumFiles = BitConverter.ToUInt16(buffer, 0x1C); - if (header.NumFiles == 0) - return Error.MSPACK_ERR_DATAFORMAT; - - header.Flags = (HeaderFlags)BitConverter.ToUInt16(buffer, 0x1E); - header.SetID = BitConverter.ToUInt16(buffer, 0x20); - header.CabinetIndex = BitConverter.ToUInt16(buffer, 0x20); - - return Error.MSPACK_ERR_OK; - } - - /// - /// Populate the extended header fields from buffer - /// - /// - public void PopulateExtendedHeader(byte[] buffer) - { - if (buffer.Length < ExtendedSize) - return; - - // Expect less than 60,000, but don't validate - HeaderReserved = BitConverter.ToUInt16(buffer, 0x00); - FolderReserved = buffer[0x02]; - DataReserved = buffer[0x03]; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/_DataBlockHeader.cs b/BurnOutSharp/External/libmspack/CAB/_DataBlockHeader.cs deleted file mode 100644 index e465d8bb..00000000 --- a/BurnOutSharp/External/libmspack/CAB/_DataBlockHeader.cs +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CAB -{ - internal class _DataBlockHeader - { - #region Fields - - /// - /// Block CRC32 checksum - /// - /// 0x00 - public uint CheckSum { get; private set; } - - /// - /// Compressed size of the data block - /// - /// 0x04 - public ushort CompressedSize { get; private set; } - - /// - /// Uncompressed size of the data block - /// - /// 0x06 - public ushort UncompressedSize { get; private set; } - - /// - /// Size of the Data Block header in bytes - /// - public const int Size = 0x08; - - #endregion - - /// - /// Private constructor - /// - private _DataBlockHeader() { } - - /// - /// Create a _DataBlockHeader from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _DataBlockHeader header) - { - header = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - header = new _DataBlockHeader(); - - header.CheckSum = BitConverter.ToUInt32(buffer, 0x00); - header.CompressedSize = BitConverter.ToUInt16(buffer, 0x04); - header.UncompressedSize = BitConverter.ToUInt16(buffer, 0x06); - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/_FileHeader.cs b/BurnOutSharp/External/libmspack/CAB/_FileHeader.cs deleted file mode 100644 index 92bcd008..00000000 --- a/BurnOutSharp/External/libmspack/CAB/_FileHeader.cs +++ /dev/null @@ -1,122 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CAB -{ - internal class _FileHeader - { - #region Fields - - /// - /// The uncompressed length of the file, in bytes. - /// - /// 0x00 - public uint UncompressedSize { get; private set; } - - /// - /// The uncompressed offset of this file in its folder. - /// - /// 0x04 - public uint FolderOffset { get; private set; } - - /// - /// Internal index of the folder - /// - /// 0x08 - public FileFlags FolderIndex { get; internal set; } - - /// - /// File's last modified date, day field. - /// - /// 0x0A - public byte LastModifiedDateDay { get; set; } - - /// - /// File's last modified date, month field. - /// - /// 0x0A - public byte LastModifiedDateMonth { get; set; } - - /// - /// File's last modified date, year field. - /// - /// 0x0A - public int LastModifiedDateYear { get; set; } - - /// - /// File's last modified time, hour field. - /// - /// 0x0C - public byte LastModifiedTimeHour { get; set; } - - /// - /// File's last modified time, minute field. - /// - /// 0x0C - public byte LastModifiedTimeMinute { get; set; } - - /// - /// File's last modified time, second field. - /// - /// 0x0C - public byte LastModifiedTimeSecond { get; set; } - - /// - /// File attributes. - /// - /// 0x0E - public FileAttributes Attributes { get; set; } - - /// - /// Size of the File header in bytes - /// - public const int Size = 0x10; - - #endregion - - /// - /// Private constructor - /// - private _FileHeader() { } - - /// - /// Create a _FileHeader from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _FileHeader header) - { - header = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - header = new _FileHeader(); - - header.UncompressedSize = BitConverter.ToUInt32(buffer, 0x00); - header.FolderOffset = BitConverter.ToUInt32(buffer, 0x04); - header.FolderIndex = (FileFlags)BitConverter.ToUInt16(buffer, 0x08); - - // Get date - ushort x = BitConverter.ToUInt16(buffer, 0x0A); - header.LastModifiedDateDay = (byte)(x & 0x1F); - header.LastModifiedDateMonth = (byte)((x >> 5) & 0xF); - header.LastModifiedDateYear = (x >> 9) + 1980; - - // Get time - x = BitConverter.ToUInt16(buffer, 0x0C); - header.LastModifiedTimeHour = (byte)(x >> 11); - header.LastModifiedTimeMinute = (byte)((x >> 5) & 0x3F); - header.LastModifiedTimeSecond = (byte)((x << 1) & 0x3E); - - header.Attributes = (FileAttributes)BitConverter.ToUInt16(buffer, 0x0E); - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CAB/_FolderHeader.cs b/BurnOutSharp/External/libmspack/CAB/_FolderHeader.cs deleted file mode 100644 index 001982cc..00000000 --- a/BurnOutSharp/External/libmspack/CAB/_FolderHeader.cs +++ /dev/null @@ -1,72 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CAB -{ - internal class _FolderHeader - { - #region Fields - - /// - /// Cabinet offset of first datablock - /// - /// 0x00 - public uint DataOffset { get; internal set; } - - /// - /// The total number of data blocks used by this folder. This includes - /// data blocks present in other files, if this folder spans more than - /// one cabinet. - /// - /// 0x04 - public ushort NumBlocks { get; internal set; } - - /// - /// The compression format used by this folder. - /// - /// The macro MSCABD_COMP_METHOD() should be used on this field to get - /// the algorithm used. The macro MSCABD_COMP_LEVEL() should be used to get - /// the "compression level". - /// - /// 0x06 - public CompressionType CompType { get; private set; } - - /// - /// Size of the Folder header in bytes - /// - public const int Size = 0x08; - - #endregion - - /// - /// Private constructor - /// - private _FolderHeader() { } - - /// - /// Create a _FolderHeader from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _FolderHeader header) - { - header = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - header = new _FolderHeader(); - - header.DataOffset = BitConverter.ToUInt32(buffer, 0x00); - header.NumBlocks = BitConverter.ToUInt16(buffer, 0x04); - header.CompType = (CompressionType)BitConverter.ToUInt16(buffer, 0x06); - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/CHM.cs b/BurnOutSharp/External/libmspack/CHM/CHM.cs deleted file mode 100644 index 50bf541a..00000000 --- a/BurnOutSharp/External/libmspack/CHM/CHM.cs +++ /dev/null @@ -1,85 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CHM -{ - /// - /// A structure which represents a CHM helpfile. - /// - /// All fields are READ ONLY. - /// - public class CHM : BaseHeader - { - #region Internal - - /// - /// CHM header information - /// - internal _CHMHeader Header { get; set; } - - /// - /// Header section table information - /// - internal _HeaderSectionTable HeaderSectionTable { get; set; } - - /// - /// Header section 0 information - /// - internal _HeaderSection0 HeaderSection0 { get; set; } - - /// - /// Header section 1 information - /// - internal _HeaderSection1 HeaderSection1 { get; set; } - - #endregion - - /// - /// The filename of the CHM helpfile. This is given by the library user - /// and may be in any format. - /// - public string Filename { get; set; } - - /// - /// A list of all non-system files in the CHM helpfile. - /// - public DecompressFile Files { get; set; } - - /// - /// A list of all system files in the CHM helpfile. - /// - /// System files are files which begin with "::". They are meta-files - /// generated by the CHM creation process. - /// - public DecompressFile SysFiles { get; set; } - - /// - /// The section 0 (uncompressed) data in this CHM helpfile. - /// - public UncompressedSection Sec0 { get; set; } - - /// - /// The section 1 (MSCompressed) data in this CHM helpfile. - /// - public MSCompressedSection Sec1 { get; set; } - - /// - /// A cache of loaded chunks, filled in by mschm_decoder::fast_find(). - /// Available only in CHM decoder version 2 and above. - /// - public byte[][] ChunkCache { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/CompressFile.cs b/BurnOutSharp/External/libmspack/CHM/CompressFile.cs deleted file mode 100644 index 305c675e..00000000 --- a/BurnOutSharp/External/libmspack/CHM/CompressFile.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CHM -{ - /// - /// A structure which represents a file to be placed in a CHM helpfile. - /// - /// A contiguous array of these structures should be passed to - /// Compressor.Generate(). The array list is terminated with an - /// entry whose InternalFile.Section field is set to #MSCHMC_ENDLIST, the - /// other fields in this entry are ignored. - /// - public class CompressFile - { - /// - /// One of #MSCHMC_ENDLIST, #MSCHMC_UNCOMP or #MSCHMC_MSCOMP. - /// - public SectionType Section { get; set; } - - /// - /// The filename of the source file that will be added to the CHM. This - /// is passed directly to mspack_system::open() - /// - public string Filename { get; set; } - - /// - /// The full path and filename of the file within the CHM helpfile, a - /// UTF-1 encoded null-terminated string. - /// - public string CHMFilename { get; set; } - - /// - /// The length of the file, in bytes. This will be adhered to strictly - /// and a read error will be issued if this many bytes cannot be read - /// from the real file at CHM generation time. - /// - public long Length { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/Compressor.cs b/BurnOutSharp/External/libmspack/CHM/Compressor.cs deleted file mode 100644 index 9b1144ef..00000000 --- a/BurnOutSharp/External/libmspack/CHM/Compressor.cs +++ /dev/null @@ -1,149 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; - -namespace LibMSPackSharp.CHM -{ - /// - /// A compressor for .CHM (Microsoft HTMLHelp) files. - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Compressor - { - #region Fields - - public SystemImpl System { get; set; } - - public string TempFile { get; set; } - - public bool UseTempFile { get; set; } - - public Error Error { get; set; } - - #endregion - - #region Public Functionality - - /// - /// Generates a CHM help file. - /// - /// The help file will contain up to two sections, an Uncompressed - /// section and potentially an MSCompressed (LZX compressed) - /// section. - /// - /// While the contents listing of a CHM file is always in lexical order, - /// the file list passed in will be taken as the correct order for files - /// within the sections. It is in your interest to place similar files - /// together for better compression. - /// - /// There are two modes of generation, to use a temporary file or not to - /// use one. See use_temporary_file() for the behaviour of generate() in - /// these two different modes. - /// - /// - /// an array of mschmc_file structures, terminated - /// with an entry whose mschmc_file::section field is - /// #MSCHMC_ENDLIST. The order of the list is - /// preserved within each section. The length of any - /// mschmc_file::chm_filename string cannot exceed - /// roughly 4096 bytes. Each source file must be able - /// to supply as many bytes as given in the - /// mschmc_file::length field. - /// - /// - /// the file to write the generated CHM helpfile to. - /// This is passed directly to mspack_system::open() - /// - /// an error code, or MSPACK_ERR_OK if successful - /// - /// - public Error Generate(CompressFile[] fileList, string outputFile) => throw new NotImplementedException(); - - /// - /// Specifies whether a temporary file is used during CHM generation. - /// - /// The CHM file format includes data about the compressed section (such - /// as its overall size) that is stored in the output CHM file prior to - /// the compressed section itself. This unavoidably requires that the - /// compressed section has to be generated, before these details can be - /// set. There are several ways this can be handled. Firstly, the - /// compressed section could be generated entirely in memory before - /// writing any of the output CHM file.This approach is not used in - /// libmspack, as the compressed section can exceed the addressable - /// memory space on most architectures. - /// - /// libmspack has two options, either to write these unknowable sections - /// with blank data, generate the compressed section, then re-open the - /// output file for update once the compressed section has been - /// completed, or to write the compressed section to a temporary file, - /// then write the entire output file at once, performing a simple - /// file-to-file copy for the compressed section. - /// - /// The simple solution of buffering the entire compressed section in - /// memory can still be used, if desired.As the temporary file's - /// filename is passed directly to mspack_system::open(), it is possible - /// for a custom mspack_system implementation to hold this file in memory, - /// without writing to a disk. - /// - /// If a temporary file is set, generate() performs the following - /// sequence of events: the temporary file is opened for writing, the - /// compression algorithm writes to the temporary file, the temporary - /// file is closed.Then the output file is opened for writing and the - /// temporary file is re-opened for reading.The output file is written - /// and the temporary file is read from. Both files are then closed.The - /// temporary file itself is not deleted. If that is desired, the - /// temporary file should be deleted after the completion of generate(), - /// if it exists. - /// - /// If a temporary file is set not to be used, generate() performs the - /// following sequence of events: the output file is opened for writing, - /// then it is written and closed.The output file is then re-opened for - /// update, the appropriate sections are seek() ed to and re-written, then - /// the output file is closed. - /// - /// - /// non-zero if the temporary file should be used, - /// zero if the temporary file should not be used. - /// - /// - /// a file to temporarily write compressed data to, - /// before opening it for reading and copying the - /// contents to the output file. This is passed - /// directly to mspack_system::open(). - /// - /// an error code, or MSPACK_ERR_OK if successful - /// - public Error UseTemporaryFile(bool useTempFile, string tempFile) => throw new NotImplementedException(); - - /// - /// Sets a CHM compression engine parameter. - /// - /// the parameter to set - /// the value to set the parameter to - /// - /// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there - /// is a problem with either parameter or value. - /// - /// - public Error SetParam(Parameters param, int value) => throw new NotImplementedException(); - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/DecompressFile.cs b/BurnOutSharp/External/libmspack/CHM/DecompressFile.cs deleted file mode 100644 index edf603f2..00000000 --- a/BurnOutSharp/External/libmspack/CHM/DecompressFile.cs +++ /dev/null @@ -1,52 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CHM -{ - /// - /// A structure which represents a file stored in a CHM helpfile. - /// - /// All fields are READ ONLY. - /// - public class DecompressFile - { - /// - /// A pointer to the next file in the list, or NULL if this is the final file. - /// - public DecompressFile Next { get; set; } - - /// - /// A pointer to the section that this file is located in. Indirectly, - /// it also points to the CHM helpfile the file is located in. - /// - public Section Section { get; set; } - - /// - /// The offset within the section data that this file is located at. - /// - public long Offset { get; set; } - - /// - /// The length of this file, in bytes - /// - public long Length { get; set; } - - /// - /// The filename of this file -- a null terminated string in UTF-8. - /// - public string Filename { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/DecompressState.cs b/BurnOutSharp/External/libmspack/CHM/DecompressState.cs deleted file mode 100644 index 8330c5e2..00000000 --- a/BurnOutSharp/External/libmspack/CHM/DecompressState.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using LibMSPackSharp.Compression; - -namespace LibMSPackSharp.CHM -{ - public class DecompressState : BaseDecompressState - { - /// - /// CHM file being decompressed - /// - public CHM Header { get; set; } - - /// - /// Uncompressed offset within folder - /// - public long Offset { get; set; } - - /// - /// Offset in input file - /// - public long InOffset { get; set; } - - /// - /// LZX decompressor state - /// - public LZX State { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs b/BurnOutSharp/External/libmspack/CHM/Decompressor.cs deleted file mode 100644 index 9f69b463..00000000 --- a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs +++ /dev/null @@ -1,1470 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; -using System.IO; -using System.Text; -using LibMSPackSharp.Compression; -using static LibMSPackSharp.Constants; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.CHM -{ - /// - /// A decompressor for .CHM (Microsoft HTMLHelp) files - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Decompressor : BaseDecompressor - { - #region Fields - - public DecompressState State { get; set; } - - #endregion - - #region Public Functionality - - /// - /// Opens a CHM helpfile and reads its contents. - /// - /// If the file opened is a valid CHM helpfile, all headers will be read - /// and a mschmd_header structure will be returned, with a full list of - /// files. - /// - /// In the case of an error occuring, NULL is returned and the error code - /// is available from last_error(). - /// - /// The filename pointer should be considered "in use" until close() is - /// called on the CHM helpfile. - /// - /// The filename of the CHM helpfile. This is passed directly to SystemImpl.Open(). - /// A pointer to a CHM structure, or NULL on failure - /// - public CHM Open(string filename) => RealOpen(filename, true); - - /// - /// Closes a previously opened CHM helpfile. - /// - /// This closes a CHM helpfile, frees the mschmd_header and all - /// mschmd_file structures associated with it (if any). This works on - /// both helpfiles opened with open() and helpfiles opened with - /// fast_open(). - /// - /// The CHM header pointer is now invalid and cannot be used again. All - /// mschmd_file pointers referencing that CHM are also now invalid, and - /// cannot be used again. - /// - /// The CHM helpfile to close - /// - /// - public void Close(CHM chm) - { - Error = Error.MSPACK_ERR_OK; - - // If this CHM was being decompressed, free decompression state - if (State != null && (State.Header == chm)) - { - System.Close(State.InputFileHandle); - System.Close(State.OutputFileHandle); - - State = null; - } - } - - /// - /// Extracts a file from a CHM helpfile. - /// - /// This extracts a file from a CHM helpfile and writes it to the given - /// filename.The filename of the file, mscabd_file::filename, is not - /// used by extract(), but can be used by the caller as a guide for - /// constructing an appropriate filename. - /// - /// This method works both with files found in the mschmd_header::files - /// and mschmd_header::sysfiles list and mschmd_file structures generated - /// on the fly by fast_find(). - /// - /// the file to be decompressed - /// the filename of the file being written to - /// an error code, or MSPACK_ERR_OK if successful - public Error Extract(DecompressFile file, string filename) - { - if (file == null || file.Section == null) - return Error = Error.MSPACK_ERR_ARGS; - - CHM chm = file.Section.Header; - - // Close existing file handles - System.Close(State?.InputFileHandle); - System.Close(State?.OutputFileHandle); - - // Allocate generic decompression state - State = new DecompressState() - { - Header = chm, - Offset = 0, - State = null, - System = System, - InputFileHandle = null, - OutputFileHandle = null, - }; - - State.System.Write = SysWrite; - - // Open input chm file if not open, or the open one is a different chm - State.InputFileHandle = System.Open(chm.Filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (State.InputFileHandle == null) - return Error = Error.MSPACK_ERR_OPEN; - - // Open file for output - FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE); - if (fh == null) - return Error = Error.MSPACK_ERR_OPEN; - - // If file is empty, simply creating it is enough - if (file.Length == 0) - { - System.Close(fh); - return Error = Error.MSPACK_ERR_OK; - } - - Error = Error.MSPACK_ERR_OK; - - // Decompress the file based on section ID - switch (file.Section.ID) - { - // Uncompressed section file - case 0: - return ExtractSection0File(file, fh); - - // MSCompressed section file - case 1: - return ExtractSection1File(file, fh); - - // Should not happen - default: - System.Close(fh); - return Error = Error.MSPACK_ERR_ARGS; - } - } - - /// - /// Opens a CHM helpfile quickly. - /// - /// If the file opened is a valid CHM helpfile, only essential headers - /// will be read.A mschmd_header structure will be still be returned, as - /// with open(), but the mschmd_header::files field will be NULL.No - /// files details will be automatically read.The fast_find() method - /// must be used to obtain file details. - /// - /// In the case of an error occuring, NULL is returned and the error code - /// is available from last_error(). - /// - /// The filename pointer should be considered "in use" until close() is - /// called on the CHM helpfile. - /// - /// - /// the filename of the CHM helpfile. This is passed - /// directly to mspack_system::open(). - /// - /// a pointer to a mschmd_header structure, or NULL on failure - /// - /// - /// - /// - public CHM FastOpen(string filename) => RealOpen(filename, false); - - #endregion - - #region Decompress State - - /// - /// Initialises the LZX decompressor to decompress the compressed stream, - /// from the nearest reset offset and length that is needed for the given - /// file. - /// - internal Error InitDecompressor(DecompressFile file) - { - MSCompressedSection sec = file.Section as MSCompressedSection; - - // Ensure we have a mscompressed content section - DecompressFile contentFile = null; - Error err = FindSysFile(sec, ref contentFile, ContentName); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - sec.Content = contentFile; - - // Ensure we have a ControlData file - DecompressFile controlFile = null; - err = FindSysFile(sec, ref controlFile, ControlName); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - sec.Control = controlFile; - - // Read ControlData - if (sec.Control.Length != _LZXControlData.Size) - { - Console.WriteLine("ControlData file is wrong size"); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - byte[] data = ReadSysFile(sec.Control); - if (data == null) - { - Console.WriteLine("Can't read mscompressed control data file"); - return Error; - } - - // Create a new control data based on that - err = _LZXControlData.Create(data, out _LZXControlData lzxControlData); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - // Find window_bits from window_size - err = lzxControlData.GetWindowBits(out int windowBits); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - // Validate reset_interval - if (lzxControlData.ResetInterval == 0 || (lzxControlData.ResetInterval % LZX_FRAME_SIZE) > 0) - { - Console.WriteLine("Bad controldata reset interval"); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - // Which reset table entry would we like? - int entry = (int)(file.Offset / lzxControlData.ResetInterval); - - // Convert from reset interval multiple (usually 64k) to 32k frames - entry *= (int)lzxControlData.ResetInterval / LZX_FRAME_SIZE; - - // Read the reset table entry - if (ReadResetTable(sec, (uint)entry, out long length, out long offset)) - { - // The uncompressed length given in the reset table is dishonest. - // The uncompressed data is always padded out from the given - // uncompressed length up to the next reset interval - - length += lzxControlData.ResetInterval - 1; - length &= -lzxControlData.ResetInterval; - } - else - { - // If we can't read the reset table entry, just start from - // the beginning. Use spaninfo to get the uncompressed length - - entry = 0; - offset = 0; - err = ReadSpanInfo(sec, out length); - } - - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - // Get offset of compressed data stream: - // = offset of uncompressed section from start of file - // + offset of compressed stream from start of uncompressed section - // + offset of chosen reset interval from start of compressed stream - State.InOffset = file.Section.Header.Sec0.Offset + sec.Content.Offset + offset; - - // Set start offset and overall remaining stream length - State.Offset = entry * LZX_FRAME_SIZE; - length -= State.Offset; - - // Initialise LZX stream - State.State = LZX.Init(State.System, State.InputFileHandle, State.OutputFileHandle, windowBits, (int)lzxControlData.ResetInterval / LZX_FRAME_SIZE, 4096, length, false); - - if (State.State == null) - Error = Error.MSPACK_ERR_NOMEMORY; - - return Error; - } - - #endregion - - #region I/O Methods - - /// - /// SysWrite is the internal writer function which the decompressor - /// uses. If either writes data to disk (self.State.OutputFileHandle) with the real - /// sys.write() function, or does nothing with the data when - /// self.State.OutputFileHandle == null. advances self.State.Offset. - /// - private static int SysWrite(object file, byte[] buffer, int offset, int bytes) - { - // Null output file means skip those bytes - if (file == null) - { - return bytes; - } - else if (file is Decompressor self) - { - self.State.Offset += (uint)bytes; - if (self.State.OutputFileHandle != null) - return self.System.Write(self.State.OutputFileHandle, buffer, offset, bytes); - - return bytes; - } - else if (file is FileStream impl) - { - return SystemImpl.DefaultSystem.Write(impl, buffer, offset, bytes); - } - - // Unknown file to write to - return -1; - } - - #endregion - - #region Helpers - - /// - /// Extract a Section 0 file - /// - private Error ExtractSection0File(DecompressFile file, FileStream fh) - { - // Simple seek + copy - if (!System.Seek(State.InputFileHandle, file.Section.Header.Sec0.Offset + file.Offset, SeekMode.MSPACK_SYS_SEEK_START)) - { - System.Close(fh); - return Error = Error.MSPACK_ERR_SEEK; - } - - byte[] buf = new byte[512]; - long length = file.Length; - while (length > 0) - { - int run = 512; - if (run > length) - run = (int)length; - - if (System.Read(State.InputFileHandle, buf, 0, run) != run) - { - System.Close(fh); - return Error = Error.MSPACK_ERR_READ; - } - - if (System.Write(fh, buf, 0, run) != run) - { - System.Close(fh); - return Error = Error.MSPACK_ERR_WRITE; - } - - length -= run; - } - - System.Close(fh); - return Error = Error.MSPACK_ERR_OK; - } - - /// - /// Extract a Section 1 file - /// - private Error ExtractSection1File(DecompressFile file, FileStream fh) - { - // (Re)initialise compression state if we it is not yet initialised, - // or we have advanced too far and have to backtrack - if (State.State == null || (file.Offset < State.Offset)) - { - if (State.State != null) - State.State = null; - - if (InitDecompressor(file) != Error.MSPACK_ERR_OK) - { - System.Close(fh); - return Error; - } - } - - // Seek to input data - if (!System.Seek(State.InputFileHandle, State.InOffset, SeekMode.MSPACK_SYS_SEEK_START)) - { - System.Close(fh); - return Error = Error.MSPACK_ERR_SEEK; - } - - // Get to correct offset. - State.OutputFileHandle = null; - long bytes; - if ((bytes = file.Offset - State.Offset) > 0) - Error = State.State.Decompress(bytes); - - // If getting to the correct offset was error free, unpack file - if (Error == Error.MSPACK_ERR_OK) - { - State.OutputFileHandle = fh; - Error = State.State.Decompress(file.Length); - } - - // Save offset in input source stream, in case there is a section 0 - // file between now and the next section 1 file extracted - State.InOffset = System.Tell(State.InputFileHandle); - - // If an LZX error occured, the LZX decompressor is now useless - if (Error != Error.MSPACK_ERR_OK) - State.State = null; - - System.Close(fh); - return Error; - } - - /// - /// Finds file details quickly. - /// - /// Instead of reading all CHM helpfile headers and building a list of - /// files, fast_open() and fast_find() are intended for finding file - /// details only when they are needed.The CHM file format includes an - /// on-disk file index to allow this. - /// - /// Given a case-sensitive filename, fast_find() will search the on-disk - /// index for that file. - /// - /// If the file was found, the caller-provided mschmd_file structure will - /// be filled out like so: - /// - section: the correct value for the found file - /// - offset: the correct value for the found file - /// - length: the correct value for the found file - /// - all other structure elements: NULL or 0 - /// - /// If the file was not found, MSPACK_ERR_OK will still be returned as the - /// result, but the caller-provided structure will be filled out like so: - /// - section: NULL - /// - offset: 0 - /// - length: 0 - /// - all other structure elements: NULL or 0 - /// - /// This method is intended to be used in conjunction with CHM helpfiles - /// opened with fast_open(), but it also works with helpfiles opened - /// using the regular open(). - /// - /// the CHM helpfile to search for the file - /// the filename of the file to search for - /// a pointer to a caller-provded mschmd_file structure - /// an error code, or MSPACK_ERR_OK if successful - /// - /// - /// - /// - private Error FastFind(CHM chm, string filename, DecompressFile f_ptr) - { - // p and end are initialised to prevent MSVC warning about "potentially" - // uninitialised usage. This is provably untrue, but MS won't fix: - // https://developercommunity.visualstudio.com/content/problem/363489/c4701-false-positive-warning.html - int p = -1, end = -1, result = -1; - Error err = Error.MSPACK_ERR_OK; - uint n, sec; - - if (chm == null || f_ptr == null) - return Error.MSPACK_ERR_ARGS; - - // Clear the results structure - f_ptr = new DecompressFile(); - - FileStream fh = System.Open(chm.Filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (fh == null) - return Error.MSPACK_ERR_OPEN; - - // Go through PMGI chunk hierarchy to reach PMGL chunk - byte[] chunk = null; - if (chm.HeaderSection1.IndexRoot < chm.HeaderSection1.NumChunks) - { - n = chm.HeaderSection1.IndexRoot; - for (; ; ) - { - chunk = ReadChunk(chm, fh, n); - if (chunk == null) - { - System.Close(fh); - return Error; - } - - // Search PMGI/PMGL chunk. exit early if no entry found - if ((result = SearchChunk(chm, chunk, filename, ref p, ref end)) <= 0) - break; - - // Found result. loop around for next chunk if this is PMGI - if (chunk[3] == 0x4C) - { - break; - } - else - { - // READ_ENCINT(n) - { - (n) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (n) = (uint)(((n) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - } - } - } - else - { - // PMGL chunks only, search from first_pmgl to last_pmgl - for (n = chm.HeaderSection1.FirstPMGL; n <= chm.HeaderSection1.LastPMGL; n = BitConverter.ToUInt32(chunk, 0x0010)) - { - chunk = ReadChunk(chm, fh, n); - if (chunk == null) - { - err = Error; - break; - } - - // Search PMGL chunk. exit if file found - if ((result = SearchChunk(chm, chunk, filename, ref p, ref end)) > 0) - break; - - // Stop simple infinite loops: can't visit the same chunk twice - if (n == BitConverter.ToUInt32(chunk, 0x0010)) - break; - } - } - - // If we found a file, read it - if (result > 0) - { - // READ_ENCINT(sec) - { - (sec) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (sec) = (uint)(((sec) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - f_ptr.Section = sec == 0 ? chm.Sec0 as Section : chm.Sec1 as Section; - - // READ_ENCINT(f_ptr.Offset) - { - (f_ptr.Offset) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (f_ptr.Offset) = (((f_ptr.Offset) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - // READ_ENCINT(f_ptr.Length) - { - (f_ptr.Length) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (f_ptr.Length) = (((f_ptr.Length) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - } - else if (result < 0) - { - err = Error.MSPACK_ERR_DATAFORMAT; - } - - System.Close(fh); - return Error = err; - } - - /// - /// Uses chmd_fast_find to locate a system file, and fills out that system - /// file's entry and links it into the list of system files. Returns zero - /// for success, non-zero for both failure and the file not existing. - /// - private Error FindSysFile(MSCompressedSection sec, ref DecompressFile f_ptr, string name) - { - DecompressFile result = null; - - // Already loaded - if (f_ptr != null) - return Error.MSPACK_ERR_OK; - - // Try using fast_find to find the file - return DATAFORMAT error if - // it fails, or successfully doesn't find the file - if (FastFind(sec.Header, name, result) != Error.MSPACK_ERR_OK || result.Section == null) - return Error.MSPACK_ERR_DATAFORMAT; - - // Copy result - f_ptr = result; - f_ptr.Filename = name; - - // Link file into sysfiles list - f_ptr.Next = sec.Header.SysFiles; - sec.Header.SysFiles = f_ptr; - - return Error.MSPACK_ERR_OK; - } - - /// - /// Reads the given chunk into memory, storing it in a chunk cache - /// so it doesn't need to be read from disk more than once - /// - private byte[] ReadChunk(CHM chm, FileStream fh, uint chunkNum) - { - // Check arguments - most are already checked by chmd_fast_find - if (chunkNum >= chm.HeaderSection1.NumChunks) - return null; - - // Ensure chunk cache is available - if (chm.ChunkCache == null) - chm.ChunkCache = new byte[chm.HeaderSection1.NumChunks][]; - - // Try to answer out of chunk cache - if (chm.ChunkCache[chunkNum] != null) - return chm.ChunkCache[chunkNum]; - - // Need to read chunk - allocate memory for it - byte[] buf = new byte[chm.HeaderSection1.ChunkSize]; - - // Seek to block and read it - if (!System.Seek(fh, (chm.HeaderSectionTable.OffsetHS1 + (chunkNum * chm.HeaderSection1.ChunkSize)), SeekMode.MSPACK_SYS_SEEK_START)) - { - Error = Error.MSPACK_ERR_SEEK; - return null; - } - - if (System.Read(fh, buf, 0, (int)chm.HeaderSection1.ChunkSize) != (int)chm.HeaderSection1.ChunkSize) - { - Error = Error.MSPACK_ERR_READ; - return null; - } - - // Check the signature. Is is PMGL or PMGI? - if (!((buf[0] == 0x50) && (buf[1] == 0x4D) && (buf[2] == 0x47) && ((buf[3] == 0x4C) || (buf[3] == 0x49)))) - { - Error = Error.MSPACK_ERR_SEEK; - return null; - } - - // All OK. Store chunk in cache and return it - return chm.ChunkCache[chunkNum] = buf; - } - - /// - /// Reads the basic CHM file headers. If the "entire" parameter is - /// non-zero, all file entries will also be read. fills out a pre-existing - /// mschmd_header structure, allocates memory for files as necessary - /// - private Error ReadHeaders(FileStream fh, CHM chm, bool entire) - { - uint section, nameLen, x, errors, numChunks; - byte[] buf = new byte[0x54]; - int name, p, end; - DecompressFile fi, link = null; - long offset, length; - int numEntries; - - // Initialise pointers - chm.Files = null; - chm.SysFiles = null; - chm.ChunkCache = null; - - chm.Sec0.Header = chm; - chm.Sec0.ID = 0; - - chm.Sec1.Header = chm; - chm.Sec1.ID = 1; - chm.Sec1.Content = null; - chm.Sec1.Control = null; - chm.Sec1.SpanInfo = null; - chm.Sec1.ResetTable = null; - - #region Header - - // Read the first header - if (System.Read(fh, buf, 0, _CHMHeader.Size) != _CHMHeader.Size) - return Error.MSPACK_ERR_READ; - - // Create a new header based on that - Error err = _CHMHeader.Create(buf, out _CHMHeader chmHeader); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Assign the header - chm.Header = chmHeader; - if (chm.Header.Version > 3) - System.Message(fh, "WARNING; CHM version > 3"); - - #endregion - - #region Header Section Table - - // Read the header section table - if (System.Read(fh, buf, 0, _HeaderSectionTable.V3Size) != _HeaderSectionTable.V3Size) - return Error.MSPACK_ERR_READ; - - // Create a new secton table based on that - err = _HeaderSectionTable.Create(buf, out _HeaderSectionTable sectionTable); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Assign the section table - chm.HeaderSectionTable = sectionTable; - - // Assign the CS0 value to the Sec0.Offset for later - chm.Sec0.Offset = chm.HeaderSectionTable.OffsetCS0; - - #endregion - - #region Header Section 0 - - // Seek to header section 0 - if (!System.Seek(fh, chm.HeaderSectionTable.OffsetHS0, SeekMode.MSPACK_SYS_SEEK_START)) - return Error.MSPACK_ERR_SEEK; - - // Read header section 0 - if (System.Read(fh, buf, 0, _HeaderSection0.Size) != _HeaderSection0.Size) - return Error.MSPACK_ERR_READ; - - // Create a new secton 0 based on that - err = _HeaderSection0.Create(buf, out _HeaderSection0 section0); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Assign the section 0 - chm.HeaderSection0 = section0; - - #endregion - - #region Header Section 1 - - // Seek to header section 1 - if (!System.Seek(fh, chm.HeaderSectionTable.OffsetHS1, SeekMode.MSPACK_SYS_SEEK_START)) - return Error.MSPACK_ERR_SEEK; - - // Read header section 1 - if (System.Read(fh, buf, 0, _HeaderSection1.Size) != _HeaderSection1.Size) - return Error.MSPACK_ERR_READ; - - // Create a new secton 1 based on that - err = _HeaderSection1.Create(buf, out _HeaderSection1 section1); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Assign the section 1 - chm.HeaderSection1 = section1; - - chm.HeaderSectionTable.OffsetHS1 = System.Tell(fh); - - // Versions before 3 don't have OffsetCS0 - if (chm.Header.Version < 3) - chm.Sec0.Offset = chm.HeaderSectionTable.OffsetHS1 + (chm.HeaderSection1.ChunkSize * chm.HeaderSection1.NumChunks); - - // Check if content offset or file size is wrong - if (chm.Sec0.Offset > chm.HeaderSection0.FileLength) - { - Console.WriteLine("Content section begins after file has ended"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - // Ensure there are chunks and that chunk size is - // large enough for signature and num_entries - if (chm.HeaderSection1.ChunkSize < (_PMGHeader.PMGLSize + 2)) - { - Console.WriteLine("Chunk size not large enough"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - if (chm.HeaderSection1.NumChunks == 0) - { - Console.WriteLine("No chunks"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - // The ChunkCache data structure is not great; large values for NumChunks - // or NumChunks*ChunkSize can exhaust all memory. Until a better chunk - // cache is implemented, put arbitrary limits on NumChunks and chunk size. - if (chm.HeaderSection1.NumChunks > 100000) - { - Console.WriteLine("More than 100,000 chunks"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - if (chm.HeaderSection1.ChunkSize > 8192) - { - Console.WriteLine("Chunk size over 8192 (get in touch if this is valid)"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - if (chm.HeaderSection1.ChunkSize * (long)chm.HeaderSection1.NumChunks > chm.HeaderSection0.FileLength) - { - Console.WriteLine("Chunks larger than entire file"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - // Common sense checks on header section 1 fields - if (chm.HeaderSection1.ChunkSize != 4096) - System.Message(fh, "WARNING; chunk size is not 4096"); - - if (chm.HeaderSection1.FirstPMGL != 0) - System.Message(fh, "WARNING; first PMGL chunk is not zero"); - - if (chm.HeaderSection1.FirstPMGL > chm.HeaderSection1.LastPMGL) - { - Console.WriteLine("First pmgl chunk is after last pmgl chunk"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - if (chm.HeaderSection1.IndexRoot != 0xFFFFFFFF && chm.HeaderSection1.IndexRoot >= chm.HeaderSection1.NumChunks) - { - Console.WriteLine("IndexRoot outside valid range"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - #endregion - - // If we are doing a quick read, stop here! - if (!entire) - return Error.MSPACK_ERR_OK; - - // Seek to the first PMGL chunk, and reduce the number of chunks to read - if ((x = chm.HeaderSection1.FirstPMGL) != 0) - { - if (!System.Seek(fh, x * chm.HeaderSection1.ChunkSize, SeekMode.MSPACK_SYS_SEEK_CUR)) - return Error.MSPACK_ERR_SEEK; - } - - numChunks = chm.HeaderSection1.LastPMGL - x + 1; - - byte[] chunk = new byte[chm.HeaderSection1.ChunkSize]; - - // Read and process all chunks from FirstPMGL to LastPMGL - errors = 0; - while (numChunks-- > 0) - { - // Read next chunk - if (System.Read(fh, chunk, 0, (int)chm.HeaderSection1.ChunkSize) != (int)chm.HeaderSection1.ChunkSize) - return Error.MSPACK_ERR_READ; - - // Create a new header based on that - err = _PMGHeader.Create(buf, out _PMGHeader pmgHeader); - if (err != Error.MSPACK_ERR_OK) - return err; - - // Process only directory (PMGL) chunks - if (!pmgHeader.IsPMGL()) - continue; - - if (pmgHeader.QuickRefSize < 2) - System.Message(fh, "WARNING; PMGL quickref area is too small"); - - if (pmgHeader.QuickRefSize > chm.HeaderSection1.ChunkSize - pmgHeader.PMGLEntries) - System.Message(fh, "WARNING; PMGL quickref area is too large"); - - p = (int)pmgHeader.PMGLEntries; - end = (int)(chm.HeaderSection1.ChunkSize - 2); - numEntries = BitConverter.ToUInt16(chunk, end); - - while (numEntries-- > 0) - { - // READ_ENCINT(nameLen) - { - (nameLen) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (nameLen) = (uint)(((nameLen) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - if (nameLen > (uint)(end - p)) - { - if (numEntries >= 0) - { - Console.WriteLine("Chunk ended before all entries could be read"); - errors++; - } - } - - name = p; p += (int)nameLen; - - // READ_ENCINT(section) - { - (section) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (section) = (uint)(((section) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - // READ_ENCINT(offset) - { - (offset) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (offset) = (((offset) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - // READ_ENCINT(length) - { - (length) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - (length) = (((length) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - // READ_ENCINT(length) - - // Ignore blank or one-char (e.g. "/") filenames we'd return as blank - if (nameLen < 2 || chunk[name + 0] == 0x00 || chunk[name + 1] == 0x00) - continue; - - // Empty files and directory names are stored as a file entry at - // offset 0 with length 0. We want to keep empty files, but not - // directory names, which end with a "/" - if ((offset == 0) && (length == 0)) - { - if ((nameLen > 0) && (chunk[name + nameLen - 1] == '/')) - continue; - } - - if (section > 1) - { - System.Message(fh, $"Invalid section number '{section}'."); - continue; - } - - fi = new DecompressFile() - { - Next = null, - Filename = Encoding.UTF8.GetString(chunk, name, (int)nameLen) + "\0", - Section = (section == 0) ? chm.Sec0 as Section : chm.Sec1 as Section, - Offset = offset, - Length = length, - }; - - if (chunk[name + 0] == ':' && chunk[name + 1] == ':') - { - // System file - if (nameLen == 40 && fi.Filename.Trim().Equals(ContentName)) - chm.Sec1.Content = fi; - - else if (nameLen == 44 && fi.Filename.Trim().Equals(ControlName)) - chm.Sec1.Control = fi; - - else if (nameLen == 41 && fi.Filename.Trim().Equals(SpanInfoName)) - chm.Sec1.SpanInfo = fi; - - else if (nameLen == 105 && fi.Filename.Trim().Equals(ResetTableName)) - chm.Sec1.ResetTable = fi; - - fi.Next = chm.SysFiles; - chm.SysFiles = fi; - } - else - { - // Normal file - if (link != null) - link.Next = fi; - else - chm.Files = fi; - - link = fi; - } - } - } - - return (errors > 0) ? Error.MSPACK_ERR_DATAFORMAT : Error.MSPACK_ERR_OK; - } - - /// - /// Reads one entry out of the reset table. Also reads the uncompressed - /// data length. Writes these to offsetPointer and lengthPointer respectively. - /// Returns non-zero for success, zero for failure. - /// - private bool ReadResetTable(MSCompressedSection sec, uint entry, out long lengthPointer, out long offsetPointer) - { - lengthPointer = 0; offsetPointer = 0; - byte[] data; - - // Do we have a ResetTable file? - DecompressFile resetTable = null; - Error err = FindSysFile(sec, ref resetTable, ResetTableName); - if (err != Error.MSPACK_ERR_OK) - return false; - - sec.ResetTable = resetTable; - - // Read ResetTable file - if (sec.ResetTable.Length < _LZXResetTable.Size) - { - Console.WriteLine("ResetTable file is too short"); - return false; - } - - if (sec.ResetTable.Length > 1000000) - { - // Arbitrary upper limit - Console.WriteLine($"ResetTable >1MB ({sec.ResetTable.Length}), report if genuine"); - return false; - } - - if ((data = ReadSysFile(sec.ResetTable)) == null) - { - Console.WriteLine("can't read reset table"); - return false; - } - - // Create a new reset data based on that - err = _LZXResetTable.Create(data, out _LZXResetTable lzxResetTable); - if (err != Error.MSPACK_ERR_OK) - return false; - - // Check sanity of reset table - if (lzxResetTable.FrameLength != LZX_FRAME_SIZE) - { - Console.WriteLine("Bad reset table frame length"); - return false; - } - - // Get the uncompressed length of the LZX stream - if ((lengthPointer = lzxResetTable.UncompressedLength) == 0) - return false; - - uint pos = lzxResetTable.TableOffset + (entry * lzxResetTable.EntrySize); - - // Ensure reset table entry for this offset exists - if (entry < lzxResetTable.NumEntries && pos <= (sec.ResetTable.Length - lzxResetTable.EntrySize)) - { - switch (lzxResetTable.EntrySize) - { - case 4: - offsetPointer = BitConverter.ToUInt32(data, (int)pos); - err = Error.MSPACK_ERR_OK; - break; - case 8: - offsetPointer = BitConverter.ToInt64(data, (int)pos); - break; - default: - Console.WriteLine("Reset table entry size neither 4 nor 8"); - err = Error.MSPACK_ERR_ARGS; - break; - } - } - else - { - Console.WriteLine("Bad reset interval"); - err = Error.MSPACK_ERR_ARGS; - } - - // Return success - return (err == Error.MSPACK_ERR_OK); - } - - /// - /// Reads the uncompressed data length from the spaninfo file. - /// Returns zero for success or a non-zero error code for failure. - /// - private Error ReadSpanInfo(MSCompressedSection sec, out long length_ptr) - { - length_ptr = 0; - - // Find SpanInfo file - DecompressFile spanInfo = null; - Error err = FindSysFile(sec, ref spanInfo, SpanInfoName); - if (err != Error.MSPACK_ERR_OK) - return Error.MSPACK_ERR_DATAFORMAT; - - sec.SpanInfo = spanInfo; - - // Check it's large enough - if (sec.SpanInfo.Length != 8) - { - Console.WriteLine("SpanInfo file is wrong size"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - // Read the SpanInfo file - byte[] data; - if ((data = ReadSysFile(sec.SpanInfo)) == null) - { - Console.WriteLine("can't read SpanInfo file"); - return Error; - } - - // Get the uncompressed length of the LZX stream - length_ptr = BitConverter.ToInt64(data, 0); - if (length_ptr <= 0) - { - Console.WriteLine("output length is invalid"); - return Error.MSPACK_ERR_DATAFORMAT; - } - - return Error.MSPACK_ERR_OK; - } - - /// - /// Allocates memory for a section 0 (uncompressed) file and reads it into memory. - /// - private byte[] ReadSysFile(DecompressFile file) - { - if (file == null || file.Section == null || (file.Section.ID != 0)) - { - Error = Error.MSPACK_ERR_DATAFORMAT; - return null; - } - - int len = (int)file.Length; - byte[] data = new byte[len]; - - if (System.Seek(State.InputFileHandle, file.Section.Header.Sec0.Offset + file.Offset, SeekMode.MSPACK_SYS_SEEK_START)) - { - Error = Error.MSPACK_ERR_SEEK; - return null; - } - - if (System.Read(State.InputFileHandle, data, 0, len) != len) - { - Error = Error.MSPACK_ERR_READ; - return null; - } - - return data; - } - - /// - /// The real implementation of chmd_open() and chmd_fast_open(). It simply - /// passes the "entire" parameter to chmd_read_headers(), which will then - /// either read all headers, or a bare mininum. - /// - private CHM RealOpen(string filename, bool entire) - { - FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (fh != null) - { - CHM chm = new CHM() { Filename = filename }; - Error error = ReadHeaders(fh, chm, entire); - if (error != Error.MSPACK_ERR_OK) - { - // If the error is DATAFORMAT, and there are some results, return - // partial results with a warning, rather than nothing - if (error == Error.MSPACK_ERR_DATAFORMAT && (chm.Files != null || chm.SysFiles != null)) - { - System.Message(fh, "WARNING; contents are corrupt"); - error = Error.MSPACK_ERR_OK; - } - else - { - Close(chm); - chm = null; - } - } - - Error = error; - System.Close(fh); - return chm; - } - else - { - Error = Error.MSPACK_ERR_OPEN; - return null; - } - } - - /// - /// searches a PMGI/PMGL chunk for a given filename entry. Returns -1 on - /// data format error, 0 if entry definitely not found, 1 if entry - /// found.In the latter case, * result and* result_end are set pointing - /// to that entry's data (either the "next chunk" ENCINT for a PMGI or - /// the section, offset and length ENCINTs for a PMGL). - /// - /// In the case of PMGL chunks, the entry has definitely been - /// found.In the case of PMGI chunks, the entry which points to the - /// chunk that may eventually contain that entry has been found. - /// - private int SearchChunk(CHM chm, byte[] chunk, string filename, ref int result, ref int resultEnd) - { - int p; - uint nameLen; - uint left, right, midpoint, entries; - int cmp; - - // Create a new header based on the chunk - Error err = _PMGHeader.Create(chunk, out _PMGHeader pmgHeader); - if (err != Error.MSPACK_ERR_OK) - return -1; - - // PMGL chunk or PMGI chunk? (note: read_chunk() has already - // checked the rest of the characters in the chunk signature) - if (pmgHeader.IsPMGL()) - entries = pmgHeader.PMGLEntries; - else - entries = pmgHeader.PMGIEntries; - - // Step 1: binary search first filename of each QR entry - // - target filename == entry - // found file - // - target filename < all entries - // file not found - // - target filename > all entries - // proceed to step 2 using final entry - // - target filename between two searched entries - // Proceed to step 2 - uint qrSize = pmgHeader.QuickRefSize; - int start = (int)(chm.HeaderSection1.ChunkSize - 2); - int end = (int)(chm.HeaderSection1.ChunkSize - qrSize); - ushort numEntries = BitConverter.ToUInt16(chunk, start); - uint qrDensity = 1 + (uint)(1 << (int)chm.HeaderSection1.Density); - uint qrEntries = (numEntries + qrDensity - 1) / qrDensity; - - if (numEntries == 0) - { - Console.Write("Chunk has no entries"); - return -1; - } - - if (qrSize > chm.HeaderSection1.ChunkSize) - { - Console.Write("quickref size > chunk size"); - return -1; - } - - resultEnd = end; - - if (((int)qrEntries * 2) > (start - end)) - { - Console.Write("WARNING; more quickrefs than quickref space"); - qrEntries = 0; // But we can live with it - } - - if (qrEntries > 0) - { - left = 0; - right = qrEntries - 1; - do - { - // Pick new midpoint - midpoint = (left + right) >> 1; - - // Compare filename with entry QR points to - p = (int)(entries + (midpoint != 0 ? BitConverter.ToUInt16(chunk, (int)(start - (midpoint << 1))) : 0)); - - // READ_ENCINT(nameLen) - { - (nameLen) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Reached end of chunk data while searching"); - return -1; - } - - (nameLen) = (uint)(((nameLen) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - if (nameLen > (uint)(end - p)) - { - Console.WriteLine("reached end of chunk data while searching"); - return -1; - } - - cmp = string.Compare(filename, Encoding.ASCII.GetString(chunk, p, (int)nameLen), StringComparison.OrdinalIgnoreCase); - - if (cmp == 0) - { - break; - } - else if (cmp < 0) - { - if (midpoint != 0) - right = midpoint - 1; - else - return 0; - } - else if (cmp > 0) - { - left = midpoint + 1; - } - } while (left <= right); - - midpoint = (left + right) >> 1; - - if (cmp == 0) - { - // Exact match! - p += (int)nameLen; - result = p; - return 1; - } - - // Otherwise, read the group of entries for QR entry M - p = (int)(entries + (midpoint != 0 ? BitConverter.ToUInt16(chunk, (int)(start - (midpoint << 1))) : 0)); - numEntries -= (ushort)(midpoint * qrDensity); - if (numEntries > qrDensity) - numEntries = (ushort)qrDensity; - } - else - { - p = (int)entries; - } - - // Step 2: linear search through the set of entries reached in step 1. - // - filename == any entry - // found entry - // - filename < all entries (PMGI) or any entry (PMGL) - // entry not found, stop now - // - filename > all entries - // entry not found (PMGL) / maybe found (PMGI) - result = -1; - while (numEntries-- > 0) - { - // READ_ENCINT(nameLen) - { - (nameLen) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Reached end of chunk data while searching"); - return -1; - } - - (nameLen) = (uint)(((nameLen) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - - if (nameLen > (uint)(end - p)) - { - Console.WriteLine("reached end of chunk data while searching"); - return -1; - } - - cmp = string.Compare(filename, Encoding.ASCII.GetString(chunk, p, (int)nameLen), StringComparison.OrdinalIgnoreCase); - p += (int)nameLen; - - if (cmp == 0) - { - // Entry found - result = p; - return 1; - } - - if (cmp < 0) - { - // Entry not found (PMGL) / maybe found (PMGI) - break; - } - - // Read and ignore the rest of this entry - if (pmgHeader.IsPMGL()) - { - // Skip section, offset, and length - for (int i = 0; i < 3; i++) - { - // READ_ENCINT(R) - right = 0; - do - { - if (p >= end) - { - Console.WriteLine("reached end of chunk data while searching"); - return -1; - } - - right = (uint)((right << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - } - else - { - result = p; // Store potential final result - - // Skip chunk number - - // READ_ENCINT(right) - { - (right) = 0; - do - { - if (p >= end) - { - Console.WriteLine("Reached end of chunk data while searching"); - return -1; - } - - (right) = (uint)(((right) << 7) | (chunk[p++] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - } - } - - // PMGL? not found. PMGI? maybe found - return (pmgHeader.IsPMGL()) ? 0 : (result != 0 ? 1 : 0); - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/Enums.cs b/BurnOutSharp/External/libmspack/CHM/Enums.cs deleted file mode 100644 index a0f400f0..00000000 --- a/BurnOutSharp/External/libmspack/CHM/Enums.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.CHM -{ - public enum Parameters - { - /// - /// Sets the "timestamp" of the CHM file - /// generated. This is not a timestamp, see mschmd_header::timestamp - /// for a description. If this timestamp is 0, generate() will use its - /// own algorithm for making a unique ID, based on the lengths and - /// names of files in the CHM itself. Defaults to 0, any value between - /// 0 and (2^32)-1 is valid. - /// - MSCHMC_PARAM_TIMESTAMP = 0, - - /// - /// Sets the "language" of the CHM file - /// generated. This is not the language used in the CHM file, but the - /// language setting of the user who ran the HTMLHelp compiler. It - /// defaults to 0x0409. The valid range is between 0x0000 and 0x7F7F. - /// - MSCHMC_PARAM_LANGUAGE = 1, - - /// - /// Sets the size of the LZX history window, - /// which is also the interval at which the compressed data stream can be - /// randomly accessed. The value is not a size in bytes, but a power of - /// two. The default value is 16 (which makes the window 2^16 bytes, or - /// 64 kilobytes), the valid range is from 15 (32 kilobytes) to 21 (2 - /// megabytes). - /// - MSCHMC_PARAM_LZXWINDOW = 2, - - /// - /// Sets the "density" of quick reference - /// entries stored at the end of directory listing chunk. Each chunk is - /// 4096 bytes in size, and contains as many file entries as there is - /// room for. At the other end of the chunk, a list of "quick reference" - /// pointers is included. The offset of every 'N'th file entry is given a - /// quick reference, where N = (2 ^ density) + 1.The default density is - /// 2. The smallest density is 0 (N = 2), the maximum is 10 (N = 1025). As - /// each file entry requires at least 5 bytes, the maximum number of - /// entries in a single chunk is roughly 800, so the maximum value 10 - /// can be used to indicate there are no quickrefs at all. - /// - MSCHMC_PARAM_DENSITY = 3, - - /// - /// Sets whether or not to include quick lookup - /// index chunk(s), in addition to normal directory listing chunks. A - /// value of zero means no index chunks will be created, a non-zero value - /// means index chunks will be created. The default is zero, "don't - /// create an index". - /// - MSCHMC_PARAM_INDEX = 4, - } - - public enum SectionType - { - /// - /// end of CHM file list - /// - MSCHMC_ENDLIST = 0, - - /// - /// this file is in the Uncompressed section - /// - MSCHMC_UNCOMP = 1, - - /// - /// this file is in the MSCompressed section - /// - MSCHMC_MSCOMP = 2, - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/MSCompressedSection.cs b/BurnOutSharp/External/libmspack/CHM/MSCompressedSection.cs deleted file mode 100644 index f5d43bb9..00000000 --- a/BurnOutSharp/External/libmspack/CHM/MSCompressedSection.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CHM -{ - /// - /// A structure which represents the LZX compressed section of a CHM helpfile. - /// - /// All fields are READ ONLY. - /// - public class MSCompressedSection : Section - { - /// - /// A pointer to the meta-file which represents all LZX compressed data. - /// - public DecompressFile Content { get; set; } - - /// - /// A pointer to the file which contains the LZX control data. - /// - public DecompressFile Control { get; set; } - - /// - /// A pointer to the file which contains the LZX reset table. - /// - public DecompressFile ResetTable { get; set; } - - /// - /// A pointer to the file which contains the LZX span information. - /// Available only in CHM decoder version 2 and above. - /// - public DecompressFile SpanInfo { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/Section.cs b/BurnOutSharp/External/libmspack/CHM/Section.cs deleted file mode 100644 index 80f99a1c..00000000 --- a/BurnOutSharp/External/libmspack/CHM/Section.cs +++ /dev/null @@ -1,41 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CHM -{ - /// - /// A structure which represents a section of a CHM helpfile. - /// - /// All fields are READ ONLY. - /// - /// Not used directly, but used as a generic base type for - /// mschmd_sec_uncompressed and mschmd_sec_mscompressed. - /// - public class Section - { - /// - /// A pointer to the CHM helpfile that contains this section. - /// - public CHM Header { get; set; } - - /// - /// The section ID. Either 0 for the uncompressed section - /// mschmd_sec_uncompressed, or 1 for the LZX compressed section - /// mschmd_sec_mscompressed. No other section IDs are known. - /// - public uint ID { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/UncompressedSection.cs b/BurnOutSharp/External/libmspack/CHM/UncompressedSection.cs deleted file mode 100644 index 9138cd99..00000000 --- a/BurnOutSharp/External/libmspack/CHM/UncompressedSection.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.CHM -{ - /// - /// A structure which represents the uncompressed section of a CHM helpfile. - /// - /// All fields are READ ONLY. - /// - public class UncompressedSection : Section - { - /// - /// The file offset of where this section begins in the CHM helpfile. - /// - public long Offset { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/_CHMHeader.cs b/BurnOutSharp/External/libmspack/CHM/_CHMHeader.cs deleted file mode 100644 index d46af784..00000000 --- a/BurnOutSharp/External/libmspack/CHM/_CHMHeader.cs +++ /dev/null @@ -1,118 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CHM -{ - internal class _CHMHeader - { - #region Fields - - /// - /// "ITSF" - /// - /// 0x0000 - public uint Signature { get; private set; } - - /// - /// The version of the CHM file format used in this file. - /// - /// 0x0004 - public uint Version { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0008 - public uint HeaderLen { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x000C - public uint Unknown1 { get; private set; } - - /// - /// The "timestamp" of the CHM helpfile. - /// - /// - /// 0x0010 - /// - /// It is the lower 32 bits of a 64-bit value representing the number of - /// centiseconds since 1601-01-01 00:00:00 UTC, plus 42. It is not useful - /// as a timestamp, but it is useful as a semi-unique ID. - /// - public uint Timestamp { get; private set; } - - /// - /// The default Language and Country ID (LCID) of the user who ran the - /// HTMLHelp Compiler. This is not the language of the CHM file itself. - /// - /// 0x0014 - public uint LanguageID { get; private set; } - - /// - /// Header GUID 1 - /// - /// 0x0018 - public Guid GUID1 { get; private set; } - - /// - /// Header GUID 2 - /// - /// 0x0028 - public Guid GUID2 { get; private set; } - - /// - /// Total size of the CHM header in bytes - /// - public const int Size = 0x0038; - - #endregion - - /// - /// Private constructor - /// - private _CHMHeader() { } - - /// - /// Create a _CHMHeader from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _CHMHeader header) - { - header = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - header = new _CHMHeader(); - - header.Signature = BitConverter.ToUInt32(buffer, 0x0000); - if (header.Signature != 0x46535449) - return Error.MSPACK_ERR_SIGNATURE; - - // Expect version less than or equal to 3, but don't validate - header.Version = BitConverter.ToUInt32(buffer, 0x0004); - header.HeaderLen = BitConverter.ToUInt32(buffer, 0x0008); - header.Unknown1 = BitConverter.ToUInt32(buffer, 0x000C); - header.Timestamp = BitConverter.ToUInt32(buffer, 0x0010); - header.LanguageID = BitConverter.ToUInt32(buffer, 0x0014); - - header.GUID1 = new Guid(new ReadOnlySpan(buffer, 0x0018, 0x10).ToArray()); - if (header.GUID1 != Guid.Parse("7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC")) - return Error.MSPACK_ERR_SIGNATURE; - - header.GUID2 = new Guid(new ReadOnlySpan(buffer, 0x0028, 0x10).ToArray()); - if (header.GUID2 != Guid.Parse("7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC")) - return Error.MSPACK_ERR_SIGNATURE; - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/_HeaderSection0.cs b/BurnOutSharp/External/libmspack/CHM/_HeaderSection0.cs deleted file mode 100644 index 238a4cb1..00000000 --- a/BurnOutSharp/External/libmspack/CHM/_HeaderSection0.cs +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CHM -{ - internal class _HeaderSection0 - { - #region Fields - - /// - /// UNKNOWN - /// - /// 0x0000 - public uint Unknown1 { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0004 - public uint Unknown2 { get; private set; } - - /// - /// The length of the CHM helpfile, in bytes. - /// - /// 0x0008 - public long FileLength { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0010 - public uint Unknown3 { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0014 - public uint Unknown4 { get; private set; } - - /// - /// Total size of the header section 0 in bytes - /// - public const int Size = 0x0018; - - #endregion - - /// - /// Private constructor - /// - private _HeaderSection0() { } - - /// - /// Create a _HeaderSection0 from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _HeaderSection0 headerSection) - { - headerSection = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - headerSection = new _HeaderSection0(); - - headerSection.Unknown1 = BitConverter.ToUInt32(buffer, 0x0000); - headerSection.Unknown2 = BitConverter.ToUInt32(buffer, 0x0004); - headerSection.FileLength = BitConverter.ToInt64(buffer, 0x0008); - - // TODO: Is this supposed to be <= 0? - if (headerSection.FileLength != 0) - return Error.MSPACK_ERR_DATAFORMAT; - - headerSection.Unknown3 = BitConverter.ToUInt32(buffer, 0x0010); - headerSection.Unknown4 = BitConverter.ToUInt32(buffer, 0x0014); - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/_HeaderSection1.cs b/BurnOutSharp/External/libmspack/CHM/_HeaderSection1.cs deleted file mode 100644 index bb810b06..00000000 --- a/BurnOutSharp/External/libmspack/CHM/_HeaderSection1.cs +++ /dev/null @@ -1,184 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CHM -{ - internal class _HeaderSection1 - { - #region Fields - - /// - /// UNKNOWN - /// - /// 0x0000 - public uint Signature { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0004 - public uint Version { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0008 - public uint HeaderLen { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x000C - public uint Unknown1 { get; private set; } - - /// - /// The size of each PMGL/PMGI chunk, in bytes. - /// - /// 0x0010 - public uint ChunkSize { get; private set; } - - /// - /// The "density" of the quick-reference section in PMGL/PMGI chunks. - /// - /// 0x0014 - public uint Density { get; private set; } - - /// - /// The depth of the index tree. - /// - /// - /// 0x0018 - /// - /// - if 1, there are no PMGI chunks, only PMGL chunks. - /// - if 2, there is 1 PMGI chunk. All chunk indices point to PMGL chunks. - /// - if 3, the root PMGI chunk points to secondary PMGI chunks, which in turn point to PMGL chunks. - /// - and so on... - /// - public uint Depth { get; private set; } - - /// - /// The number of the root PMGI chunk. - /// - /// - /// 0x001C - /// - /// If there is no index in the CHM helpfile, this will be 0xFFFFFFFF. - /// - public uint IndexRoot { get; private set; } - - /// - /// The number of the first PMGL chunk. Usually zero. - /// Available only in CHM decoder version 2 and above. - /// - /// 0x0020 - public uint FirstPMGL { get; private set; } - - /// - /// The number of the last PMGL chunk. Usually num_chunks-1. - /// Available only in CHM decoder version 2 and above. - /// - /// 0x0024 - public uint LastPMGL { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0028 - public uint Unknown2 { get; private set; } - - /// - /// The number of PMGL/PMGI directory chunks in this CHM helpfile. - /// - /// 0x002C - public uint NumChunks { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0030 - public uint LanguageID { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0034 - public Guid GUID { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0044 - public uint Unknown3 { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0048 - public uint Unknown4 { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x004C - public uint Unknown5 { get; private set; } - - /// - /// UNKNOWN - /// - /// 0x0050 - public uint Unknown6 { get; private set; } - - /// - /// Total size of the header section 1 in bytes - /// - public const int Size = 0x0054; - - #endregion - - /// - /// Private constructor - /// - private _HeaderSection1() { } - - /// - /// Create a _HeaderSection1 from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _HeaderSection1 headerSection) - { - headerSection = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - headerSection = new _HeaderSection1(); - - headerSection.Signature = BitConverter.ToUInt32(buffer, 0x0000); - headerSection.Version = BitConverter.ToUInt32(buffer, 0x0004); - headerSection.HeaderLen = BitConverter.ToUInt32(buffer, 0x0008); - headerSection.Unknown1 = BitConverter.ToUInt32(buffer, 0x000C); - headerSection.ChunkSize = BitConverter.ToUInt32(buffer, 0x0010); - headerSection.Density = BitConverter.ToUInt32(buffer, 0x0014); - headerSection.Depth = BitConverter.ToUInt32(buffer, 0x0018); - headerSection.IndexRoot = BitConverter.ToUInt32(buffer, 0x001C); - headerSection.FirstPMGL = BitConverter.ToUInt32(buffer, 0x0020); - headerSection.LastPMGL = BitConverter.ToUInt32(buffer, 0x0024); - headerSection.Unknown2 = BitConverter.ToUInt32(buffer, 0x0028); - headerSection.NumChunks = BitConverter.ToUInt32(buffer, 0x002C); - headerSection.LanguageID = BitConverter.ToUInt32(buffer, 0x0030); - headerSection.GUID = new Guid(new ReadOnlySpan(buffer, 0x0034, 0x10).ToArray()); - headerSection.Unknown3 = BitConverter.ToUInt32(buffer, 0x0044); - headerSection.Unknown4 = BitConverter.ToUInt32(buffer, 0x0048); - headerSection.Unknown5 = BitConverter.ToUInt32(buffer, 0x004C); - headerSection.Unknown6 = BitConverter.ToUInt32(buffer, 0x0050); - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/_HeaderSectionTable.cs b/BurnOutSharp/External/libmspack/CHM/_HeaderSectionTable.cs deleted file mode 100644 index 824c932b..00000000 --- a/BurnOutSharp/External/libmspack/CHM/_HeaderSectionTable.cs +++ /dev/null @@ -1,104 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CHM -{ - internal class _HeaderSectionTable - { - #region Regular Table - - /// - /// Header section 0 offset - /// - /// 0x0000 - public long OffsetHS0 { get; private set; } - - /// - /// Header section 0 length - /// - /// 0x0008 - public long LengthHS0 { get; private set; } - - /// - /// Header section 1 offset - /// The file offset of the first PMGL/PMGI directory chunk. - /// - /// - /// 0x0010 - /// - /// This is internally settable because it has to be corrected in some cases - /// - public long OffsetHS1 { get; internal set; } - - /// - /// Header section 1 length - /// - /// 0x0018 - public long LengthHS1 { get; private set; } - - /// - /// Total size of the version 1 and 2 header section table in bytes - /// - public const int Size = 0x0020; - - #endregion - - #region Version 3 Table - - /// - /// Header section 0 offset correct - /// - /// 0x0020 - public long OffsetCS0 { get; private set; } - - /// - /// Total size of the version 3 header section table in bytes - /// - public const int V3Size = 0x0028; - - #endregion - - /// - /// Private constructor - /// - private _HeaderSectionTable() { } - - /// - /// Create a _HeaderSectionTable from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _HeaderSectionTable headerSectionTable) - { - headerSectionTable = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - headerSectionTable = new _HeaderSectionTable(); - - headerSectionTable.OffsetHS0 = BitConverter.ToInt64(buffer, 0x0000); - headerSectionTable.LengthHS0 = BitConverter.ToInt64(buffer, 0x0008); - headerSectionTable.OffsetHS1 = BitConverter.ToInt64(buffer, 0x0010); - headerSectionTable.LengthHS1 = BitConverter.ToInt64(buffer, 0x0018); - - if (buffer.Length >= V3Size) - { - headerSectionTable.OffsetCS0 = BitConverter.ToInt64(buffer, 0x0020); - } - - // OffsetCS0 does not exist in version 1 or 2 CHM files. - // The offset will be corrected later, once HS1 is read. - // TODO: Are these supposed to be == 0? - if (headerSectionTable.OffsetHS0 != 0 || headerSectionTable.OffsetHS1 != 0 || headerSectionTable.OffsetCS0 != 0) - return Error.MSPACK_ERR_DATAFORMAT; - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/_LZXControlData.cs b/BurnOutSharp/External/libmspack/CHM/_LZXControlData.cs deleted file mode 100644 index c8f3ed09..00000000 --- a/BurnOutSharp/External/libmspack/CHM/_LZXControlData.cs +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.CHM -{ - internal class _LZXControlData - { - #region Fields - - /// - /// Length of the control data - /// - /// 0x0000 - public uint Length { get; private set; } - - /// - /// "LZXC" - /// - /// 0x0004 - public uint Signature { get; private set; } - - /// - /// Control data version - /// - /// 0x0008 - public uint Version { get; private set; } - - /// - /// Reset interval - /// - /// 0x000C - public uint ResetInterval { get; private set; } - - /// - /// Window size - /// - /// 0x0010 - public uint WindowSize { get; private set; } - - /// - /// Cache size - /// - /// 0x0014 - public uint CacheSize { get; private set; } - - /// - /// Cache size - /// - /// 0x0018 - public uint Unknown1 { get; private set; } - - /// - /// Total size of the LZX control data in bytes - /// - public const int Size = 0x001C; - - #endregion - - /// - /// Private constructor - /// - private _LZXControlData() { } - - /// - /// Create a _LZXControlData from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _LZXControlData controlData) - { - controlData = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - controlData = new _LZXControlData(); - - controlData.Length = BitConverter.ToUInt32(buffer, 0x0000); - controlData.Signature = BitConverter.ToUInt32(buffer, 0x0004); - if (controlData.Signature != 0x43585A4C) - return Error.MSPACK_ERR_SIGNATURE; - - controlData.Version = BitConverter.ToUInt32(buffer, 0x0008); - switch (controlData.Version) - { - case 1: - controlData.ResetInterval = BitConverter.ToUInt32(buffer, 0x000C); - controlData.WindowSize = BitConverter.ToUInt32(buffer, 0x0010); - break; - case 2: - controlData.ResetInterval = BitConverter.ToUInt32(buffer, 0x000C) * LZX_FRAME_SIZE; - controlData.WindowSize = BitConverter.ToUInt32(buffer, 0x0010) * LZX_FRAME_SIZE; - break; - default: - return Error.MSPACK_ERR_DATAFORMAT; - } - - controlData.CacheSize = BitConverter.ToUInt32(buffer, 0x0014); - controlData.Unknown1 = BitConverter.ToUInt32(buffer, 0x0018); - - return Error.MSPACK_ERR_OK; - } - - /// - /// Get the number of bits in the window based on the window size - /// - /// Window - /// An error code or MSPACK_ERR_OK if all is good - public Error GetWindowBits(out int windowBits) - { - switch (WindowSize) - { - case 0x008000: - windowBits = 15; - break; - - case 0x010000: - windowBits = 16; - break; - - case 0x020000: - windowBits = 17; - break; - - case 0x040000: - windowBits = 18; - break; - - case 0x080000: - windowBits = 19; - break; - - case 0x100000: - windowBits = 20; - break; - - case 0x200000: - windowBits = 21; - break; - - default: - windowBits = -1; - return Error.MSPACK_ERR_DATAFORMAT; - } - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/_LZXResetTable.cs b/BurnOutSharp/External/libmspack/CHM/_LZXResetTable.cs deleted file mode 100644 index 22495dc3..00000000 --- a/BurnOutSharp/External/libmspack/CHM/_LZXResetTable.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CHM -{ - internal class _LZXResetTable - { - #region Fields - - /// - /// UNKNOWN - /// - /// 0x0000 - public uint Unknown1 { get; private set; } - - /// - /// Number of entries in the table - /// - /// 0x0004 - public uint NumEntries { get; private set; } - - /// - /// Size of each entry - /// - /// 0x0008 - public uint EntrySize { get; private set; } - - /// - /// Table offset - /// - /// 0x000C - public uint TableOffset { get; private set; } - - /// - /// Uncompressed length - /// - /// 0x0010 - public long UncompressedLength { get; private set; } - - /// - /// Compressed length - /// - /// 0x0018 - public long CompressedLength { get; private set; } - - /// - /// Frame length - /// - /// 0x0020 - public long FrameLength { get; private set; } - - /// - /// Total size of the LZX reset table in bytes - /// - public const int Size = 0x0028; - - #endregion - - /// - /// Private constructor - /// - private _LZXResetTable() { } - - /// - /// Create a _LZXControlData from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _LZXResetTable resetTable) - { - resetTable = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - resetTable = new _LZXResetTable(); - - resetTable.Unknown1 = BitConverter.ToUInt32(buffer, 0x0000); - resetTable.NumEntries = BitConverter.ToUInt32(buffer, 0x0004); - resetTable.EntrySize = BitConverter.ToUInt32(buffer, 0x0008); - resetTable.TableOffset = BitConverter.ToUInt32(buffer, 0x000C); - resetTable.UncompressedLength = BitConverter.ToInt64(buffer, 0x0010); - resetTable.CompressedLength = BitConverter.ToInt64(buffer, 0x0018); - resetTable.FrameLength = BitConverter.ToInt64(buffer, 0x0020); - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/CHM/_PMGHeader.cs b/BurnOutSharp/External/libmspack/CHM/_PMGHeader.cs deleted file mode 100644 index 22f4489b..00000000 --- a/BurnOutSharp/External/libmspack/CHM/_PMGHeader.cs +++ /dev/null @@ -1,118 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.CHM -{ - internal class _PMGHeader - { - #region Fields - - /// - /// "PMGL" or "PMGI" - /// - /// 0x0000 - public uint Signature { get; private set; } - - /// - /// Quick reference size - /// - /// 0x0004 - public uint QuickRefSize { get; private set; } - - /// - /// Number of entries in a PMGI chunk - /// - /// - /// 0x0008 - /// - /// Unused in PMGL - /// - public uint PMGIEntries { get; private set; } - - /// - /// Previous chunk ID - /// - /// - /// 0x000C - /// - /// Does not exist in PMGI - /// - public uint PrevChunk { get; private set; } - - /// - /// Next chunk ID - /// - /// - /// 0x0010 - /// - /// Does not exist in PMGI - /// - public uint NextChunk { get; private set; } - - /// - /// Number of entries in a PMGL chunk - /// - /// - /// 0x0014 - /// - /// Does not exist in PMGI - /// - public uint PMGLEntries { get; private set; } - - /// - /// Total size of the PMGI header in bytes - /// - public const int PMGISize = 0x000C; - - /// - /// Total size of the PMGL header in bytes - /// - public const int PMGLSize = 0x0014; - - #endregion - - /// - /// Private constructor - /// - private _PMGHeader() { } - - /// - /// Create a _PMGHeader from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _PMGHeader header) - { - header = null; - if (buffer == null || buffer.Length < PMGISize) - return Error.MSPACK_ERR_READ; - - header = new _PMGHeader(); - - header.Signature = BitConverter.ToUInt32(buffer, 0x0000); - header.QuickRefSize = BitConverter.ToUInt32(buffer, 0x0004); - header.PMGIEntries = BitConverter.ToUInt32(buffer, 0x0008); - - if (buffer.Length >= PMGLSize) - { - header.PrevChunk = BitConverter.ToUInt32(buffer, 0x000C); - header.NextChunk = BitConverter.ToUInt32(buffer, 0x0010); - header.PMGLEntries = BitConverter.ToUInt32(buffer, 0x0014); - } - - return Error.MSPACK_ERR_OK; - } - - /// - /// Determines if a PMG chunk is PMGL or PMGI - /// - /// True for PMGL and false of PMGI - public bool IsPMGL() => Signature == 0x4C474D50; - } -} diff --git a/BurnOutSharp/External/libmspack/Checksum.cs b/BurnOutSharp/External/libmspack/Checksum.cs deleted file mode 100644 index 3095525b..00000000 --- a/BurnOutSharp/External/libmspack/Checksum.cs +++ /dev/null @@ -1,111 +0,0 @@ -/* - * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or - * code or tables extracted from it, as desired without restriction. - * - * First, the polynomial itself and its table of feedback terms. The - * polynomial is - * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 - * - * Note that we take it "backwards" and put the highest-order term in - * the lowest-order bit. The X^32 term is "implied"; the LSB is the - * X^31 term, etc. The X^0 term (usually shown as "+1") results in - * the MSB being 1 - * - * Note that the usual hardware shift register implementation, which - * is what we're using (we're merely optimizing it by doing eight-bit - * chunks at a time) shifts bits into the lowest-order term. In our - * implementation, that means shifting towards the right. Why do we - * do it this way? Because the calculated CRC must be transmitted in - * order from highest-order term to lowest-order term. UARTs transmit - * characters in order from LSB to MSB. By storing the CRC this way - * we hand it to the UART in the order low-byte to high-byte; the UART - * sends each low-bit to hight-bit; and the result is transmission bit - * by bit from highest- to lowest-order term without requiring any bit - * shuffling on our part. Reception works similarly - * - * The feedback terms table consists of 256, 32-bit entries. Notes - * - * The table can be generated at runtime if desired; code to do so - * is shown later. It might not be obvious, but the feedback - * terms simply represent the results of eight shift/xor opera - * tions for all combinations of data and CRC register values - * - * The values must be right-shifted by eight bits by the "updcrc - * logic; the shift must be unsigned (bring in zeroes). On some - * hardware you could probably optimize the shift in assembler by - * using byte-swap instructions - * polynomial $edb88320 - */ - -namespace LibMSPackSharp -{ - public class Checksum - { - public static readonly uint[] CRC32Table = new uint[256] - { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d - }; - - /// - /// Return a 32-bit CRC of the contents of the buffer. - /// - public static uint CRC32(byte[] ss, int pointer, int len, uint val) - { - while (--len >= 0) - val = CRC32Table[(val ^ ss[pointer++]) & 0xff] ^ (val >> 8); - - return val; - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadBits.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadBits.cs deleted file mode 100644 index d86816c0..00000000 --- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadBits.cs +++ /dev/null @@ -1,294 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2013 Stuart Caie. - * - * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted - * by Microsoft Corporation. - * - * libmspack is free software { get; set; } you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; -using System.Linq; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - /* This header defines macros that read data streams by - * the individual bits - * - * INIT_BITS initialises bitstream state in state structure - * STORE_BITS stores bitstream state in state structure - * RESTORE_BITS restores bitstream state from state structure - * ENSURE_BITS(n) ensure there are at least N bits in the bit buffer - * READ_BITS(var,n) takes N bits from the buffer and puts them in var - * PEEK_BITS(n) extracts without removing N bits from the bit buffer - * REMOVE_BITS(n) removes N bits from the bit buffer - * - * READ_BITS simply calls ENSURE_BITS, PEEK_BITS and REMOVE_BITS, - * which means it's limited to reading the number of bits you can - * ensure at any one time. It also fails if asked to read zero bits. - * If you need to read zero bits, or more bits than can be ensured in - * one go, use READ_MANY_BITS instead. - * - * These macros have variable names baked into them, so to use them - * you have to define some macros: - * - BITS_TYPE: the type name of your state structure - * - BITS_VAR: the variable that points to your state structure - * - define BITS_ORDER_MSB if bits are read from the MSB, or - * define BITS_ORDER_LSB if bits are read from the LSB - * - READ_BYTES: some code that reads more data into the bit buffer, - * it should use READ_IF_NEEDED (calls read_input if the byte buffer - * is empty), then INJECT_BITS(data,n) to put data from the byte - * buffer into the bit buffer. - * - * You also need to define some variables and structure members: - * - byte[] i_ptr; // current position in the byte buffer - * - byte[] i_end; // end of the byte buffer - * - uint bit_buffer; // the bit buffer itself - * - uint bits_left; // number of bits remaining - * - * If you use read_input() and READ_IF_NEEDED, they also expect these - * structure members: - * - struct mspack_system *sys; // to access sys->read() - * - uint error; // to record/return read errors - * - byte input_end; // to mark reaching the EOF - * - byte[] inbuf; // the input byte buffer - * - uint inbuf_size; // the size of the input byte buffer - * - * Your READ_BYTES implementation should read data from *i_ptr and - * put them in the bit buffer. READ_IF_NEEDED will call read_input() - * if i_ptr reaches i_end, and will fill up inbuf and set i_ptr to - * the start of inbuf and i_end to the end of inbuf. - * - * If you're reading in MSB order, the routines work by using the area - * beyond the MSB and the LSB of the bit buffer as a free source of - * zeroes when shifting. This avoids having to mask any bits. So we - * have to know the bit width of the bit buffer variable. We use - * and CHAR_BIT to find the size of the bit buffer in bits. - * - * If you are reading in LSB order, bits need to be masked. Normally - * this is done by computing the mask: N bits are masked by the value - * (1< - /// Initialises bitstream state in state structure - /// - public void INIT_BITS() - { - InputPointer = 0; - InputEnd = 0; - BitBuffer = 0; - BitsLeft = 0; - EndOfInput = 0; - } - - /// - /// Ensure there are at least N bits in the bit buffer - /// - public void ENSURE_BITS(int nbits) - { - while (BitsLeft < nbits) - { - READ_BYTES(); - if (Error != Error.MSPACK_ERR_OK) - return; - } - } - - /// - /// Read from the input if the buffer is empty - /// - public void READ_IF_NEEDED() - { - if (InputPointer >= InputEnd) - ReadInput(); - } - - /// - /// Read bytes from the input into the bit buffer - /// - public abstract void READ_BYTES(); - - /// - /// Read an input stream and fill the buffer - /// - protected virtual void ReadInput() - { - int read = System.Read(InputFileHandle, InputBuffer, 0, (int)InputBufferSize); - if (read < 0) - { - Error = Error.MSPACK_ERR_READ; - return; - } - - // We might overrun the input stream by asking for bits we don't use, - // so fake 2 more bytes at the end of input - if (read == 0) - { - if (EndOfInput > 0) - { - Console.WriteLine("Out of input bytes"); - Error = Error.MSPACK_ERR_READ; - return; - } - else - { - read = 2; - InputBuffer[0] = InputBuffer[1] = 0; - EndOfInput = 1; - } - } - - // Update i_ptr and i_end - InputPointer = 0; - InputEnd = read; - } - - #endregion - - #region MSB - - /// - /// Inject data into the bit buffer - /// - public void INJECT_BITS_MSB(int bitdata, int nbits) - { - BitBuffer |= ((uint)bitdata << (BITBUF_WIDTH - nbits - BitsLeft)); - BitsLeft += nbits; - } - - /// - /// Extracts without removing N bits from the bit buffer - /// - public long PEEK_BITS_MSB(int nbits) => (BitBuffer >> (BITBUF_WIDTH - (nbits))); - - /// - /// Takes N bits from the buffer and puts them in var - /// - public long READ_BITS_MSB(int nbits) - { - ENSURE_BITS(nbits); - if (Error != Error.MSPACK_ERR_OK) - return -1; - - long temp = PEEK_BITS_MSB(nbits); - - REMOVE_BITS_MSB(nbits); - return temp; - } - - /// - /// Read multiple bits and put them in var - /// - public long READ_MANY_BITS_MSB(int nbits) - { - byte needed = (byte)(nbits), bitrun; - long temp = 0; - while (needed > 0) - { - if (BitsLeft <= (BITBUF_WIDTH - 16)) - { - READ_BYTES(); - if (Error != Error.MSPACK_ERR_OK) - return -1; - } - - bitrun = (byte)((BitsLeft < needed) ? BitsLeft : needed); - temp = (temp << bitrun) | PEEK_BITS_MSB(bitrun); - REMOVE_BITS_MSB(bitrun); - needed -= bitrun; - } - - return temp; - } - - /// - /// Removes N bits from the bit buffer - /// - public void REMOVE_BITS_MSB(int nbits) - { - BitBuffer <<= nbits; - BitsLeft -= nbits; - } - - #endregion - - #region LSB - - /// - /// Inject data into the bit buffer - /// - public void INJECT_BITS_LSB(int bitdata, int nbits) - { - BitBuffer |= (uint)(bitdata << BitsLeft); - BitsLeft += nbits; - } - - /// - /// Extracts without removing N bits from the bit buffer - /// - public long PEEK_BITS_LSB(int nbits) => (BitBuffer & ((1 << (nbits)) - 1)); - - /// - /// Extracts without removing N bits from the bit buffer using a bit mask - /// - public long PEEK_BITS_T_LSB(int nbits) => BitBuffer & LSBBitMask[(nbits)]; - - /// - /// Takes N bits from the buffer and puts them in var - /// - public long READ_BITS_LSB(int nbits) - { - ENSURE_BITS(nbits); - if (Error != Error.MSPACK_ERR_OK) - return -1; - - long temp = PEEK_BITS_LSB(nbits); - - REMOVE_BITS_LSB(nbits); - return temp; - } - - /// - /// Takes N bits from the buffer and puts them in var using a bit mask - /// - public long READ_BITS_T_LSB(int nbits) - { - ENSURE_BITS(nbits); - if (Error != Error.MSPACK_ERR_OK) - return -1; - - long temp = PEEK_BITS_T_LSB(nbits); - - REMOVE_BITS_LSB(nbits); - return temp; - } - - /// - /// Removes N bits from the bit buffer - /// - public void REMOVE_BITS_LSB(int nbits) - { - BitBuffer >>= nbits; - BitsLeft -= nbits; - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadHuff.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadHuff.cs deleted file mode 100644 index c8ef39bc..00000000 --- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.ReadHuff.cs +++ /dev/null @@ -1,342 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2013 Stuart Caie. - * - * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted - * by Microsoft Corporation. - * - * libmspack is free software { get; set; } you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public abstract partial class CompressionStream : BaseDecompressState - { - #region Common - - /// - /// Per compression error code for decoding failure - /// - public abstract Error HUFF_ERROR(); - - #endregion - - #region MSB - - /// - /// Decodes the next huffman symbol from the input bitstream into var. - /// Do not use this macro on a table unless build_decode_table() succeeded. - /// - public long READ_HUFFSYM_MSB(ushort[] table, byte[] lengths, int tablebits, int maxsymbols) - { - ENSURE_BITS(HUFF_MAXBITS); - ushort sym = table[PEEK_BITS_MSB(tablebits)]; - if (sym >= maxsymbols) - HUFF_TRAVERSE_MSB(ref sym, table, tablebits, maxsymbols); - - REMOVE_BITS_MSB(lengths[sym]); - return sym; - } - - /// - /// Traverse for a single symbol - /// - private void HUFF_TRAVERSE_MSB(ref ushort sym, ushort[] table, int tablebits, int maxsymbols) - { - int i = 1 << (BITBUF_WIDTH - tablebits); - do - { - if ((i >>= 1) == 0) - { - Error = HUFF_ERROR(); - return; - } - - sym = table[(sym << 1) | ((BitBuffer & i) != 0 ? 1 : 0)]; - } while (sym >= maxsymbols); - } - - /// - /// This function was originally coded by David Tritscher. - /// - /// It builds a fast huffman decoding table from - /// a canonical huffman code lengths table. - /// - /// total number of symbols in this huffman tree. - /// any symbols with a code length of nbits or less can be decoded in one lookup of the table. - /// A table to get code lengths from [0 to nsyms-1] - /// - /// The table to fill up with decoded symbols and pointers. - /// Should be ((1< - /// True for OK or false for error - public static bool MakeDecodeTableMSB(int nsyms, int nbits, byte[] length, ushort[] table) - { - ushort sym, next_symbol; - long leaf, fill; - byte bit_num; - long pos = 0; // The current position in the decode table - long table_mask = 1 << nbits; - long bit_mask = table_mask >> 1; // Don't do 0 length codes - - // Fill entries for codes short enough for a direct mapping - for (bit_num = 1; bit_num <= nbits; bit_num++) - { - for (sym = 0; sym < nsyms; sym++) - { - if (length[sym] != bit_num) - continue; - - leaf = pos; - if ((pos += bit_mask) > table_mask) - return false; // Table overrun - - // Fill all possible lookups of this symbol with the symbol itself - for (fill = bit_mask; fill-- > 0;) - { - table[leaf++] = sym; - } - } - - bit_mask >>= 1; - } - - // Exit with success if table is now complete - if (pos == table_mask) - return true; - - // Mark all remaining table entries as unused - for (sym = (ushort)pos; sym < table_mask; sym++) - { - table[sym] = 0xFFFF; - } - - // next_symbol = base of allocation for long codes - next_symbol = (ushort)(((table_mask >> 1) < nsyms) ? nsyms : (table_mask >> 1)); - - // Give ourselves room for codes to grow by up to 16 more bits. - // codes now start at bit nbits+16 and end at (nbits+16-codelength) - pos <<= 16; - table_mask <<= 16; - bit_mask = 1 << 15; - - for (bit_num = (byte)(nbits + 1); bit_num <= HUFF_MAXBITS; bit_num++) - { - for (sym = 0; sym < nsyms; sym++) - { - if (length[sym] != bit_num) - continue; - if (pos >= table_mask) - return false; // Table overflow - - leaf = pos >> 16; - for (fill = 0; fill < (bit_num - nbits); fill++) - { - // If this path hasn't been taken yet, 'allocate' two entries - if (table[leaf] == 0xFFFF) - { - table[(next_symbol << 1)] = 0xFFFF; - table[(next_symbol << 1) + 1] = 0xFFFF; - table[leaf] = next_symbol++; - } - - // Follow the path and select either left or right for next bit - leaf = (uint)(table[leaf] << 1); - if (((pos >> (15 - (int)fill)) & 1) != 0) - leaf++; - } - - table[leaf] = sym; - pos += bit_mask; - } - - bit_mask >>= 1; - } - - // Full table? - return pos == table_mask; - } - - #endregion - - #region LSB - - /// - /// Decodes the next huffman symbol from the input bitstream into var. - /// Do not use this macro on a table unless build_decode_table() succeeded. - /// - public long READ_HUFFSYM_LSB(ushort[] table, byte[] lengths, int tablebits, int maxsymbols) - { - ENSURE_BITS(HUFF_MAXBITS); - ushort sym = table[PEEK_BITS_LSB(tablebits)]; - if (sym >= maxsymbols) - HUFF_TRAVERSE_LSB(ref sym, table, tablebits, maxsymbols); - - REMOVE_BITS_LSB(lengths[sym]); - return sym; - } - - /// - /// Traverse for a single symbol - /// - private void HUFF_TRAVERSE_LSB(ref ushort sym, ushort[] table, int tablebits, int maxsymbols) - { - int i = tablebits - 1; - do - { - if (i++ > HUFF_MAXBITS) - { - Error = HUFF_ERROR(); - return; - } - - sym = table[(sym << 1) | ((BitBuffer >> i) & 1)]; - } while (sym >= maxsymbols); - } - - /// - /// This function was originally coded by David Tritscher. - /// - /// It builds a fast huffman decoding table from - /// a canonical huffman code lengths table. - /// - /// total number of symbols in this huffman tree. - /// any symbols with a code length of nbits or less can be decoded in one lookup of the table. - /// A table to get code lengths from [0 to nsyms-1] - /// - /// The table to fill up with decoded symbols and pointers. - /// Should be ((1< - /// True for OK or false for error - public static bool MakeDecodeTableLSB(int nsyms, int nbits, byte[] length, ushort[] table) - { - ushort sym, next_symbol; - uint leaf, fill; - uint reverse; - byte bit_num; - uint pos = 0; // The current position in the decode table - uint table_mask = (uint)1 << nbits; - uint bit_mask = table_mask >> 1; // Don't do 0 length codes - - // Fill entries for codes short enough for a direct mapping - for (bit_num = 1; bit_num <= nbits; bit_num++) - { - for (sym = 0; sym < nsyms; sym++) - { - if (length[sym] != bit_num) - continue; - - // Reverse the significant bits - fill = length[sym]; - reverse = pos >> (int)(nbits - fill); - leaf = 0; - - do - { - leaf <<= 1; - leaf |= reverse & 1; - reverse >>= 1; - } while (--fill > 0); - - if ((pos += bit_mask) > table_mask) - return false; // Table overrun - - // Fill all possible lookups of this symbol with the symbol itself - fill = bit_mask; - next_symbol = (ushort)(1 << bit_num); - - do - { - table[leaf] = sym; - leaf += next_symbol; - } while (--fill > 0); - } - - bit_mask >>= 1; - } - - // Exit with success if table is now complete - if (pos == table_mask) - return true; - - // Mark all remaining table entries as unused - for (sym = (ushort)pos; sym < table_mask; sym++) - { - reverse = sym; - leaf = 0; - fill = (uint)nbits; - - do - { - leaf <<= 1; - leaf |= reverse & 1; - reverse >>= 1; - } while (--fill > 0); - - table[leaf] = 0xFFFF; - } - - // next_symbol = base of allocation for long codes - next_symbol = ((table_mask >> 1) < nsyms) ? (ushort)nsyms : (ushort)(table_mask >> 1); - - // Give ourselves room for codes to grow by up to 16 more bits. - // codes now start at bit nbits+16 and end at (nbits+16-codelength) - pos <<= 16; - table_mask <<= 16; - bit_mask = 1 << 15; - - for (bit_num = (byte)(nbits + 1); bit_num <= HUFF_MAXBITS; bit_num++) - { - for (sym = 0; sym < nsyms; sym++) - { - if (length[sym] != bit_num) - continue; - if (pos >= table_mask) - return false; // Table overflow - - // leaf = the first nbits of the code, reversed - reverse = pos >> 16; - leaf = 0; - fill = (uint)nbits; - - do - { - leaf <<= 1; - leaf |= reverse & 1; - reverse >>= 1; - } while (--fill > 0); - - for (fill = 0; fill < (bit_num - nbits); fill++) - { - // If this path hasn't been taken yet, 'allocate' two entries - if (table[leaf] == 0xFFFF) - { - table[(next_symbol << 1)] = 0xFFFF; - table[(next_symbol << 1) + 1] = 0xFFFF; - table[leaf] = (ushort)next_symbol++; - } - - // Follow the path and select either left or right for next bit - leaf = (uint)(table[leaf] << 1); - if (((pos >> (15 - (int)fill)) & 1) != 0) - leaf++; - } - - table[leaf] = sym; - pos += bit_mask; - } - - bit_mask >>= 1; - } - - // Full table? - return pos == table_mask; - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs deleted file mode 100644 index c26e200f..00000000 --- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2013 Stuart Caie. - * - * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted - * by Microsoft Corporation. - * - * libmspack is free software { get; set; } you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public abstract partial class CompressionStream : BaseDecompressState - { - public byte[] InputBuffer { get; set; } - - public uint InputBufferSize { get; set; } - - /// - /// i_ptr - /// - public int InputPointer { get; set; } - - /// - /// i_end - /// - public int InputEnd { get; set; } - - /// - /// o_ptr - /// - public int OutputPointer { get; set; } - - /// - /// o_end - /// - public int OutputEnd { get; set; } - - /// - /// bit_buffer - /// - public uint BitBuffer { get; set; } - - /// - /// bits_left - /// - public int BitsLeft { get; set; } - - /// - /// Have we reached the end of input? - /// - public int EndOfInput { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/Constants.cs b/BurnOutSharp/External/libmspack/Compression/Constants.cs deleted file mode 100644 index 5bec9141..00000000 --- a/BurnOutSharp/External/libmspack/Compression/Constants.cs +++ /dev/null @@ -1,281 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2010 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - internal static class Constants - { - #region readbits.h - - /// - /// Bit width of a UInt32 bit buffer - /// - public const int BITBUF_WIDTH = 4 * CHAR_BIT; - - /// - /// Number of bits in a character - /// - internal const int CHAR_BIT = 8; - - // lsb_bit_mask[n] = (1 << n) - 1 - internal static readonly ushort[] LSBBitMask = new ushort[17] - { - 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff - }; - - #endregion - - #region readhuff.h - - /// - /// Maximum bits in a Huffman code - /// - public const int HUFF_MAXBITS = 16; - - #endregion - - #region LZSS - - /// - /// Size of an LZSS window - /// - public const int LZSS_WINDOW_SIZE = 4096; - - /// - /// LZSS window fill byte - /// - public const byte LZSS_WINDOW_FILL = 0x20; - - #endregion - - #region LZX - - // Some constants defined by the LZX specification - public const int LZX_MIN_MATCH = 2; - public const int LZX_MAX_MATCH = 257; - public const int LZX_NUM_CHARS = 256; - - public const int LZX_PRETREE_NUM_ELEMENTS = 20; - public const int LZX_ALIGNED_NUM_ELEMENTS = 8; // Aligned offset tree #elements - public const int LZX_NUM_PRIMARY_LENGTHS = 7; // This one missing from spec! - public const int LZX_NUM_SECONDARY_LENGTHS = 249; // Length tree #elements - - // LZX huffman defines: tweak tablebits as desired - - public const int LZX_PRETREE_MAXSYMBOLS = LZX_PRETREE_NUM_ELEMENTS; - public const byte LZX_PRETREE_TABLEBITS = 6; - public const int LZX_MAINTREE_MAXSYMBOLS = LZX_NUM_CHARS + 290 * 8; - public const byte LZX_MAINTREE_TABLEBITS = 12; - public const int LZX_LENGTH_MAXSYMBOLS = LZX_NUM_SECONDARY_LENGTHS + 1; - public const byte LZX_LENGTH_TABLEBITS = 12; - public const int LZX_ALIGNED_MAXSYMBOLS = LZX_ALIGNED_NUM_ELEMENTS; - public const byte LZX_ALIGNED_TABLEBITS = 7; - public const int LZX_LENTABLE_SAFETY = 64; // Table decoding overruns are allowed - - public const int LZX_FRAME_SIZE = 32768; // The size of a frame in LZX - - #region LZX static data tables - - /// - /// LZX uses 'position slots' to represent match offsets. For every match, - /// a small 'position slot' number and a small offset from that slot are - /// encoded instead of one large offset. - /// - /// The number of slots is decided by how many are needed to encode the - /// largest offset for a given window size. This is easy when the gap between - /// slots is less than 128Kb, it's a linear relationship. But when extra_bits - /// reaches its limit of 17 (because LZX can only ensure reading 17 bits of - /// data at a time), we can only jump 128Kb at a time and have to start - /// using more and more position slots as each window size doubles. - /// - public static readonly uint[] LZXPositionSlots = new uint[11] - { - 30, 32, 34, 36, 38, 42, 50, 66, 98, 162, 290 - }; - - /// - /// An index to the position slot bases - /// - /// - /// Calculated as follows: - /// LZXPositionBase[0] = 0 - /// LZXPositionBase[i] = LZXPositionBase[i - 1] + (1 << ExtraBits(i - 1)) - /// - public static readonly uint[] LZXPositionBase = new uint[290] - { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, - 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, - 49152, 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360, - 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936, - 1835008, 1966080, 2097152, 2228224, 2359296, 2490368, 2621440, 2752512, - 2883584, 3014656, 3145728, 3276800, 3407872, 3538944, 3670016, 3801088, - 3932160, 4063232, 4194304, 4325376, 4456448, 4587520, 4718592, 4849664, - 4980736, 5111808, 5242880, 5373952, 5505024, 5636096, 5767168, 5898240, - 6029312, 6160384, 6291456, 6422528, 6553600, 6684672, 6815744, 6946816, - 7077888, 7208960, 7340032, 7471104, 7602176, 7733248, 7864320, 7995392, - 8126464, 8257536, 8388608, 8519680, 8650752, 8781824, 8912896, 9043968, - 9175040, 9306112, 9437184, 9568256, 9699328, 9830400, 9961472, 10092544, - 10223616, 10354688, 10485760, 10616832, 10747904, 10878976, 11010048, - 11141120, 11272192, 11403264, 11534336, 11665408, 11796480, 11927552, - 12058624, 12189696, 12320768, 12451840, 12582912, 12713984, 12845056, - 12976128, 13107200, 13238272, 13369344, 13500416, 13631488, 13762560, - 13893632, 14024704, 14155776, 14286848, 14417920, 14548992, 14680064, - 14811136, 14942208, 15073280, 15204352, 15335424, 15466496, 15597568, - 15728640, 15859712, 15990784, 16121856, 16252928, 16384000, 16515072, - 16646144, 16777216, 16908288, 17039360, 17170432, 17301504, 17432576, - 17563648, 17694720, 17825792, 17956864, 18087936, 18219008, 18350080, - 18481152, 18612224, 18743296, 18874368, 19005440, 19136512, 19267584, - 19398656, 19529728, 19660800, 19791872, 19922944, 20054016, 20185088, - 20316160, 20447232, 20578304, 20709376, 20840448, 20971520, 21102592, - 21233664, 21364736, 21495808, 21626880, 21757952, 21889024, 22020096, - 22151168, 22282240, 22413312, 22544384, 22675456, 22806528, 22937600, - 23068672, 23199744, 23330816, 23461888, 23592960, 23724032, 23855104, - 23986176, 24117248, 24248320, 24379392, 24510464, 24641536, 24772608, - 24903680, 25034752, 25165824, 25296896, 25427968, 25559040, 25690112, - 25821184, 25952256, 26083328, 26214400, 26345472, 26476544, 26607616, - 26738688, 26869760, 27000832, 27131904, 27262976, 27394048, 27525120, - 27656192, 27787264, 27918336, 28049408, 28180480, 28311552, 28442624, - 28573696, 28704768, 28835840, 28966912, 29097984, 29229056, 29360128, - 29491200, 29622272, 29753344, 29884416, 30015488, 30146560, 30277632, - 30408704, 30539776, 30670848, 30801920, 30932992, 31064064, 31195136, - 31326208, 31457280, 31588352, 31719424, 31850496, 31981568, 32112640, - 32243712, 32374784, 32505856, 32636928, 32768000, 32899072, 33030144, - 33161216, 33292288, 33423360 - }; - - #endregion - - #endregion - - #region MSZIP - - public const int MSZIP_FRAME_SIZE = 32768; // Size of LZ history window - public const int MSZIP_LITERAL_MAXSYMBOLS = 288; // literal/length huffman tree - public const int MSZIP_LITERAL_TABLEBITS = 9; - public const int MSZIP_DISTANCE_MAXSYMBOLS = 32; // Distance huffman tree - public const int MSZIP_DISTANCE_TABLEBITS = 6; - - // If there are less direct lookup entries than symbols, the longer - // code pointers will be <= maxsymbols. This must not happen, or we - // will decode entries badly - - //public const int MSZIP_LITERAL_TABLESIZE = (MSZIP_LITERAL_MAXSYMBOLS * 4); - public const int MSZIP_LITERAL_TABLESIZE = ((1 << MSZIP_LITERAL_TABLEBITS) + (MSZIP_LITERAL_MAXSYMBOLS * 2)); - - //public const int MSZIP_DISTANCE_TABLESIZE = (MSZIP_DISTANCE_MAXSYMBOLS * 4); - public const int MSZIP_DISTANCE_TABLESIZE = ((1 << MSZIP_DISTANCE_TABLEBITS) + (MSZIP_DISTANCE_MAXSYMBOLS * 2)); - - /// - /// Match lengths for literal codes 257.. 285 - /// - public static readonly ushort[] LiteralLengths = new ushort[29] - { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, - 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 - }; - - /// - /// Match offsets for distance codes 0 .. 29 - /// - public static readonly ushort[] DistanceOffsets = new ushort[30] - { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, - 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 - }; - - /// - /// Extra bits required for literal codes 257.. 285 - /// - public static readonly byte[] LiteralExtraBits = new byte[29] - { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, - 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 - }; - - /// - /// Extra bits required for distance codes 0 .. 29 - /// - public static readonly byte[] DistanceExtraBits = new byte[30] - { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, - 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 - }; - - /// - /// The order of the bit length Huffman code lengths - /// - public static readonly byte[] BitLengthOrder = new byte[19] - { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - - #endregion - - #region QTM - - public const int QTM_FRAME_SIZE = 32768; - - /* Quantum static data tables: - * - * Quantum uses 'position slots' to represent match offsets. For every - * match, a small 'position slot' number and a small offset from that slot - * are encoded instead of one large offset. - * - * position_base[] is an index to the position slot bases - * - * extra_bits[] states how many bits of offset-from-base data is needed. - * - * length_base[] and length_extra[] are equivalent in function, but are - * used for encoding selector 6 (variable length match) match lengths, - * instead of match offsets. - * - * They are generated with the following code: - * uint i, offset; - * for (i = 0, offset = 0; i < 42; i++) { - * position_base[i] = offset; - * extra_bits[i] = ((i < 2) ? 0 : (i - 2)) >> 1; - * offset += 1 << extra_bits[i]; - * } - * for (i = 0, offset = 0; i < 26; i++) { - * length_base[i] = offset; - * length_extra[i] = (i < 2 ? 0 : i - 2) >> 2; - * offset += 1 << length_extra[i]; - * } - * length_base[26] = 254; length_extra[26] = 0; - */ - - public static readonly uint[] QTMPositionBase = new uint[42] - { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, - 65536, 98304, 131072, 196608, 262144, 393216, 524288, 786432, 1048576, 1572864 - }; - - public static readonly byte[] QTMExtraBits = new byte[42] - { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, - 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19 - }; - - public static readonly byte[] QTMLengthBase = new byte[27] - { - 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 18, 22, 26, - 30, 38, 46, 54, 62, 78, 94, 110, 126, 158, 190, 222, 254 - }; - - public static readonly byte[] QTMLengthExtra = new byte[27] - { - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 - }; - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/DES.cs b/BurnOutSharp/External/libmspack/Compression/DES.cs deleted file mode 100644 index 384ac8c6..00000000 --- a/BurnOutSharp/External/libmspack/Compression/DES.cs +++ /dev/null @@ -1,15 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public class DES - { - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/Enums.cs b/BurnOutSharp/External/libmspack/Compression/Enums.cs deleted file mode 100644 index 5d6f57d0..00000000 --- a/BurnOutSharp/External/libmspack/Compression/Enums.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public enum LZSSMode - { - LZSS_MODE_EXPAND = 0, - - LZSS_MODE_MSHELP = 1, - - LZSS_MODE_QBASIC = 2, - } - - public enum LZXBlockType : byte - { - LZX_BLOCKTYPE_INVALID0 = 0, - - LZX_BLOCKTYPE_VERBATIM = 1, - - LZX_BLOCKTYPE_ALIGNED = 2, - - LZX_BLOCKTYPE_UNCOMPRESSED = 3, - - LZX_BLOCKTYPE_INVALID4 = 4, - - LZX_BLOCKTYPE_INVALID5 = 5, - - LZX_BLOCKTYPE_INVALID6 = 6, - - LZX_BLOCKTYPE_INVALID7 = 7, - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.Decompress.cs b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.Decompress.cs deleted file mode 100644 index 815c2923..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.Decompress.cs +++ /dev/null @@ -1,293 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2010 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System.IO; -using static LibMSPackSharp.Constants; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - /// - /// In the KWAJ LZH format, there is no special 'eof' marker, it just - /// ends. Depending on how many bits are left in the final byte when - /// the stream ends, that might be enough to start another literal or - /// match. The only easy way to detect that we've come to an end is to - /// guard all bit-reading. We allow fake bits to be read once we reach - /// the end of the stream, but we check if we then consumed any of - /// those fake bits, after doing the READ_BITS / READ_HUFFSYM. This - /// isn't how the default ReadInput works (it simply lets - /// 2 fake bytes in then stops), so we implement our own. - /// - public partial class LZHKWAJ - { - public static LZHKWAJ Init(SystemImpl sys, FileStream input, FileStream output) - { - if (sys == null || input == null || output == null) - return null; - - return new LZHKWAJ() - { - System = sys, - InputFileHandle = input, - OutputFileHandle = output, - }; - } - - public Error Decompress() - { - int i; - int lit_run = 0; - int j, pos = 0, len, offset; - uint[] types = new uint[6]; - - // Reset global state - INIT_BITS(); - - for (i = 0; i < LZSS_WINDOW_SIZE; i++) - { - Window[i] = LZSS_WINDOW_FILL; - } - - // Read 6 encoding types (for byte alignment) but only 5 are needed - for (i = 0; i < 6; i++) - { - types[i] = (uint)READ_BITS_SAFE(4); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - } - - // Read huffman table symbol lengths and build huffman trees - BUILD_TREE(types[0], MATCHLEN1_table, MATCHLEN1_len, KWAJ_TABLEBITS, KWAJ_MATCHLEN1_SYMS); - BUILD_TREE(types[1], MATCHLEN2_table, MATCHLEN2_len, KWAJ_TABLEBITS, KWAJ_MATCHLEN2_SYMS); - BUILD_TREE(types[2], LITLEN_table, LITLEN_len, KWAJ_TABLEBITS, KWAJ_LITLEN_SYMS); - BUILD_TREE(types[3], OFFSET_table, OFFSET_len, KWAJ_TABLEBITS, KWAJ_OFFSET_SYMS); - BUILD_TREE(types[4], LITERAL_table, LITERAL_len, KWAJ_TABLEBITS, KWAJ_LITERAL_SYMS); - - while (EndOfInput == 0) - { - if (lit_run > 0) - { - len = (int)READ_HUFFSYM_SAFE(MATCHLEN2_table, MATCHLEN2_len, KWAJ_MATCHLEN2_TBLSIZE, KWAJ_MATCHLEN2_SYMS); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - } - else - { - len = (int)READ_HUFFSYM_SAFE(MATCHLEN1_table, MATCHLEN1_len, KWAJ_MATCHLEN1_TBLSIZE, KWAJ_MATCHLEN1_SYMS); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - } - - if (len > 0) - { - len += 2; - lit_run = 0; // Not the end of a literal run - - j = (int)READ_HUFFSYM_SAFE(OFFSET_table, OFFSET_len, KWAJ_OFFSET_TBLSIZE, KWAJ_OFFSET_SYMS); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - offset = j << 6; - - j = (int)READ_BITS_SAFE(6); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - offset |= j; - - // Copy match as output and into the ring buffer - while (len-- > 0) - { - Window[pos] = Window[(pos + 4096 - offset) & 4095]; - WRITE_BYTE(pos); - if (Error != Error.MSPACK_ERR_OK) - return Error; - - pos++; - pos &= 4095; - } - } - else - { - len = (int)READ_HUFFSYM_SAFE(LITLEN_table, LITLEN_len, KWAJ_LITLEN_TBLSIZE, KWAJ_LITLEN_SYMS); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - len++; - lit_run = (len == 32) ? 0 : 1; // End of a literal run? - while (len-- > 0) - { - j = (int)READ_HUFFSYM_SAFE(LITERAL_table, LITERAL_len, KWAJ_LITERAL_TBLSIZE, KWAJ_LITERAL_SYMS); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - // Copy as output and into the ring buffer - Window[pos] = (byte)j; - - WRITE_BYTE(pos); - if (Error != Error.MSPACK_ERR_OK) - return Error; - - pos++; pos &= 4095; - } - } - } - - return Error.MSPACK_ERR_OK; - } - - private Error BUILD_TREE(uint type, ushort[] table, byte[] lengths, int tablebits, int maxsymbols) - { - Error err = ReadLens(type, (uint)maxsymbols, MATCHLEN1_len); - if (err != Error.MSPACK_ERR_OK) - return err; - - if (!CompressionStream.MakeDecodeTableMSB(maxsymbols, tablebits, lengths, table)) - return Error.MSPACK_ERR_DATAFORMAT; - - return Error.MSPACK_ERR_OK; - } - - /// - /// Safely read bits from the buffer - /// - private long READ_BITS_SAFE(int nbits) - { - long val = READ_BITS_MSB(nbits); - if (EndOfInput != 0 && BitsLeft < EndOfInput) - Error = Error.MSPACK_ERR_NOMEMORY; - else - Error = Error.MSPACK_ERR_OK; - - return val; - } - - /// - /// Safely read a symbol from a Huffman tree - /// - private long READ_HUFFSYM_SAFE(ushort[] table, byte[] lengths, int tablebits, int maxsymbols) - { - long val = READ_HUFFSYM_MSB(table, lengths, tablebits, maxsymbols); - if (EndOfInput != 0 && BitsLeft < EndOfInput) - Error = Error.MSPACK_ERR_NOMEMORY; - else - Error = Error.MSPACK_ERR_OK; - - return val; - } - - /// - /// Write a single byte to the output stream - /// - private void WRITE_BYTE(int pos) - { - if (System.Write(OutputFileHandle, Window, pos, 1) != 1) - Error = Error.MSPACK_ERR_WRITE; - } - - private Error ReadLens(uint type, uint numsyms, byte[] lens) - { - uint i, c, sel; - - switch (type) - { - case 0: - i = numsyms; - c = (uint)((i == 16) ? 4 : (i == 32) ? 5 : (i == 64) ? 6 : (i == 256) ? 8 : 0); - for (i = 0; i < numsyms; i++) - { - lens[i] = (byte)c; - } - - break; - - case 1: - c = (uint)READ_BITS_SAFE(4); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - lens[0] = (byte)c; - for (i = 1; i < numsyms; i++) - { - sel = (uint)READ_BITS_SAFE(1); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - if (sel == 0) - { - lens[i] = (byte)c; - } - else - { - sel = (uint)READ_BITS_SAFE(1); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - if (sel == 0) - { - lens[i] = (byte)++c; - } - else - { - c = (uint)READ_BITS_SAFE(4); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - lens[i] = (byte)c; - } - } - } - - break; - - case 2: - c = (uint)READ_BITS_SAFE(4); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - lens[0] = (byte)c; - for (i = 1; i < numsyms; i++) - { - sel = (uint)READ_BITS_SAFE(2); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - if (sel == 3) - { - c = (uint)READ_BITS_SAFE(4); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - } - else - { - c += (uint)((byte)sel - 1); - } - - lens[i] = (byte)c; - } - - break; - - case 3: - for (i = 0; i < numsyms; i++) - { - c = (uint)READ_BITS_SAFE(4); - if (Error == Error.MSPACK_ERR_NOMEMORY) - return Error.MSPACK_ERR_OK; - - lens[i] = (byte)c; - } - - break; - } - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadBits.cs b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadBits.cs deleted file mode 100644 index 138ae39c..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadBits.cs +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2010 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using static LibMSPackSharp.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class LZHKWAJ : CompressionStream - { - /// - public override void READ_BYTES() - { - if (InputPointer >= InputEnd) - { - ReadInput(); - if (Error != Error.MSPACK_ERR_OK) - return; - - InputPointer = InputPointer; - InputEnd = InputEnd; - } - - INJECT_BITS_MSB(InputBuffer[InputPointer++], 8); - } - - /// - protected override void ReadInput() - { - int read; - if (EndOfInput != 0) - { - EndOfInput += 8; - InputBuffer[0] = 0; - read = 1; - } - else - { - read = System.Read(InputFileHandle, InputBuffer, 0, KWAJ_INPUT_SIZE); - if (read < 0) - { - Error = Error.MSPACK_ERR_READ; - return; - } - - if (read == 0) - { - InputEnd = 8; - InputBuffer[0] = 0; - read = 1; - } - } - - // Update InputPointer and InputLength - InputPointer = 0; - InputEnd = read; - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadHuff.cs b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadHuff.cs deleted file mode 100644 index 78c1e026..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.ReadHuff.cs +++ /dev/null @@ -1,17 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2010 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public partial class LZHKWAJ : CompressionStream - { - /// - public override Error HUFF_ERROR() => Error.MSPACK_ERR_DATAFORMAT; - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs b/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs deleted file mode 100644 index 442fd5a8..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZHKWAJ.cs +++ /dev/null @@ -1,37 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2010 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using static LibMSPackSharp.Constants; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class LZHKWAJ : CompressionStream - { - // Huffman code lengths - - public byte[] MATCHLEN1_len { get; set; } = new byte[KWAJ_MATCHLEN1_SYMS]; - public byte[] MATCHLEN2_len { get; set; } = new byte[KWAJ_MATCHLEN2_SYMS]; - public byte[] LITLEN_len { get; set; } = new byte[KWAJ_LITLEN_SYMS]; - public byte[] OFFSET_len { get; set; } = new byte[KWAJ_OFFSET_SYMS]; - public byte[] LITERAL_len { get; set; } = new byte[KWAJ_LITERAL_SYMS]; - - // Huffman decoding tables - - public ushort[] MATCHLEN1_table { get; set; } = new ushort[KWAJ_MATCHLEN1_TBLSIZE]; - public ushort[] MATCHLEN2_table { get; set; } = new ushort[KWAJ_MATCHLEN2_TBLSIZE]; - public ushort[] LITLEN_table { get; set; } = new ushort[KWAJ_LITLEN_TBLSIZE]; - public ushort[] OFFSET_table { get; set; } = new ushort[KWAJ_OFFSET_TBLSIZE]; - public ushort[] LITERAL_table { get; set; } = new ushort[KWAJ_LITERAL_TBLSIZE]; - - // History window - - public byte[] Window { get; set; } = new byte[LZSS_WINDOW_SIZE]; - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZSS.cs b/BurnOutSharp/External/libmspack/Compression/LZSS.cs deleted file mode 100644 index f9859432..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZSS.cs +++ /dev/null @@ -1,177 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2010 Stuart Caie. - * - * LZSS is a derivative of LZ77 and was created by James Storer and - * Thomas Szymanski in 1982. Haruhiko Okumura wrote a very popular C - * implementation. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System.IO; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public class LZSS - { - /// - /// Decompresses an LZSS stream. - /// - /// Input bytes will be read in as necessary using the system.read() - /// function with the input file handle given.This will continue until - /// system.read() returns 0 bytes, or an error.Errors will be passed - /// out of the function as MSPACK_ERR_READ errors. Input streams should - /// convey an "end of input stream" by refusing to supply all the bytes - /// that LZSS asks for when they reach the end of the stream, rather - /// than return an error code. - /// - /// Output bytes will be passed to the system.write() function, using - /// the output file handle given.More than one call may be made to - /// system.write(). - /// - /// As EXPAND.EXE (SZDD/KWAJ), Microsoft Help and QBasic have slightly - /// different encodings for the control byte and matches, a "mode" - /// parameter is allowed, to choose the encoding. - /// - /// - /// an mspack_system structure used to read from - /// the input stream and write to the output - /// stream, also to allocate and free memory. - /// - /// an input stream with the LZSS data. - /// an output stream to write the decoded data to. - /// - /// the number of bytes to use as an input - /// bitstream buffer. - /// - /// one of LZSSMode values - /// an error code, or MSPACK_ERR_OK if successful - public static Error Decompress(SystemImpl system, FileStream input, FileStream output, int input_buffer_size, LZSSMode mode) - { - // Check parameters - if (system == null || input_buffer_size < 1 || (mode != LZSSMode.LZSS_MODE_EXPAND && mode != LZSSMode.LZSS_MODE_MSHELP && mode != LZSSMode.LZSS_MODE_QBASIC)) - return Error.MSPACK_ERR_ARGS; - - // Allocate memory - byte[] window = new byte[LZSS_WINDOW_SIZE + input_buffer_size]; - - // Initialise decompression - int inbuf = LZSS_WINDOW_SIZE; - for (int j = inbuf; j < window.Length; j++) - { - window[j] = LZSS_WINDOW_FILL; - } - - uint pos = LZSS_WINDOW_SIZE - (uint)((mode == LZSSMode.LZSS_MODE_QBASIC) ? 18 : 16); - uint invert = (uint)((mode == LZSSMode.LZSS_MODE_MSHELP) ? ~0 : 0); - int i_ptr = 0, i_end = 0, read; - - // Loop forever; exit condition is in ENSURE_BYTES macro - for (; ; ) - { - //ENSURE_BYTES - { - if (i_ptr >= i_end) - { - read = input.Read(window, inbuf, input_buffer_size); - if (read <= 0) - return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; - - i_ptr = inbuf; - i_end = read; - } - } - - uint c = window[i_ptr++] ^ invert; - for (uint i = 0x01; (i & 0xFF) != 0; i <<= 1) - { - // Literal - if (c != 0 & i != 0) - { - //ENSURE_BYTES - { - if (i_ptr >= i_end) - { - read = input.Read(window, inbuf, input_buffer_size); - if (read <= 0) - return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; - - i_ptr = inbuf; - i_end = read; - } - } - - window[pos] = window[i_ptr++]; - - //WRITE_BYTE - { - try { output.Write(window, (int)pos, 1); } - catch { return Error.MSPACK_ERR_WRITE; } - } - - pos++; - pos &= LZSS_WINDOW_SIZE - 1; - } - - // Match - else - { - //ENSURE_BYTES - { - if (i_ptr >= i_end) - { - read = input.Read(window, inbuf, input_buffer_size); - if (read <= 0) - return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; - - i_ptr = inbuf; - i_end = read; - } - } - - uint mpos = window[i_ptr++]; - - //ENSURE_BYTES - { - if (i_ptr >= i_end) - { - read = input.Read(window, inbuf, input_buffer_size); - if (read <= 0) - return (read < 0) ? Error.MSPACK_ERR_READ : Error.MSPACK_ERR_OK; - - i_ptr = inbuf; - i_end = read; - } - } - - mpos |= (uint)(window[i_ptr] & 0xF0) << 4; - uint len = (uint)(window[i_ptr++] & 0x0F) + 3; - - while (len-- != 0) - { - window[pos] = window[mpos]; - - //WRITE_BYTE - { - try { output.Write(window, (int)pos, 1); } - catch { return Error.MSPACK_ERR_WRITE; } - } - - pos++; - pos &= LZSS_WINDOW_SIZE - 1; - mpos++; - mpos &= LZSS_WINDOW_SIZE - 1; - } - } - } - } - - /* not reached */ - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.Decompress.cs b/BurnOutSharp/External/libmspack/Compression/LZX.Decompress.cs deleted file mode 100644 index 865ffb50..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZX.Decompress.cs +++ /dev/null @@ -1,847 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2013 Stuart Caie. - * - * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted - * by Microsoft Corporation. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -/* Microsoft's LZX document (in cab-sdk.exe) and their implementation - * of the com.ms.util.cab Java package do not concur. - * - * In the LZX document, there is a table showing the correlation between - * window size and the number of position slots. It states that the 1MB - * window = 40 slots and the 2MB window = 42 slots. In the implementation, - * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the - * first slot whose position base is equal to or more than the required - * window size'. This would explain why other tables in the document refer - * to 50 slots rather than 42. - * - * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode - * is not defined in the specification. - * - * The LZX document does not state the uncompressed block has an - * uncompressed length field. Where does this length field come from, so - * we can know how large the block is? The implementation has it as the 24 - * bits following after the 3 blocktype bits, before the alignment - * padding. - * - * The LZX document states that aligned offset blocks have their aligned - * offset huffman tree AFTER the main and length trees. The implementation - * suggests that the aligned offset tree is BEFORE the main and length - * trees. - * - * The LZX document decoding algorithm states that, in an aligned offset - * block, if an extra_bits value is 1, 2 or 3, then that number of bits - * should be read and the result added to the match offset. This is - * correct for 1 and 2, but not 3, where just a huffman symbol (using the - * aligned tree) should be read. - * - * Regarding the E8 preprocessing, the LZX document states 'No translation - * may be performed on the last 6 bytes of the input block'. This is - * correct. However, the pseudocode provided checks for the *E8 leader* - * up to the last 6 bytes. If the leader appears between -10 and -7 bytes - * from the end, this would cause the next four bytes to be modified, at - * least one of which would be in the last 6 bytes, which is not allowed - * according to the spec. - * - * The specification states that the huffman trees must always contain at - * least one element. However, many CAB files contain blocks where the - * length tree is completely empty (because there are no matches), and - * this is expected to succeed. - * - * The errors in LZX documentation appear have been corrected in the - * new documentation for the LZX DELTA format. - * - * http://msdn.microsoft.com/en-us/library/cc483133.aspx - * - * However, this is a different format, an extension of regular LZX. - * I have noticed the following differences, there may be more: - * - * The maximum window size has increased from 2MB to 32MB. This also - * increases the maximum number of position slots, etc. - * - * If the match length is 257 (the maximum possible), this signals - * a further length decoding step, that allows for matches up to - * 33024 bytes long. - * - * The format now allows for "reference data", supplied by the caller. - * If match offsets go further back than the number of bytes - * decompressed so far, that is them accessing the reference data. - */ - -using System; -using System.IO; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class LZX - { - #region Public Functionality - - /// - /// Allocates and initialises LZX decompression state for decoding an LZX - /// stream. - /// - /// This routine uses system.alloc() to allocate memory. If memory - /// allocation fails, or the parameters to this function are invalid, - /// null is returned. - /// - /// A SystemImpl structure used to read from the input stream and write to the output stream, also to allocate and free memory. - /// An input stream with the LZX data. - /// An output stream to write the decoded data to. - /// The size of the decoding window, which must be between 15 and 21 inclusive for regular LZX data, or between 17 and 25 inclusive for LZX DELTA data. - /// - /// The interval at which the LZX bitstream is reset, in multiples of LZX frames (32678 bytes), - /// e.g. a value of 2 indicates the input stream resets after every 65536 output bytes. - /// A value of 0 indicates that the bitstream never resets, such as in CAB LZX streams. - /// - /// The number of bytes to use as an input bitstream buffer. - /// - /// The length in bytes of the entirely decompressed output stream, if known in advance. - /// It is used to correctly perform the Intel E8 transformation, which must stop 6 bytes before the very end of the decompressed stream. - /// It is not otherwise used or adhered to. If the full decompressed length is known in advance, set it here. - /// If it is NOT known, use the value 0, and call lzxd_set_outputLength() once it is known. - /// If never set, 4 of the final 6 bytes of the output stream may be incorrect - /// - /// Should be zero for all regular LZX data, non-zero for LZX DELTA encoded data. - /// A pointer to an initialised LZX structure, or null if there was not enough memory or parameters to the function were wrong. - public static LZX Init(SystemImpl system, FileStream input, FileStream output, int window_bits, int reset_interval, int input_buffer_size, long output_length, bool is_delta) - { - if (system == null) - return null; - - // LZX DELTA window sizes are between 2^17 (128KiB) and 2^25 (32MiB), - // regular LZX windows are between 2^15 (32KiB) and 2^21 (2MiB) - if (is_delta) - { - if (window_bits < 17 || window_bits > 25) - return null; - } - else - { - if (window_bits < 15 || window_bits > 21) - return null; - } - - if (reset_interval < 0 || output_length < 0) - { - Console.WriteLine("Reset interval or output length < 0"); - return null; - } - - // Round up input buffer size to multiple of two - input_buffer_size = (input_buffer_size + 1) & -2; - if (input_buffer_size < 2) - return null; - - // Allocate decompression state - LZX lzx = new LZX() - { - // Allocate decompression window and input buffer - Window = new byte[1 << window_bits], - InputBuffer = new byte[input_buffer_size], - - System = system, - InputFileHandle = input, - OutputFileHandle = output, - Offset = 0, - Length = output_length, - - InputBufferSize = (uint)input_buffer_size, - WindowSize = (uint)(1 << window_bits), - ReferenceDataSize = 0, - WindowPosition = 0, - FramePosition = 0, - Frame = 0, - ResetInterval = (uint)reset_interval, - IntelFileSize = 0, - IntelStarted = false, - Error = Error.MSPACK_ERR_OK, - NumOffsets = LZXPositionSlots[window_bits - 15] << 3, - IsDelta = is_delta, - - OutputPointer = 0, - OutputEnd = 0, - WriteFromE8 = false, - }; - - lzx.ResetState(); - lzx.INIT_BITS(); - - return lzx; - } - - /// - /// Reads LZX DELTA reference data into the window and allows - /// lzxd_decompress() to reference it. - /// - /// Call this before the first call to lzxd_decompress(). - /// - /// A SystemImpl structure to use with the input param. Only read() will be called. - /// An input file handle to read reference data using system.read(). - /// The length of the reference data. Cannot be longer than the LZX window size. - /// An error code, or MSPACK_ERR_OK if successful - public Error SetReferenceData(SystemImpl system, FileStream input, uint length) - { - if (!IsDelta) - { - Console.WriteLine("Only LZX DELTA streams support reference data"); - return Error.MSPACK_ERR_ARGS; - } - - if (Offset > 0) - { - Console.WriteLine("Too late to set reference data after decoding starts"); - return Error.MSPACK_ERR_ARGS; - } - - if (length > WindowSize) - { - Console.WriteLine($"Reference length ({length}) is longer than the window"); - return Error.MSPACK_ERR_ARGS; - } - - if (length > 0 && (system == null || input == null)) - { - Console.WriteLine("Length > 0 but no system or input"); - return Error.MSPACK_ERR_ARGS; - } - - ReferenceDataSize = length; - if (length > 0) - { - // Copy reference data - int pos = (int)(WindowSize - length); - int bytes = system.Read(input, Window, pos, (int)length); - - // Length can't be more than 2^25, so no signedness problem - if (bytes < (int)length) - return Error.MSPACK_ERR_READ; - } - - ReferenceDataSize = length; - return Error.MSPACK_ERR_OK; - } - - // See description of outputLength in Init() - public void SetOutputLength(long outputLength) - { - if (outputLength > 0) - Length = outputLength; - } - - /// - /// Decompresses entire or partial LZX streams. - /// - /// The number of bytes of data that should be decompressed is given as the - /// out_bytes parameter. If more bytes are decoded than are needed, they - /// will be kept over for a later invocation. - /// - /// The output bytes will be passed to the system.write() function given in - /// lzxd_init(), using the output file handle given in lzxd_init(). More than - /// one call may be made to system.write(). - /// Input bytes will be read in as necessary using the system.read() - /// function given in lzxd_init(), using the input file handle given in - /// lzxd_init(). This will continue until system.read() returns 0 bytes, - /// or an error. Errors will be passed out of the function as - /// MSPACK_ERR_READ errors. Input streams should convey an "end of input - /// stream" by refusing to supply all the bytes that LZX asks for when they - /// reach the end of the stream, rather than return an error code. - /// - /// If any error code other than MSPACK_ERR_OK is returned, the stream - /// should be considered unusable and lzxd_decompress() should not be - /// called again on this stream. - /// - /// The number of bytes of data to decompress. - /// an error code, or MSPACK_ERR_OK if successful - public Error Decompress(long out_bytes) - { - int match_length, length_footer, extra, verbatim_bits, bytes_todo; - int this_run, main_element, aligned_bits, j, warned = 0; - byte[] buf = new byte[12]; - int runsrc, rundest; - uint frame_size = 0, end_frame, match_offset; - - // Easy answers - if (out_bytes < 0) - return Error.MSPACK_ERR_ARGS; - if (Error != Error.MSPACK_ERR_OK) - return Error; - - // Flush out any stored-up bytes before we begin - int i = OutputEnd - OutputPointer; - if (i > out_bytes) - i = (int)out_bytes; - - if (i > 0) - { - if (System.Write(OutputFileHandle, WriteFromE8 ? E8Buffer : Window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - OutputPointer += i; - Offset += i; - out_bytes -= i; - } - - if (out_bytes == 0) - return Error.MSPACK_ERR_OK; - - end_frame = (uint)((Offset + out_bytes) / LZX_FRAME_SIZE) + 1; - - while (Frame < end_frame) - { - // Have we reached the reset interval? (if there is one?) - if (ResetInterval != 0 && ((Frame % ResetInterval) == 0)) - { - if (BlockRemaining > 0) - { - // This is a file format error, we can make a best effort to extract what we can - Console.WriteLine($"{BlockRemaining} bytes remaining at reset interval"); - if (warned == 0) - { - System.Message(null, "WARNING; invalid reset interval detected during LZX decompression"); - warned++; - } - } - - // Re-read the intel header and reset the huffman lengths - ResetState(); - } - - // LZX DELTA format has chunk_size, not present in LZX format - if (IsDelta) - { - ENSURE_BITS(16); - REMOVE_BITS_MSB(16); - } - - // Read header if necessary - if (HeaderRead == 0) - { - // Read 1 bit. If bit=0, intel filesize = 0. - // If bit=1, read intel filesize (32 bits) - j = 0; - i = (int)READ_BITS_MSB(1); - if (i != 0) - { - i = (int)READ_BITS_MSB(16); - j = (int)READ_BITS_MSB(16); - } - - IntelFileSize = (i << 16) | j; - HeaderRead = 1; - } - - // Calculate size of frame: all frames are 32k except the final frame - // which is 32kb or less. this can only be calculated when lzx->length - // has been filled in. - frame_size = LZX_FRAME_SIZE; - if (Length != 0 && (Length - Offset) < frame_size) - frame_size = (uint)(Length - Offset); - - // Decode until one more frame is available - bytes_todo = (int)(FramePosition + frame_size - WindowPosition); - while (bytes_todo > 0) - { - // Initialise new block, if one is needed - if (BlockRemaining == 0) - { - // Realign if previous block was an odd-sized UNCOMPRESSED block - if (BlockType == LZXBlockType.LZX_BLOCKTYPE_UNCOMPRESSED && (BlockLength & 1) != 0) - { - READ_IF_NEEDED(); - InputPointer++; - } - - // Read block type (3 bits) and block length (24 bits) - BlockType = (LZXBlockType)READ_BITS_MSB(3); - i = (int)READ_BITS_MSB(16); - j = (int)READ_BITS_MSB(8); - BlockRemaining = BlockLength = (i << 8) | j; - Console.WriteLine($"New block - type: {BlockType}, length: {BlockLength}"); - - // Read individual block headers - switch (BlockType) - { - case LZXBlockType.LZX_BLOCKTYPE_ALIGNED: - // Read lengths of and build aligned huffman decoding tree - for (i = 0; i < 8; i++) - { - j = (int)READ_BITS_MSB(3); - ALIGNED_len[i] = (byte)j; - } - - BUILD_TABLE(ALIGNED_table, ALIGNED_len, LZX_ALIGNED_TABLEBITS, LZX_ALIGNED_MAXSYMBOLS); - - // Rest of aligned header is same as verbatim - - // Read lengths of and build main huffman decoding tree - ReadLengths(MAINTREE_len, 0, 256); - ReadLengths(MAINTREE_len, 256, LZX_NUM_CHARS + NumOffsets); - BUILD_TABLE(MAINTREE_table, MAINTREE_len, LZX_MAINTREE_TABLEBITS, LZX_MAINTREE_MAXSYMBOLS); - - // If the literal 0xE8 is anywhere in the block... - if (MAINTREE_len[0xE8] != 0) - IntelStarted = true; - - // Read lengths of and build lengths huffman decoding tree - ReadLengths(LENGTH_len, 0, LZX_NUM_SECONDARY_LENGTHS); - BUILD_TABLE_MAYBE_EMPTY(); - break; - - case LZXBlockType.LZX_BLOCKTYPE_VERBATIM: - // Read lengths of and build main huffman decoding tree - ReadLengths(MAINTREE_len, 0, 256); - ReadLengths(MAINTREE_len, 256, LZX_NUM_CHARS + NumOffsets); - BUILD_TABLE(MAINTREE_table, MAINTREE_len, LZX_MAINTREE_TABLEBITS, LZX_MAINTREE_MAXSYMBOLS); - - // If the literal 0xE8 is anywhere in the block... - if (MAINTREE_len[0xE8] != 0) - IntelStarted = true; - - // Read lengths of and build lengths huffman decoding tree - ReadLengths(LENGTH_len, 0, LZX_NUM_SECONDARY_LENGTHS); - BUILD_TABLE_MAYBE_EMPTY(); - break; - - case LZXBlockType.LZX_BLOCKTYPE_UNCOMPRESSED: - // Because we can't assume otherwise - IntelStarted = true; - - // Read 1-16 (not 0-15) bits to align to bytes - if (BitsLeft == 0) - ENSURE_BITS(16); - - BitsLeft = 0; - BitBuffer = 0; - - // Read 12 bytes of stored R0 / R1 / R2 values - for (rundest = 0, i = 0; i < 12; i++) - { - READ_IF_NEEDED(); - buf[rundest++] = InputBuffer[InputPointer++]; - } - - R[0] = (uint)(buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24)); - R[1] = (uint)(buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24)); - R[2] = (uint)(buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24)); - break; - - default: - Console.WriteLine($"Bad block type {BlockType}"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - } - - // Decode more of the block: - // run = min(what's available, what's needed) - this_run = BlockRemaining; - if (this_run > bytes_todo) - this_run = bytes_todo; - - // Assume we decode exactly this_run bytes, for now - bytes_todo -= this_run; - BlockRemaining -= this_run; - - // Decode at least this_run bytes - switch (BlockType) - { - case LZXBlockType.LZX_BLOCKTYPE_ALIGNED: - case LZXBlockType.LZX_BLOCKTYPE_VERBATIM: - while (this_run > 0) - { - main_element = (int)READ_HUFFSYM_MSB(MAINTREE_table, MAINTREE_len, LZX_MAINTREE_TABLEBITS, LZX_MAINTREE_MAXSYMBOLS); - if (main_element < LZX_NUM_CHARS) - { - // Literal: 0 to LZX_NUM_CHARS-1 - Window[WindowPosition++] = (byte)main_element; - this_run--; - } - else - { - // Match: LZX_NUM_CHARS ((slot<<3) | length_header (3 bits)) - main_element -= LZX_NUM_CHARS; - - // Get match length - match_length = main_element & LZX_NUM_PRIMARY_LENGTHS; - if (match_length == LZX_NUM_PRIMARY_LENGTHS) - { - if (LENGTH_empty) - { - Console.WriteLine("LENGTH symbol needed but tree is empty"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - length_footer = (int)READ_HUFFSYM_MSB(LENGTH_table, LENGTH_len, LZX_LENGTH_TABLEBITS, LZX_LENGTH_MAXSYMBOLS); - match_length += length_footer; - } - - match_length += LZX_MIN_MATCH; - - // Get match offset - switch ((match_offset = (uint)(main_element >> 3))) - { - case 0: - match_offset = R[0]; - break; - - case 1: - match_offset = R[1]; - R[1] = R[0]; - R[0] = match_offset; - break; - - case 2: - match_offset = R[2]; - R[2] = R[0]; - R[0] = match_offset; - break; - - default: - if (BlockType == LZXBlockType.LZX_BLOCKTYPE_VERBATIM) - { - if (match_offset == 3) - { - match_offset = 1; - } - else - { - extra = ExtraBits(match_offset); - verbatim_bits = (int)READ_BITS_MSB(extra); - match_offset = (uint)(PositionBase(match_offset) - 2 + verbatim_bits); - } - } - else // LZX_BLOCKTYPE_ALIGNED - { - extra = ExtraBits(match_offset); - match_offset = (uint)(PositionBase(match_offset) - 2); - if (extra > 3) // >3: verbatim and aligned bits - { - extra -= 3; - verbatim_bits = (int)READ_BITS_MSB(extra); - match_offset += (uint)(verbatim_bits << 3); - aligned_bits = (int)READ_HUFFSYM_MSB(ALIGNED_table, ALIGNED_len, LZX_ALIGNED_TABLEBITS, LZX_ALIGNED_MAXSYMBOLS); - match_offset += (uint)aligned_bits; - } - else if (extra == 3) // 3: aligned bits only - { - aligned_bits = (int)READ_HUFFSYM_MSB(ALIGNED_table, ALIGNED_len, LZX_ALIGNED_TABLEBITS, LZX_ALIGNED_MAXSYMBOLS); - match_offset += (uint)aligned_bits; - } - else if (extra > 0) // 1-2: verbatim bits only - { - verbatim_bits = (int)READ_BITS_MSB(extra); - match_offset += (uint)verbatim_bits; - } - else // 0: not defined in LZX specification! - { - match_offset = 1; - } - } - - // Update repeated offset LRU queue - R[2] = R[1]; - R[1] = R[0]; - R[0] = match_offset; - break; - } - - // LZX DELTA uses max match length to signal even longer match - if (match_length == LZX_MAX_MATCH && IsDelta) - { - int extra_len = 0; - ENSURE_BITS(3); // 4 entry huffman tree - if (PEEK_BITS_MSB(1) == 0) - { - REMOVE_BITS_MSB(1); // '0' -> 8 extra length bits - extra_len = (int)READ_BITS_MSB(8); - } - else if (PEEK_BITS_MSB(2) == 2) - { - REMOVE_BITS_MSB(2); // '10' -> 10 extra length bits + 0x100 - extra_len = (int)READ_BITS_MSB(10); - extra_len += 0x100; - } - else if (PEEK_BITS_MSB(3) == 6) - { - REMOVE_BITS_MSB(3); // '110' -> 12 extra length bits + 0x500 - extra_len = (int)READ_BITS_MSB(12); - extra_len += 0x500; - } - else - { - REMOVE_BITS_MSB(3); // '111' -> 15 extra length bits - extra_len = (int)READ_BITS_MSB(15); - } - - match_length += extra_len; - } - - if ((WindowPosition + match_length) > WindowSize) - { - Console.WriteLine("Match ran over window wrap"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - // TODO: This falls out of sync after (91,3) - // - Official program goes to (94, 3) - // - Ours goes to (95, 3) - - // Copy match - rundest = WindowPosition; - i = match_length; - - // Does match offset wrap the window? - if (match_offset > WindowPosition) - { - if (match_offset > Offset && (match_offset - WindowPosition) > ReferenceDataSize) - { - Console.WriteLine("Match offset beyond LZX stream"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - // j = length from match offset to end of window - j = (int)match_offset - WindowPosition; - if (j > (int)WindowSize) - { - Console.WriteLine("Match offset beyond window boundaries"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - runsrc = (int)(WindowSize - j); - if (j < i) - { - // If match goes over the window edge, do two copy runs - i -= j; - while (j-- > 0) - { - Window[rundest++] = Window[runsrc++]; - } - - runsrc = 0; - } - - while (i-- > 0) - { - Window[rundest++] = Window[runsrc++]; - } - } - else - { - runsrc = rundest - (int)match_offset; - while (i-- > 0) - { - Window[rundest++] = Window[runsrc++]; - } - } - - this_run -= match_length; - WindowPosition += match_length; - } - } - - break; - - case LZXBlockType.LZX_BLOCKTYPE_UNCOMPRESSED: - // As this_run is limited not to wrap a frame, this also means it - // won't wrap the window (as the window is a multiple of 32k) - rundest = WindowPosition; - WindowPosition += this_run; - while (this_run > 0) - { - if ((i = InputEnd - InputPointer) == 0) - { - READ_IF_NEEDED(); - } - else - { - if (i > this_run) - i = this_run; - - Array.Copy(InputBuffer, InputPointer, Window, rundest, i); - rundest += 1; - InputPointer += i; - this_run -= i; - } - } - - break; - - default: - return Error = Error.MSPACK_ERR_DECRUNCH; // Might as well - } - - // Did the final match overrun our desired this_run length? - if (this_run < 0) - { - if ((uint)(-this_run) > BlockRemaining) - { - Console.Write($"Overrun went past end of block by {-this_run} ({BlockRemaining} remaining)"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - BlockRemaining -= -this_run; - } - } - - // Streams don't extend over frame boundaries - if ((WindowPosition - FramePosition) != frame_size) - { - Console.WriteLine($"Decode beyond output frame limits {WindowPosition - FramePosition} != {frame_size}"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - // Re-align input bitstream - if (BitsLeft > 0) - ENSURE_BITS(16); - if ((BitsLeft & 15) != 0) - REMOVE_BITS_MSB(BitsLeft & 15); - - // Check that we've used all of the previous frame first - if (OutputPointer != OutputEnd) - { - Console.Write($"{OutputEnd - OutputPointer} avail bytes, new {frame_size} frame"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - // Does this intel block _really_ need decoding? - if (IntelStarted && IntelFileSize != 0 && Frame < 32768 && frame_size > 10) - { - int data = 0; - int dataend = (int)frame_size - 10; - int curpos = (int)Offset; - int filesize = IntelFileSize; - int abs_off, rel_off; - - // Copy E8 block to the e8 buffer and tweak if needed - WriteFromE8 = true; - OutputPointer = data; - Array.Copy(Window, FramePosition, E8Buffer, data, frame_size); - - while (data < dataend) - { - if (E8Buffer[data++] != 0xE8) - { - curpos++; - continue; - } - - abs_off = E8Buffer[data + 0] | (E8Buffer[data + 1] << 8) | (E8Buffer[data + 2] << 16) | (E8Buffer[data + 3] << 24); - if ((abs_off >= -curpos) && (abs_off < filesize)) - { - rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize; - E8Buffer[data + 0] = (byte)rel_off; - E8Buffer[data + 1] = (byte)(rel_off >> 8); - E8Buffer[data + 2] = (byte)(rel_off >> 16); - E8Buffer[data + 3] = (byte)(rel_off >> 24); - } - - data += 4; - curpos += 5; - } - } - else - { - WriteFromE8 = false; - OutputPointer = (int)FramePosition; - } - - OutputEnd = (int)frame_size; - - // Write a frame - i = (int)(out_bytes < frame_size ? out_bytes : frame_size); - if (System.Write(OutputFileHandle, WriteFromE8 ? E8Buffer : Window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - OutputPointer += i; - Offset += i; - out_bytes -= i; - - // Advance frame start position - FramePosition += (uint)frame_size; - Frame++; - - // Wrap window / frame position pointers - if (WindowPosition == WindowSize) - WindowPosition = 0; - if (FramePosition == WindowSize) - FramePosition = 0; - } - - if (out_bytes > 0) - { - Console.WriteLine($"{out_bytes} bytes left to output"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - return Error.MSPACK_ERR_OK; - } - - #endregion - - #region Helpers - - /// - /// States how many bits of offset-from-base data is needed. - /// - private int ExtraBits(uint offset) - { - if (offset < 4) - return 0; - else if (offset >= 4 && offset < 36) - return (int)Math.Floor((double)(offset / 2)) - 1; - else // offset >= 36 - return 17; - } - - /// - /// An index to the position slot bases - /// - private long PositionBase(uint offset) - { - if (offset < 0 || offset >= 290) - return 0; - - return LZXPositionBase[offset]; - - // TODO: Replace naieve recursive implementation - if (offset == 0) - return 0; - else - return PositionBase(offset - 1) + (1 << ExtraBits(offset - 1)); - } - - /// - /// Reset the internal state - /// - private void ResetState() - { - R[0] = 1; - R[1] = 1; - R[2] = 1; - HeaderRead = 0; - BlockRemaining = 0; - BlockType = LZXBlockType.LZX_BLOCKTYPE_INVALID0; - WriteFromE8 = false; - - // Initialise tables to 0 (because deltas will be applied to them) - for (int i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) - { - MAINTREE_len[i] = 0; - } - - for (int i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) - { - LENGTH_len[i] = 0; - } - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.ReadBits.cs b/BurnOutSharp/External/libmspack/Compression/LZX.ReadBits.cs deleted file mode 100644 index 370a3297..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZX.ReadBits.cs +++ /dev/null @@ -1,34 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2013 Stuart Caie. - * - * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted - * by Microsoft Corporation. - * - * libmspack is free software { get; set; } you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public partial class LZX : CompressionStream - { - /// - public override void READ_BYTES() - { - READ_IF_NEEDED(); - if (Error != Error.MSPACK_ERR_OK) - return; - - byte b0 = InputBuffer[InputPointer++]; - - READ_IF_NEEDED(); - if (Error != Error.MSPACK_ERR_OK) - return; - - byte b1 = InputBuffer[InputPointer++]; - INJECT_BITS_MSB((b1 << 8) | b0, 16); - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.ReadHuff.cs b/BurnOutSharp/External/libmspack/Compression/LZX.ReadHuff.cs deleted file mode 100644 index ba892e66..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZX.ReadHuff.cs +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2013 Stuart Caie. - * - * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted - * by Microsoft Corporation. - * - * libmspack is free software { get; set; } you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class LZX : CompressionStream - { - /// - public override Error HUFF_ERROR() => Error.MSPACK_ERR_DECRUNCH; - - /// - /// BUILD_TABLE(tbl) builds a huffman lookup table from code lengths - /// - private Error BUILD_TABLE(ushort[] table, byte[] lengths, int tablebits, int maxsymbols) - { - if (!MakeDecodeTableMSB(maxsymbols, tablebits, lengths, table)) - { - Console.WriteLine("Failed to build table"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - return Error = Error.MSPACK_ERR_OK; - } - - private Error BUILD_TABLE_MAYBE_EMPTY() - { - LENGTH_empty = false; - if (!MakeDecodeTableMSB(LZX_LENGTH_MAXSYMBOLS, LZX_LENGTH_TABLEBITS, LENGTH_len, LENGTH_table)) - { - for (int i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) - { - if (LENGTH_len[i] > 0) - { - Console.WriteLine("Failed to build LENGTH table"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - } - - // Empty tree - allow it, but don't decode symbols with it - LENGTH_empty = true; - } - - return Error = Error.MSPACK_ERR_OK; - } - - /// - /// READ_LENGTHS(tablename, first, last) reads in code lengths for symbols - /// first to last in the given table. The code lengths are stored in their - /// own special LZX way. - /// - private Error ReadLengths(byte[] lens, uint first, uint last) - { - uint x, y; - int z; - - // Read lengths for pretree (20 symbols, lengths stored in fixed 4 bits) - for (x = 0; x < LZX_PRETREE_MAXSYMBOLS; x++) - { - y = (uint)READ_BITS_MSB(4); - PRETREE_len[x] = (byte)y; - } - - BUILD_TABLE(PRETREE_table, PRETREE_len, LZX_PRETREE_TABLEBITS, LZX_PRETREE_MAXSYMBOLS); - if (Error != Error.MSPACK_ERR_OK) - return Error; - - for (x = first; x < last;) - { - z = (int)READ_HUFFSYM_MSB(PRETREE_table, PRETREE_len, LZX_PRETREE_TABLEBITS, LZX_PRETREE_MAXSYMBOLS); - if (z == 17) - { - // Code = 17, run of ([read 4 bits]+4) zeros - y = (uint)READ_BITS_MSB(4); - y += 4; - while (y-- > 0) - { - lens[x++] = 0; - } - } - else if (z == 18) - { - // Code = 18, run of ([read 5 bits]+20) zeros - y = (uint)READ_BITS_MSB(5); - y += 20; - while (y-- > 0) - { - lens[x++] = 0; - } - } - else if (z == 19) - { - // Code = 19, run of ([read 1 bit]+4) [read huffman symbol] - y = (uint)READ_BITS_MSB(1); - y += 4; - - z = (int)READ_HUFFSYM_MSB(PRETREE_table, PRETREE_len, LZX_PRETREE_TABLEBITS, LZX_PRETREE_MAXSYMBOLS); - z = lens[x] - z; - if (z < 0) - z += 17; - - while (y-- > 0) - { - lens[x++] = (byte)z; - } - } - else - { - // Code = 0 to 16, delta current length entry - z = lens[x] - z; - if (z < 0) - z += 17; - - lens[x++] = (byte)z; - } - } - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.cs b/BurnOutSharp/External/libmspack/Compression/LZX.cs deleted file mode 100644 index c9bf0f07..00000000 --- a/BurnOutSharp/External/libmspack/Compression/LZX.cs +++ /dev/null @@ -1,133 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2013 Stuart Caie. - * - * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted - * by Microsoft Corporation. - * - * libmspack is free software { get; set; } you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class LZX : CompressionStream - { - /// - /// Number of bytes actually output - /// - public long Offset { get; set; } - - /// - /// Overall decompressed length of stream - /// - public long Length { get; set; } - - /// - /// Decoding window - /// - public byte[] Window { get; set; } - - /// - /// Window size - /// - public uint WindowSize { get; set; } - - /// - /// LZX DELTA reference data size - /// - public uint ReferenceDataSize { get; set; } - - /// - /// Number of match_offset entries in table - /// - public uint NumOffsets { get; set; } - - /// - /// Decompression offset within window - /// - public int WindowPosition { get; set; } - - /// - /// Current frame offset within in window - /// - public uint FramePosition { get; set; } - - /// - /// The number of 32kb frames processed - /// - public uint Frame { get; set; } - - /// - /// Which frame do we reset the compressor? - /// - public uint ResetInterval { get; set; } - - /// - /// For the LRU offset system - /// - public uint[] R { get; set; } = new uint[3]; - - /// - /// Uncompressed length of this LZX block - /// - public int BlockLength { get; set; } - - /// - /// Uncompressed bytes still left to decode - /// - public int BlockRemaining { get; set; } - - /// - /// Magic header value used for transform - /// - public int IntelFileSize { get; set; } - - /// - /// Has intel E8 decoding started? - /// - public bool IntelStarted { get; set; } - - /// - /// Type of the current block - /// - public LZXBlockType BlockType { get; set; } - - /// - /// Have we started decoding at all yet? - /// - public byte HeaderRead { get; set; } - - /// - /// Does stream follow LZX DELTA spec? - /// - public bool IsDelta { get; set; } - - #region Huffman code lengths - - public byte[] PRETREE_len { get; set; } = new byte[LZX_PRETREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY]; - public byte[] MAINTREE_len { get; set; } = new byte[LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY]; - public byte[] LENGTH_len { get; set; } = new byte[LZX_LENGTH_MAXSYMBOLS + LZX_LENTABLE_SAFETY]; - public byte[] ALIGNED_len { get; set; } = new byte[LZX_ALIGNED_MAXSYMBOLS + LZX_LENTABLE_SAFETY]; - - #endregion - - #region Huffman decoding tables - - public ushort[] PRETREE_table { get; set; } = new ushort[(1 << LZX_PRETREE_TABLEBITS) + (LZX_PRETREE_MAXSYMBOLS * 2)]; - public ushort[] MAINTREE_table { get; set; } = new ushort[(1 << LZX_MAINTREE_TABLEBITS) + (LZX_MAINTREE_MAXSYMBOLS * 2)]; - public ushort[] LENGTH_table { get; set; } = new ushort[(1 << LZX_LENGTH_TABLEBITS) + (LZX_LENGTH_MAXSYMBOLS * 2)]; - public ushort[] ALIGNED_table { get; set; } = new ushort[(1 << LZX_ALIGNED_TABLEBITS) + (LZX_ALIGNED_MAXSYMBOLS * 2)]; - - #endregion - - public bool LENGTH_empty { get; set; } - - public byte[] E8Buffer { get; set; } = new byte[LZX_FRAME_SIZE]; - - public bool WriteFromE8 { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.Decompress.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.Decompress.cs deleted file mode 100644 index ea2f7611..00000000 --- a/BurnOutSharp/External/libmspack/Compression/MSZIP.Decompress.cs +++ /dev/null @@ -1,613 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The deflate method was created by Phil Katz. MSZIP is equivalent to the - * deflate method. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; -using System.IO; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class MSZIP - { - /// - /// Allocates MS-ZIP decompression stream for decoding the given stream. - /// - /// - uses system.alloc() to allocate memory - /// - /// - returns null if not enough memory - /// - /// - input_buffer_size is how many bytes to use as an input bitstream buffer - /// - /// - if RepairMode is non-zero, errors in decompression will be skipped - /// and 'holes' left will be filled with zero bytes. This allows at least - /// a partial recovery of erroneous data. - /// - public static MSZIP Init(SystemImpl system, FileStream input, FileStream output, int input_buffer_size, bool repair_mode) - { - if (system == null) - return null; - - // Round up input buffer size to multiple of two - input_buffer_size = (input_buffer_size + 1) & -2; - if (input_buffer_size < 2) - return null; - - // Allocate decompression state - return new MSZIP - { - // Allocate input buffer - InputBuffer = new byte[input_buffer_size], - - // Initialise decompression state - System = system, - InputFileHandle = input, - OutputFileHandle = output, - InputBufferSize = (uint)input_buffer_size, - EndOfInput = 0, - Error = Error.MSPACK_ERR_OK, - RepairMode = repair_mode, - - InputPointer = 0, - InputEnd = 0, - OutputPointer = 0, - OutputEnd = 0, - BitBuffer = 0, - BitsLeft = 0, - }; - } - - /// - /// Decompresses, or decompresses more of, an MS-ZIP stream. - /// - /// - out_bytes of data will be decompressed and the function will return - /// with an MSPACK_ERR_OK return code. - /// - /// - decompressing will stop as soon as out_bytes is reached. if the true - /// amount of bytes decoded spills over that amount, they will be kept for - /// a later invocation of mszipd_decompress(). - /// - /// - the output bytes will be passed to the system.write() function given in - /// mszipd_init(), using the output file handle given in mszipd_init(). More - /// than one call may be made to system.write() - /// - /// - MS-ZIP will read input bytes as necessary using the system.read() - /// function given in mszipd_init(), using the input file handle given in - /// mszipd_init(). This will continue until system.read() returns 0 bytes, - /// or an error. - /// - public Error Decompress(long out_bytes) - { - int i, readState; - Error error; - - // Easy answers - if (out_bytes < 0) - return Error.MSPACK_ERR_ARGS; - if (Error != Error.MSPACK_ERR_OK) - return Error; - - // Flush out any stored-up bytes before we begin - i = OutputEnd - OutputPointer; - if (i > out_bytes) - i = (int)out_bytes; - - if (i > 0) - { - if (System.Write(OutputFileHandle, Window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - OutputPointer += i; - out_bytes -= i; - } - - if (out_bytes == 0) - return Error.MSPACK_ERR_OK; - - while (out_bytes > 0) - { - // Skip to next read 'CK' header - i = BitsLeft & 7; - - // Align to bytestream - REMOVE_BITS_LSB(i); - - readState = 0; - do - { - i = (int)READ_BITS_LSB(8); - - if (i == 'C') - readState = 1; - else if ((readState == 1) && (i == 'K')) - readState = 2; - else - readState = 0; - } while (readState != 2); - - // Inflate a block, repair and realign if necessary - WindowPosition = 0; - BytesOutput = 0; - - if ((error = Inflate()) != Error.MSPACK_ERR_OK) - { - Console.WriteLine($"Inflate error {error}"); - if (RepairMode) - { - // Recover partially-inflated buffers - if (BytesOutput == 0 && WindowPosition > 0) - FlushWindow(WindowPosition); - - System.Message(null, $"MSZIP error, {MSZIP_FRAME_SIZE - BytesOutput} bytes of data lost."); - for (i = BytesOutput; i < MSZIP_FRAME_SIZE; i++) - { - Window[i] = 0x00; - } - - BytesOutput = MSZIP_FRAME_SIZE; - } - else - { - return Error = error; - } - } - - OutputPointer = 0; - OutputEnd = BytesOutput; - - // Write a frame - i = (out_bytes < BytesOutput) ? (int)out_bytes : BytesOutput; - if (System.Write(OutputFileHandle, Window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - // mspack errors (i.e. read errors) are fatal and can't be recovered - if ((error > 0) && RepairMode) - return error; - - OutputPointer += i; - out_bytes -= i; - } - - if (out_bytes > 0) - { - Console.WriteLine($"Bytes left to output: {out_bytes}"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - return Error.MSPACK_ERR_OK; - } - - /// - /// Decompresses an entire MS-ZIP stream in a KWAJ file. Acts very much - /// like mszipd_decompress(), but doesn't take an out_bytes parameter - /// - public Error DecompressKWAJ() - { - int i, block_len; - Error error; - - // Unpack blocks until block_len == 0 - for (; ; ) - { - // Align to bytestream, read block_len - i = BitsLeft & 7; - REMOVE_BITS_LSB(i); - - block_len = (int)READ_BITS_LSB(8); - i = (int)READ_BITS_LSB(8); - - block_len |= i << 8; - if (block_len == 0) - break; - - // Read "CK" header - i = (int)READ_BITS_LSB(8); - if (i != 'C') - return Error.MSPACK_ERR_DATAFORMAT; - - i = (int)READ_BITS_LSB(8); - if (i != 'K') - return Error.MSPACK_ERR_DATAFORMAT; - - // Inflate block - WindowPosition = 0; - BytesOutput = 0; - - if ((error = Inflate()) != Error.MSPACK_ERR_OK) - { - Console.WriteLine($"Inflate error {error}"); - return Error = (error > 0) ? error : Error.MSPACK_ERR_DECRUNCH; - } - - // Write inflated block - try { System.Write(OutputFileHandle, Window, 0, BytesOutput); } - catch { return Error = Error.MSPACK_ERR_WRITE; } - } - - return Error.MSPACK_ERR_OK; - } - - private Error ReadLens() - { - // bitlen Huffman codes -- immediate lookup, 7 bit max code length - ushort[] bl_table = new ushort[(1 << 7)]; - byte[] bl_len = new byte[19]; - - byte[] lens = new byte[MSZIP_LITERAL_MAXSYMBOLS + MSZIP_DISTANCE_MAXSYMBOLS]; - uint lit_codes, dist_codes, code, last_code = 0, bitlen_codes, i, run; - - // Read the number of codes - lit_codes = (uint)READ_BITS_LSB(5); - lit_codes += 257; - - dist_codes = (uint)READ_BITS_LSB(5); - dist_codes += 1; - - bitlen_codes = (uint)READ_BITS_LSB(5); - bitlen_codes += 4; - - if (lit_codes > MSZIP_LITERAL_MAXSYMBOLS) - return Error.INF_ERR_SYMLENS; - if (dist_codes > MSZIP_DISTANCE_MAXSYMBOLS) - return Error.INF_ERR_SYMLENS; - - // Read in the bit lengths in their unusual order - for (i = 0; i < bitlen_codes; i++) - { - bl_len[BitLengthOrder[i]] = (byte)READ_BITS_LSB(3); - } - - while (i < 19) - { - bl_len[BitLengthOrder[i++]] = 0; - } - - // Create decoding table with an immediate lookup - if (!CompressionStream.MakeDecodeTableLSB(19, 7, bl_len, bl_table)) - return Error.INF_ERR_BITLENTBL; - - // Read literal / distance code lengths - for (i = 0; i < (lit_codes + dist_codes); i++) - { - // Single-level huffman lookup - - ENSURE_BITS(7); - code = bl_table[PEEK_BITS_LSB(7)]; - REMOVE_BITS_LSB(bl_len[code]); - - if (code < 16) - { - lens[i] = (byte)(last_code = code); - } - else - { - switch (code) - { - case 16: - run = (uint)READ_BITS_LSB(2); - run += 3; - code = last_code; - break; - - case 17: - run = (uint)READ_BITS_LSB(3); - run += 3; - code = 0; - break; - - case 18: - run = (uint)READ_BITS_LSB(7); - run += 11; - code = 0; - break; - - default: - Console.WriteLine($"Bad code!: {code}"); - return Error.INF_ERR_BADBITLEN; - } - - if ((i + run) > (lit_codes + dist_codes)) - return Error.INF_ERR_BITOVERRUN; - - while (run-- > 0) - { - lens[i++] = (byte)code; - } - - i--; - } - } - - // Copy LITERAL code lengths and clear any remaining - i = lit_codes; - Array.Copy(lens, 0, LITERAL_len, 0, i); - while (i < MSZIP_LITERAL_MAXSYMBOLS) - { - LITERAL_len[i++] = 0; - } - - i = dist_codes; - Array.Copy(lens, lit_codes, DISTANCE_len, 0, i); - while (i < MSZIP_DISTANCE_MAXSYMBOLS) - { - DISTANCE_len[i++] = 0; - } - - return 0; - } - - /// - /// A clean implementation of RFC 1951 / inflate - /// - private Error Inflate() - { - uint last_block, block_type, distance, length, this_run, i; - Error err; - ushort sym; - - do - { - // Read in last block bit - last_block = (uint)READ_BITS_LSB(1); - - // Read in block type - block_type = (uint)READ_BITS_LSB(2); - - if (block_type == 0) - { - // Uncompressed block - byte[] lens_buf = new byte[4]; - - // Go to byte boundary - i = (uint)(BitsLeft & 7); - REMOVE_BITS_LSB((int)i); - - // Read 4 bytes of data, emptying the bit-buffer if necessary - for (i = 0; (BitsLeft >= 8); i++) - { - if (i == 4) - return Error.INF_ERR_BITBUF; - - lens_buf[i] = (byte)PEEK_BITS_LSB(8); - REMOVE_BITS_LSB(8); - } - - if (BitsLeft != 0) - return Error.INF_ERR_BITBUF; - - while (i < 4) - { - READ_IF_NEEDED(); - if (Error != Error.MSPACK_ERR_OK) - return Error; - - lens_buf[i++] = InputBuffer[InputPointer++]; - } - - // Get the length and its complement - length = (ushort)(lens_buf[0] | (lens_buf[1] << 8)); - i = (ushort)(lens_buf[2] | (lens_buf[3] << 8)); - - ushort compl = (ushort)(~i & 0xFFFF); - if (length != compl) - return Error.INF_ERR_COMPLEMENT; - - // Read and copy the uncompressed data into the window - while (length > 0) - { - READ_IF_NEEDED(); - if (Error != Error.MSPACK_ERR_OK) - return Error; - - this_run = length; - if (this_run > (uint)(InputEnd - InputPointer)) - this_run = (uint)(InputEnd - InputPointer); - - if (this_run > (MSZIP_FRAME_SIZE - WindowPosition)) - this_run = MSZIP_FRAME_SIZE - WindowPosition; - - Array.Copy(InputBuffer, InputPointer, Window, WindowPosition, this_run); - - WindowPosition += this_run; - InputPointer += (int)this_run; - length -= this_run; - - err = FLUSH_IF_NEEDED(); - if (err != Error.MSPACK_ERR_OK) - return err; - } - } - else if ((block_type == 1) || (block_type == 2)) - { - // Huffman-compressed LZ77 block - uint match_posn, code; - - if (block_type == 1) - { - // Block with fixed Huffman codes - i = 0; - while (i < 144) - { - LITERAL_len[i++] = 8; - } - - while (i < 256) - { - LITERAL_len[i++] = 9; - } - - while (i < 280) - { - LITERAL_len[i++] = 7; - } - - while (i < 288) - { - LITERAL_len[i++] = 8; - } - - for (i = 0; i < 32; i++) - { - DISTANCE_len[i] = 5; - } - } - else - { - // Block with dynamic Huffman codes - if ((err = ReadLens()) != Error.MSPACK_ERR_OK) - return err; - } - - // Now huffman lengths are read for either kind of block, - // create huffman decoding tables - if (!CompressionStream.MakeDecodeTableLSB(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS, LITERAL_len, LITERAL_table)) - return Error.INF_ERR_LITERALTBL; - - if (!CompressionStream.MakeDecodeTableLSB(MSZIP_DISTANCE_MAXSYMBOLS, MSZIP_DISTANCE_TABLEBITS, DISTANCE_len, DISTANCE_table)) - return Error.INF_ERR_DISTANCETBL; - - // Decode forever until end of block code - for (; ; ) - { - code = (uint)READ_HUFFSYM_LSB(LITERAL_table, LITERAL_len, MSZIP_LITERAL_TABLEBITS, MSZIP_LITERAL_MAXSYMBOLS); - - if (code < 256) - { - Window[WindowPosition++] = (byte)code; - err = FLUSH_IF_NEEDED(); - if (err != Error.MSPACK_ERR_OK) - return err; - } - else if (code == 256) - { - // END OF BLOCK CODE: loop break point - break; - } - else - { - code -= 257; // Codes 257-285 are matches - if (code >= 29) - return Error.INF_ERR_LITCODE; // Codes 286-287 are illegal - - length = (uint)READ_BITS_T_LSB(LiteralExtraBits[code]); - length += LiteralLengths[code]; - - code = (uint)READ_HUFFSYM_LSB(DISTANCE_table, DISTANCE_len, MSZIP_DISTANCE_TABLEBITS, MSZIP_DISTANCE_MAXSYMBOLS); - - if (code >= 30) - return Error.INF_ERR_DISTCODE; - - distance = (uint)READ_BITS_T_LSB(DistanceExtraBits[code]); - distance += DistanceOffsets[code]; - - // Match position is window position minus distance. If distance - // is more than window position numerically, it must 'wrap - // around' the frame size. - match_posn = (uint)((distance > WindowPosition) ? MSZIP_FRAME_SIZE : 0) + WindowPosition - distance; - - // Copy match - if (length < 12) - { - // Short match, use slower loop but no loop setup code - while (length-- > 0) - { - Window[WindowPosition++] = Window[match_posn++]; - match_posn &= MSZIP_FRAME_SIZE - 1; - err = FLUSH_IF_NEEDED(); - if (err != Error.MSPACK_ERR_OK) - return err; - } - } - else - { - // Longer match, use faster loop but with setup expense */ - int runsrc, rundest; - do - { - this_run = length; - if ((match_posn + this_run) > MSZIP_FRAME_SIZE) - this_run = MSZIP_FRAME_SIZE - match_posn; - if ((WindowPosition + this_run) > MSZIP_FRAME_SIZE) - this_run = MSZIP_FRAME_SIZE - WindowPosition; - - rundest = (int)WindowPosition; - WindowPosition += this_run; - runsrc = (int)match_posn; - match_posn += this_run; - length -= this_run; - while (this_run-- > 0) - { - Window[rundest++] = Window[runsrc++]; - } - - if (match_posn == MSZIP_FRAME_SIZE) - match_posn = 0; - - err = FLUSH_IF_NEEDED(); - if (err != Error.MSPACK_ERR_OK) - return err; - } while (length > 0); - } - - } - - } - } - else - { - // block_type == 3 -- bad block type - return Error.INF_ERR_BLOCKTYPE; - } - } while (last_block == 0); - - // Flush the remaining data - if (WindowPosition > 0) - { - if (FlushWindow(WindowPosition) != Error.MSPACK_ERR_OK) - return Error.INF_ERR_FLUSH; - } - - // Return success - return Error.MSPACK_ERR_OK; - } - - private Error FLUSH_IF_NEEDED() - { - if (WindowPosition == MSZIP_FRAME_SIZE) - { - if (FlushWindow(MSZIP_FRAME_SIZE) != Error.MSPACK_ERR_OK) - return Error.INF_ERR_FLUSH; - - WindowPosition = 0; - } - - return Error.MSPACK_ERR_OK; - } - - /// - /// inflate() calls this whenever the window should be flushed. As - /// MSZIP only expands to the size of the window, the implementation used - /// simply keeps track of the amount of data flushed, and if more than 32k - /// is flushed, an error is raised. - /// - private Error FlushWindow(uint data_flushed) - { - BytesOutput += (int)data_flushed; - if (BytesOutput > MSZIP_FRAME_SIZE) - { - Console.WriteLine($"Overflow: {data_flushed} bytes flushed, total is now {BytesOutput}"); - return Error.MSPACK_ERR_ARGS; - } - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.ReadBits.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.ReadBits.cs deleted file mode 100644 index c74fde69..00000000 --- a/BurnOutSharp/External/libmspack/Compression/MSZIP.ReadBits.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The deflate method was created by Phil Katz. MSZIP is equivalent to the - * deflate method. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public partial class MSZIP : CompressionStream - { - /// - public override void READ_BYTES() - { - READ_IF_NEEDED(); - if (Error != Error.MSPACK_ERR_OK) - return; - - INJECT_BITS_LSB(InputBuffer[InputPointer++], 8); - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.ReadHuff.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.ReadHuff.cs deleted file mode 100644 index dad81278..00000000 --- a/BurnOutSharp/External/libmspack/Compression/MSZIP.ReadHuff.cs +++ /dev/null @@ -1,20 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The deflate method was created by Phil Katz. MSZIP is equivalent to the - * deflate method. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public partial class MSZIP : CompressionStream - { - /// - public override Error HUFF_ERROR() => Error.INF_ERR_HUFFSYM; - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs deleted file mode 100644 index 9486a19a..00000000 --- a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The deflate method was created by Phil Katz. MSZIP is equivalent to the - * deflate method. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class MSZIP : CompressionStream - { - /// - /// 32kb history window - /// - public byte[] Window { get; set; } = new byte[MSZIP_FRAME_SIZE]; - - /// - /// Offset within window - /// - public uint WindowPosition { get; set; } - - public bool RepairMode { get; set; } - - public int BytesOutput { get; set; } - - #region Huffman code lengths - - public byte[] LITERAL_len { get; set; } = new byte[MSZIP_LITERAL_MAXSYMBOLS]; - public byte[] DISTANCE_len { get; set; } = new byte[MSZIP_DISTANCE_MAXSYMBOLS]; - - #endregion - - #region Huffman decoding tables - - public ushort[] LITERAL_table { get; set; } = new ushort[MSZIP_LITERAL_TABLESIZE]; - public ushort[] DISTANCE_table { get; set; } = new ushort[MSZIP_DISTANCE_TABLESIZE]; - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/None.Decompress.cs b/BurnOutSharp/External/libmspack/Compression/None.Decompress.cs deleted file mode 100644 index 98b9ebe8..00000000 --- a/BurnOutSharp/External/libmspack/Compression/None.Decompress.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System.IO; - -namespace LibMSPackSharp.Compression -{ - public partial class None - { - public static None Init(SystemImpl sys, FileStream input, FileStream output, int bufsize) - { - return new None() - { - System = sys, - InputFileHandle = input, - OutputFileHandle = output, - Buffer = new byte[bufsize], - BufferSize = bufsize, - }; - } - - public Error Decompress(long bytes) - { - int run; - while (bytes > 0) - { - run = (bytes > BufferSize) ? BufferSize : (int)bytes; - - if (System.Read(InputFileHandle, Buffer, 0, run) != run) - return Error.MSPACK_ERR_READ; - - if (System.Write(OutputFileHandle, Buffer, 0, run) != run) - return Error.MSPACK_ERR_WRITE; - - bytes -= run; - } - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/None.cs b/BurnOutSharp/External/libmspack/Compression/None.cs deleted file mode 100644 index bd6f180e..00000000 --- a/BurnOutSharp/External/libmspack/Compression/None.cs +++ /dev/null @@ -1,21 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - /// - /// The "not compressed" method decompressor - /// - public partial class None : BaseDecompressState - { - public byte[] Buffer { get; set; } - - public int BufferSize { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/QTM.Decompress.cs b/BurnOutSharp/External/libmspack/Compression/QTM.Decompress.cs deleted file mode 100644 index 43c68d6a..00000000 --- a/BurnOutSharp/External/libmspack/Compression/QTM.Decompress.cs +++ /dev/null @@ -1,542 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The Quantum method was created by David Stafford, adapted by Microsoft - * Corporation. - * - * This decompressor is based on an implementation by Matthew Russotto, used - * with permission. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -/* Quantum decompression implementation */ - -/* This decompressor was researched and implemented by Matthew Russotto. It - * has since been tidied up by Stuart Caie. More information can be found at - * http://www.speakeasy.org/~russotto/quantumcomp.html - */ - -using System; -using System.IO; -using static LibMSPackSharp.Compression.Constants; - -namespace LibMSPackSharp.Compression -{ - public partial class QTM - { - /// - /// allocates Quantum decompression state for decoding the given stream. - /// - /// - returns null if window_bits is outwith the range 10 to 21 (inclusive). - /// - uses system.alloc() to allocate memory - /// - returns null if not enough memory - /// - window_bits is the size of the Quantum window, from 1Kb(10) to 2Mb(21). - /// - input_buffer_size is the number of bytes to use to store bitstream data. - /// - public static QTM Init(SystemImpl system, FileStream input, FileStream output, int window_bits, int input_buffer_size) - { - uint window_size = (uint)(1 << window_bits); - - if (system == null) - return null; - - // Quantum supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) - if (window_bits < 10 || window_bits > 21) - return null; - - // Round up input buffer size to multiple of two - input_buffer_size = (input_buffer_size + 1) & -2; - if (input_buffer_size < 2) - return null; - - // Allocate decompression state - QTM qtm = new QTM() - { - // Allocate decompression window and input buffer - Window = new byte[window_size], - InputBuffer = new byte[input_buffer_size], - - // Initialise decompression state - System = system, - InputFileHandle = input, - OutputFileHandle = output, - InputBufferSize = (uint)input_buffer_size, - WindowSize = window_size, - WindowPosition = 0, - FrameTODO = QTM_FRAME_SIZE, - HeaderRead = 0, - Error = Error.MSPACK_ERR_OK, - - InputPointer = 0, - InputEnd = 0, - OutputPointer = 0, - OutputEnd = 0, - BitBuffer = 0, - BitsLeft = 0, - EndOfInput = 0, - }; - - // Initialise arithmetic coding models - // - model 4 depends on window size, ranges from 20 to 24 - // - model 5 depends on window size, ranges from 20 to 36 - // - model 6pos depends on window size, ranges from 20 to 42 - - int i = window_bits * 2; - qtm.InitModel(qtm.Model0, qtm.Model0Symbols, 0, 64); - qtm.InitModel(qtm.Model1, qtm.Model1Symbols, 64, 64); - qtm.InitModel(qtm.Model2, qtm.Model2Symbols, 128, 64); - qtm.InitModel(qtm.Model3, qtm.Model3Symbols, 192, 64); - qtm.InitModel(qtm.Model4, qtm.Model4Symbols, 0, (i > 24) ? 24 : i); - qtm.InitModel(qtm.Model5, qtm.Model5Symbols, 0, (i > 36) ? 36 : i); - qtm.InitModel(qtm.Model6, qtm.Model6Symbols, 0, i); - qtm.InitModel(qtm.Model6Len, qtm.Model6LenSymbols, 0, 27); - qtm.InitModel(qtm.Model7, qtm.Model7Symbols, 0, 7); - - // All ok - return qtm; - } - - /// - /// Decompresses, or decompresses more of, a Quantum stream. - /// - /// - out_bytes of data will be decompressed and the function will return - /// with an MSPACK_ERR_OK return code. - /// - /// - decompressing will stop as soon as out_bytes is reached. if the true - /// amount of bytes decoded spills over that amount, they will be kept for - /// a later invocation of qtmd_decompress(). - /// - /// - the output bytes will be passed to the system.write() function given in - /// qtmd_init(), using the output file handle given in qtmd_init(). More - /// than one call may be made to system.write() - /// - /// - Quantum will read input bytes as necessary using the system.read() - /// function given in qtmd_init(), using the input file handle given in - /// qtmd_init(). This will continue until system.read() returns 0 bytes, - /// or an error. - /// - public Error Decompress(long out_bytes) - { - uint frame_todo, frame_end, window_posn, match_offset, range; - byte[] window; - int runsrc, rundest; - int i, j, selector, extra, sym, match_length; - ushort H, L, C, symf; - - // Easy answers - if (out_bytes < 0) - return Error.MSPACK_ERR_ARGS; - - if (Error != Error.MSPACK_ERR_OK) - return Error; - - // Flush out any stored-up bytes before we begin - i = OutputEnd - OutputPointer; - if (i > out_bytes) - i = (int)out_bytes; - - if (i > 0) - { - if (System.Write(OutputFileHandle, Window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - OutputPointer += i; - out_bytes -= i; - } - - if (out_bytes == 0) - return Error.MSPACK_ERR_OK; - - // Restore local state - window = Window; - window_posn = WindowPosition; - frame_todo = FrameTODO; - H = High; - L = Low; - C = Current; - - // While we do not have enough decoded bytes in reserve - while ((OutputEnd - OutputPointer) < out_bytes) - { - // Read header if necessary. Initialises H, L and C - if (HeaderRead != 0) - { - H = 0xFFFF; - L = 0; - C = (ushort)READ_BITS_MSB(16); - HeaderRead = 1; - } - - // Decode more, up to the number of bytes needed, the frame boundary, - // or the window boundary, whichever comes first - frame_end = (uint)(window_posn + (out_bytes - (OutputEnd - OutputPointer))); - if ((window_posn + frame_todo) < frame_end) - frame_end = window_posn + frame_todo; - if (frame_end > WindowSize) - frame_end = WindowSize; - - while (window_posn < frame_end) - { - selector = GET_SYMBOL(Model7, ref H, ref L, ref C); - if (selector < 4) - { - // Literal byte - QTMDModel mdl; - switch (selector) - { - case 0: - mdl = Model0; - break; - - case 1: - mdl = Model1; - break; - - case 2: - mdl = Model2; - break; - - case 3: - default: - mdl = Model3; - break; - } - - sym = GET_SYMBOL(mdl, ref H, ref L, ref C); - window[window_posn++] = (byte)sym; - frame_todo--; - } - else - { - // Match repeated string - switch (selector) - { - // Selector 4 = fixed length match (3 bytes) - case 4: - sym = GET_SYMBOL(Model4, ref H, ref L, ref C); - extra = (int)READ_MANY_BITS_MSB(QTMExtraBits[sym]); - match_offset = (uint)(QTMPositionBase[sym] + extra + 1); - match_length = 3; - break; - - // Selector 5 = fixed length match (4 bytes) - case 5: - sym = GET_SYMBOL(Model5, ref H, ref L, ref C); - extra = (int)READ_MANY_BITS_MSB(QTMExtraBits[sym]); - match_offset = (uint)(QTMPositionBase[sym] + extra + 1); - match_length = 4; - break; - - // Selector 6 = variable length match - case 6: - sym = GET_SYMBOL(Model6Len, ref H, ref L, ref C); - extra = (int)READ_MANY_BITS_MSB(QTMLengthExtra[sym]); - match_length = QTMLengthBase[sym] + extra + 5; - - sym = GET_SYMBOL(Model6, ref H, ref L, ref C); - extra = (int)READ_MANY_BITS_MSB(QTMExtraBits[sym]); - match_offset = (uint)(QTMPositionBase[sym] + extra + 1); - break; - - default: - // Should be impossible, model7 can only return 0-6 - Console.WriteLine($"Got {selector} from selector"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - rundest = (int)window_posn; - frame_todo -= (uint)match_length; - - // Does match destination wrap the window? This situation is possible - // where the window size is less than the 32k frame size, but matches - // must not go beyond a frame boundary - if ((window_posn + match_length) > WindowSize) - { - // Copy first part of match, before window end - i = (int)(WindowSize - window_posn); - j = (int)(window_posn - match_offset); - - while (i-- > 0) - { - window[rundest++] = window[j++ & (WindowSize - 1)]; - } - - // Flush currently stored data - i = (int)(WindowSize - OutputPointer); - - // This should not happen, but if it does then this code - // can't handle the situation (can't flush up to the end of - // the window, but can't break out either because we haven't - // finished writing the match). Bail out in this case - if (i > out_bytes) - { - Console.WriteLine($"During window-wrap match; {i} bytes to flush but only need {out_bytes}"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - if (System.Write(OutputFileHandle, window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - out_bytes -= i; - OutputPointer = 0; - OutputEnd = 0; - - // Copy second part of match, after window wrap - rundest = 0; - i = (int)(match_length - (WindowSize - window_posn)); - while (i-- > 0) - { - window[rundest++] = window[j++ & (WindowSize - 1)]; - } - - window_posn = (uint)(window_posn + match_length - WindowSize); - - break; // Because "window_posn < frame_end" has now failed - } - else - { - // Normal match - output won't wrap window or frame end - i = match_length; - - // Does match _offset_ wrap the window? - if (match_offset > window_posn) - { - // j = length from match offset to end of window - j = (int)(match_offset - window_posn); - if (j > (int)WindowSize) - { - Console.WriteLine("Match offset beyond window boundaries"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - runsrc = (int)(WindowSize - j); - if (j < i) - { - // If match goes over the window edge, do two copy runs - i -= j; - while (j-- > 0) - { - window[rundest++] = window[runsrc++]; - } - - runsrc = 0; - } - - while (i-- > 0) - { - window[rundest++] = window[runsrc++]; - } - } - else - { - runsrc = (int)(rundest - match_offset); - while (i-- > 0) - { - window[rundest++] = window[runsrc++]; - } - } - - window_posn += (uint)match_length; - } - } - } - - OutputEnd = (int)window_posn; - - // If we subtracted too much from frame_todo, it will - // wrap around past zero and go above its max value - if (frame_todo > QTM_FRAME_SIZE) - { - Console.WriteLine("Overshot frame alignment"); - return Error = Error.MSPACK_ERR_DECRUNCH; - } - - // Another frame completed? - if (frame_todo == 0) - { - // Re-align input - if ((BitsLeft & 7) != 0) - REMOVE_BITS_MSB(BitsLeft & 7); - - // Special Quantum hack -- cabd.c injects a trailer byte to allow the - // decompressor to realign itself. CAB Quantum blocks, unlike LZX - // blocks, can have anything from 0 to 4 trailing null bytes. - do - { - i = (int)READ_BITS_MSB(8); - } while (i != 0xFF); - - HeaderRead = 0; - - frame_todo = QTM_FRAME_SIZE; - } - - // Window wrap? - if (window_posn == WindowSize) - { - // Flush all currently stored data - i = (OutputEnd - OutputPointer); - - // Break out if we have more than enough to finish this request - if (i >= out_bytes) - break; - - if (System.Write(OutputFileHandle, window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - out_bytes -= i; - OutputPointer = 0; - OutputEnd = 0; - window_posn = 0; - } - - } - - if (out_bytes > 0) - { - i = (int)out_bytes; - - if (System.Write(OutputFileHandle, window, OutputPointer, i) != i) - return Error = Error.MSPACK_ERR_WRITE; - - OutputPointer += i; - } - - // Store local state - WindowPosition = window_posn; - FrameTODO = frame_todo; - High = H; - Low = L; - Current = C; - - return Error.MSPACK_ERR_OK; - } - - private ushort GET_SYMBOL(QTMDModel model, ref ushort H, ref ushort L, ref ushort C) - { - uint range = (uint)((H - L) & 0xFFFF) + 1; - ushort symf = (ushort)(((((C - L + 1) * model.Syms[0].CumulativeFrequency) - 1) / range) & 0xFFFF); - - int i = 1; - for (; i < model.Entries; i++) - { - if (model.Syms[i].CumulativeFrequency <= symf) - break; - } - - ushort temp = model.Syms[i - 1].Sym; - - range = (uint)(H - L) + 1; - symf = model.Syms[0].CumulativeFrequency; - H = (ushort)(L + ((model.Syms[i - 1].CumulativeFrequency * range) / symf) - 1); - L = (ushort)(L + ((model.Syms[i].CumulativeFrequency * range) / symf)); - - do - { - model.Syms[--i].CumulativeFrequency += 8; - } while (i > 0); - - if (model.Syms[0].CumulativeFrequency > 3800) - UpdateModel(model); - - while (true) - { - if ((L & 0x8000) != (H & 0x8000)) - { - if ((L & 0x4000) != 0 && (H & 0x4000) == 0) - { - // Underflow case - C ^= 0x4000; - L &= 0x3FFF; - H |= 0x4000; - } - else - { - break; - } - } - - L <<= 1; - H = (ushort)((H << 1) | 1); - - ENSURE_BITS(1); - C = (ushort)((C << 1) | (PEEK_BITS_MSB(1))); - REMOVE_BITS_MSB(1); - } - - return temp; - } - - private void UpdateModel(QTMDModel model) - { - QTMDModelSym tmp; - int i, j; - - if (--model.ShiftsLeft > 0) - { - for (i = model.Entries - 1; i >= 0; i--) - { - // -1, not -2; the 0 entry saves this - model.Syms[i].CumulativeFrequency >>= 1; - if (model.Syms[i].CumulativeFrequency <= model.Syms[i + 1].CumulativeFrequency) - model.Syms[i].CumulativeFrequency = (ushort)(model.Syms[i + 1].CumulativeFrequency + 1); - } - } - else - { - model.ShiftsLeft = 50; - for (i = 0; i < model.Entries; i++) - { - // No -1, want to include the 0 entry - - // This converts CumFreqs into frequencies, then shifts right - model.Syms[i].CumulativeFrequency -= model.Syms[i + 1].CumulativeFrequency; - model.Syms[i].CumulativeFrequency++; // Avoid losing things entirely - model.Syms[i].CumulativeFrequency >>= 1; - } - - // Now sort by frequencies, decreasing order -- this must be an - // inplace selection sort, or a sort with the same (in)stability - // characteristics - for (i = 0; i < model.Entries - 1; i++) - { - for (j = i + 1; j < model.Entries; j++) - { - if (model.Syms[i].CumulativeFrequency < model.Syms[j].CumulativeFrequency) - { - tmp = model.Syms[i]; - model.Syms[i] = model.Syms[j]; - model.Syms[j] = tmp; - } - } - } - - // Then convert frequencies back to CumFreq - for (i = model.Entries - 1; i >= 0; i--) - { - model.Syms[i].CumulativeFrequency += model.Syms[i + 1].CumulativeFrequency; - } - } - } - - private void InitModel(QTMDModel model, QTMDModelSym[] syms, int start, int len) - { - model.ShiftsLeft = 4; - model.Entries = len; - model.Syms = syms; - - for (int i = 0; i <= len; i++) - { - // Actual symbol - syms[i].Sym = (ushort)(start + i); - - // Current frequency of that symbol - syms[i].CumulativeFrequency = (ushort)(len - i); - } - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/QTM.ReadBits.cs b/BurnOutSharp/External/libmspack/Compression/QTM.ReadBits.cs deleted file mode 100644 index 83ce7f6c..00000000 --- a/BurnOutSharp/External/libmspack/Compression/QTM.ReadBits.cs +++ /dev/null @@ -1,34 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The Quantum method was created by David Stafford, adapted by Microsoft - * Corporation. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public partial class QTM : CompressionStream - { - /// - public override void READ_BYTES() - { - READ_IF_NEEDED(); - if (Error != Error.MSPACK_ERR_OK) - return; - - byte b0 = InputBuffer[InputPointer++]; - - READ_IF_NEEDED(); - if (Error != Error.MSPACK_ERR_OK) - return; - - byte b1 = InputBuffer[InputPointer++]; - INJECT_BITS_MSB((b0 << 8) | b1, 16); - } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/QTM.ReadHuff.cs b/BurnOutSharp/External/libmspack/Compression/QTM.ReadHuff.cs deleted file mode 100644 index 96b62bb9..00000000 --- a/BurnOutSharp/External/libmspack/Compression/QTM.ReadHuff.cs +++ /dev/null @@ -1,22 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The Quantum method was created by David Stafford, adapted by Microsoft - * Corporation. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.Compression -{ - public partial class QTM : CompressionStream - { - /// - public override Error HUFF_ERROR() => throw new NotImplementedException(); - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/QTM.cs b/BurnOutSharp/External/libmspack/Compression/QTM.cs deleted file mode 100644 index 33bc9f3e..00000000 --- a/BurnOutSharp/External/libmspack/Compression/QTM.cs +++ /dev/null @@ -1,123 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The Quantum method was created by David Stafford, adapted by Microsoft - * Corporation. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public partial class QTM : CompressionStream - { - /// - /// Decoding window - /// - public byte[] Window { get; set; } - - /// - /// Window size - /// - public uint WindowSize { get; set; } - - /// - /// Decompression offset within window - /// - public uint WindowPosition { get; set; } - - /// - /// Bytes remaining for current frame - /// - public uint FrameTODO { get; set; } - - /// - /// High: arith coding state - /// - public ushort High { get; set; } - - /// - /// Low: arith coding state - /// - public ushort Low { get; set; } - - /// - /// Current: arith coding state - /// - public ushort Current { get; set; } - - /// - /// Have we started decoding a new frame? - /// - public byte HeaderRead { get; set; } - - // Four literal models, each representing 64 symbols - - /// - /// For literals from 0 to 63 (selector = 0) - /// - public QTMDModel Model0 { get; set; } - - /// - /// For literals from 64 to 127 (selector = 1) - /// - public QTMDModel Model1 { get; set; } - - /// - /// For literals from 128 to 191 (selector = 2) - /// - public QTMDModel Model2 { get; set; } - - /// - /// For literals from 129 to 255 (selector = 3) - /// - public QTMDModel Model3 { get; set; } - - // Three match models. - - /// - /// For match with fixed length of 3 bytes - /// - public QTMDModel Model4 { get; set; } - - /// - /// For match with fixed length of 4 bytes - /// - public QTMDModel Model5 { get; set; } - - /// - /// For variable length match, encoded with model6len model - /// - public QTMDModel Model6 { get; set; } - - public QTMDModel Model6Len { get; set; } - - /// - /// Selector model. 0-6 to say literal (0,1,2,3) or match (4,5,6) - /// - public QTMDModel Model7 { get; set; } - - // Symbol arrays for all models - - public QTMDModelSym[] Model0Symbols { get; set; } = new QTMDModelSym[64 + 1]; - - public QTMDModelSym[] Model1Symbols { get; set; } = new QTMDModelSym[64 + 1]; - - public QTMDModelSym[] Model2Symbols { get; set; } = new QTMDModelSym[64 + 1]; - - public QTMDModelSym[] Model3Symbols { get; set; } = new QTMDModelSym[64 + 1]; - - public QTMDModelSym[] Model4Symbols { get; set; } = new QTMDModelSym[24 + 1]; - - public QTMDModelSym[] Model5Symbols { get; set; } = new QTMDModelSym[36 + 1]; - - public QTMDModelSym[] Model6Symbols { get; set; } = new QTMDModelSym[42 + 1]; - - public QTMDModelSym[] Model6LenSymbols { get; set; } = new QTMDModelSym[27 + 1]; - - public QTMDModelSym[] Model7Symbols { get; set; } = new QTMDModelSym[7 + 1]; - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/QTMDModel.cs b/BurnOutSharp/External/libmspack/Compression/QTMDModel.cs deleted file mode 100644 index a4dc09c8..00000000 --- a/BurnOutSharp/External/libmspack/Compression/QTMDModel.cs +++ /dev/null @@ -1,23 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The Quantum method was created by David Stafford, adapted by Microsoft - * Corporation. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public class QTMDModel - { - public int ShiftsLeft { get; set; } - - public int Entries { get; set; } - - public QTMDModelSym[] Syms { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/Compression/QTMDModelSym.cs b/BurnOutSharp/External/libmspack/Compression/QTMDModelSym.cs deleted file mode 100644 index 75af0fda..00000000 --- a/BurnOutSharp/External/libmspack/Compression/QTMDModelSym.cs +++ /dev/null @@ -1,21 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * The Quantum method was created by David Stafford, adapted by Microsoft - * Corporation. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.Compression -{ - public class QTMDModelSym - { - public ushort Sym { get; set; } - - public ushort CumulativeFrequency { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/Constants.cs b/BurnOutSharp/External/libmspack/Constants.cs deleted file mode 100644 index 82871f2c..00000000 --- a/BurnOutSharp/External/libmspack/Constants.cs +++ /dev/null @@ -1,158 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2004 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp -{ - internal class Constants - { - #region CAB - - // CAB data blocks are <= 32768 bytes in uncompressed form.Uncompressed - // blocks have zero growth. MSZIP guarantees that it won't grow above - // uncompressed size by more than 12 bytes.LZX guarantees it won't grow - // more than 6144 bytes.Quantum has no documentation, but the largest - // block seen in the wild is 337 bytes above uncompressed size. - - public const int CAB_BLOCKMAX = 32768; - public const int CAB_INPUTMAX = CAB_BLOCKMAX + 6144; - - // input buffer needs to be CAB_INPUTMAX + 1 byte to allow for max-sized block - // plus 1 trailer byte added by cabd_sys_read_block() for Quantum alignment. - // - // When MSCABD_PARAM_SALVAGE is set, block size is not checked so can be - // up to 65535 bytes, so max input buffer size needed is 65535 + 1 - - public const int CAB_INPUTMAX_SALVAGE = 65535; - public const int CAB_INPUTBUF = CAB_INPUTMAX_SALVAGE + 1; - - // There are no more than 65535 data blocks per folder, so a folder cannot - // be more than 32768*65535 bytes in length.As files cannot span more than - // one folder, this is also their max offset, length and offset+length limit. - - public const int CAB_FOLDERMAX = 65535; - public const int CAB_LENGTHMAX = CAB_BLOCKMAX * CAB_FOLDERMAX; - - #endregion - - #region CHM - - // Filenames of the system files used for decompression. - // - Content and ControlData are essential. - // - ResetTable is preferred, but SpanInfo can be used if not available - public const string ContentName = "::DataSpace/Storage/MSCompressed/Content"; - public const string ControlName = "::DataSpace/Storage/MSCompressed/ControlData"; - public const string SpanInfoName = "::DataSpace/Storage/MSCompressed/SpanInfo"; - public const string ResetTableName = "::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable"; - - #endregion - - #region HLP - - // None currently - - #endregion - - #region KWAJ - - // Input buffer size during decompression - not worth parameterising IMHO - public const int KWAJ_INPUT_SIZE = (2048); - - // Huffman codes that are 9 bits or less are decoded immediately - public const int KWAJ_TABLEBITS = (9); - - // Number of codes in each huffman table - - public const int KWAJ_MATCHLEN1_SYMS = (16); - public const int KWAJ_MATCHLEN2_SYMS = (16); - public const int KWAJ_LITLEN_SYMS = (32); - public const int KWAJ_OFFSET_SYMS = (64); - public const int KWAJ_LITERAL_SYMS = (256); - - // Define decoding table sizes - - public const int KWAJ_TABLESIZE = (1 << KWAJ_TABLEBITS); - - //public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_MATCHLEN1_SYMS * 4); - public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_MATCHLEN1_SYMS * 2)); - - //public const int KWAJ_MATCHLEN2_TBLSIZE = (KWAJ_MATCHLEN2_SYMS * 4); - public const int KWAJ_MATCHLEN2_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_MATCHLEN2_SYMS * 2)); - - //public const int KWAJ_LITLEN_TBLSIZE = (KWAJ_LITLEN_SYMS * 4); - public const int KWAJ_LITLEN_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_LITLEN_SYMS * 2)); - - //public const int KWAJ_OFFSET_TBLSIZE = (KWAJ_OFFSET_SYMS * 4); - public const int KWAJ_OFFSET_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_OFFSET_SYMS * 2)); - - //public const int KWAJ_LITERAL_TBLSIZE = (KWAJ_LITERAL_SYMS * 4); - public const int KWAJ_LITERAL_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_LITERAL_SYMS * 2)); - - #endregion - - #region LIT - - // None currently - - #endregion - - #region OAB - - // _Header - public const int oabhead_VersionHi = 0x0000; - public const int oabhead_VersionLo = 0x0004; - public const int oabhead_BlockMax = 0x0008; - public const int oabhead_TargetSize = 0x000c; - public const int oabhead_SIZEOF = 0x0010; - - // _Block - public const int oabblk_Flags = 0x0000; - public const int oabblk_CompSize = 0x0004; - public const int oabblk_UncompSize = 0x0008; - public const int oabblk_CRC = 0x000c; - public const int oabblk_SIZEOF = 0x0010; - - // _PatchHeader - public const int patchhead_VersionHi = 0x0000; - public const int patchhead_VersionLo = 0x0004; - public const int patchhead_BlockMax = 0x0008; - public const int patchhead_SourceSize = 0x000c; - public const int patchhead_TargetSize = 0x0010; - public const int patchhead_SourceCRC = 0x0014; - public const int patchhead_TargetCRC = 0x0018; - public const int patchhead_SIZEOF = 0x001c; - - // _PatchBlock - public const int patchblk_PatchSize = 0x0000; - public const int patchblk_TargetSize = 0x0004; - public const int patchblk_SourceSize = 0x0008; - public const int patchblk_CRC = 0x000c; - public const int patchblk_SIZEOF = 0x0010; - - #endregion - - #region SZDD - - /// - /// Input buffer size during decompression - not worth parameterising IMHO - /// - public const int SZDD_INPUT_SIZE = 2048; - - public static readonly byte[] expandSignature = new byte[8] - { - 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33 - }; - - public static readonly byte[] qbasicSignature = new byte[8] - { - 0x53, 0x5A, 0x20, 0x88, 0xF0, 0x27, 0x33, 0xD1 - }; - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/Enums.cs b/BurnOutSharp/External/libmspack/Enums.cs deleted file mode 100644 index 0acb3d44..00000000 --- a/BurnOutSharp/External/libmspack/Enums.cs +++ /dev/null @@ -1,293 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp -{ - /// - /// All compressors and decompressors use the same set of error codes. Most - /// methods return an error code directly.For methods which do not - /// return error codes directly, the error code can be obtained with the - /// last_error() method. - /// - public enum Error - { - #region MSPACK Errors - - /// - /// Used to indicate success. - /// This error code is defined as zero, all other code are non-zero. - /// - MSPACK_ERR_OK = 0, - - /// - /// A method was called with inappropriate arguments. - /// - MSPACK_ERR_ARGS = 1, - - /// - /// Error opening file - /// - MSPACK_ERR_OPEN = 2, - - /// - /// Error reading file - /// - MSPACK_ERR_READ = 3, - - /// - /// Error writing file - /// - MSPACK_ERR_WRITE = 4, - - /// - /// Seek error - /// - MSPACK_ERR_SEEK = 5, - - /// - /// Out of memory - /// - MSPACK_ERR_NOMEMORY = 6, - - /// - /// Bad "magic id" in file - /// - MSPACK_ERR_SIGNATURE = 7, - - /// - /// Bad or corrupt file format - /// - MSPACK_ERR_DATAFORMAT = 8, - - /// - /// Bad checksum or CRC - /// - MSPACK_ERR_CHECKSUM = 9, - - /// - /// Error during compression - /// - MSPACK_ERR_CRUNCH = 10, - - /// - /// Error during decompression - /// - MSPACK_ERR_DECRUNCH = 11, - - #endregion - - #region Inflate Errors - - /// - /// Unknown block type - /// - INF_ERR_BLOCKTYPE = -1, - - /// - /// Block size complement mismatch - /// - INF_ERR_COMPLEMENT = -2, - - /// - /// Error from flush_window callback - /// - INF_ERR_FLUSH = -3, - - /// - /// Too many bits in bit buffer - /// - INF_ERR_BITBUF = -4, - - /// - /// Too many symbols in blocktype 2 header - /// - INF_ERR_SYMLENS = -5, - - /// - /// Failed to build bitlens huffman table - /// - INF_ERR_BITLENTBL = -6, - - /// - /// Failed to build literals huffman table - /// - INF_ERR_LITERALTBL = -7, - - /// - /// Failed to build distance huffman table - /// - INF_ERR_DISTANCETBL = -8, - - /// - /// Bitlen RLE code goes over table size - /// - INF_ERR_BITOVERRUN = -9, - - /// - /// Invalid bit-length code - /// - INF_ERR_BADBITLEN = -10, - - /// - /// Out-of-range literal code - /// - INF_ERR_LITCODE = -11, - - /// - /// Out-of-range distance code - /// - INF_ERR_DISTCODE = -12, - - /// - /// Somehow, distance is beyond 32k - /// - INF_ERR_DISTANCE = -13, - - /// - /// Out of bits decoding huffman symbol - /// - INF_ERR_HUFFSYM = -14, - - #endregion - } - - /// - /// The interface to request current version of - /// - public enum Interfaces - { - /// - /// Pass to mspack_version() to get the overall library version - /// - MSPACK_VER_LIBRARY = 0, - - /// - /// Pass to mspack_version() to get the mspack_system version - /// - MSPACK_VER_SYSTEM = 1, - - /// - /// Pass to mspack_version() to get the mscab_decompressor version - /// - MSPACK_VER_MSCABD = 2, - - /// - /// Pass to mspack_version() to get the mscab_compressor version - /// - MSPACK_VER_MSCABC = 3, - - /// - /// Pass to mspack_version() to get the mschm_decompressor version - /// - MSPACK_VER_MSCHMD = 4, - - /// - /// Pass to mspack_version() to get the mschm_compressor version - /// - MSPACK_VER_MSCHMC = 5, - - /// - /// Pass to mspack_version() to get the mslit_decompressor version - /// - MSPACK_VER_MSLITD = 6, - - /// - /// Pass to mspack_version() to get the mslit_compressor version - /// - MSPACK_VER_MSLITC = 7, - - /// - /// Pass to mspack_version() to get the mshlp_decompressor version - /// - MSPACK_VER_MSHLPD = 8, - - /// - /// Pass to mspack_version() to get the mshlp_compressor version - /// - MSPACK_VER_MSHLPC = 9, - - /// - /// Pass to mspack_version() to get the msszdd_decompressor version - /// - MSPACK_VER_MSSZDDD = 10, - - /// - /// Pass to mspack_version() to get the msszdd_compressor version - /// - MSPACK_VER_MSSZDDC = 11, - - /// - /// Pass to mspack_version() to get the mskwaj_decompressor version - /// - MSPACK_VER_MSKWAJD = 12, - - /// - /// Pass to mspack_version() to get the mskwaj_compressor version - /// - MSPACK_VER_MSKWAJC = 13, - - /// - /// Pass to mspack_version() to get the msoab_decompressor version - /// - MSPACK_VER_MSOABD = 14, - - /// - /// Pass to mspack_version() to get the msoab_compressor version - /// - MSPACK_VER_MSOABC = 15, - } - - public enum OpenMode - { - /// - /// mspack_system::open() mode: open existing file for reading. - /// - MSPACK_SYS_OPEN_READ = 0, - - /// - /// mspack_system::open() mode: open new file for writing - /// - MSPACK_SYS_OPEN_WRITE = 1, - - /// - /// mspack_system::open() mode: open existing file for writing - /// - MSPACK_SYS_OPEN_UPDATE = 2, - - /// - /// mspack_system::open() mode: open existing file for writing - /// - MSPACK_SYS_OPEN_APPEND = 3, - } - - public enum SeekMode - { - /// - /// mspack_system::seek() mode: seek relative to start of file - /// - MSPACK_SYS_SEEK_START = 0, - - /// - /// mspack_system::seek() mode: seek relative to current offset - /// - MSPACK_SYS_SEEK_CUR = 1, - - /// - /// mspack_system::seek() mode: seek relative to end of file - /// - MSPACK_SYS_SEEK_END = 2, - } -} diff --git a/BurnOutSharp/External/libmspack/HLP/Compressor.cs b/BurnOutSharp/External/libmspack/HLP/Compressor.cs deleted file mode 100644 index 5017a0d9..00000000 --- a/BurnOutSharp/External/libmspack/HLP/Compressor.cs +++ /dev/null @@ -1,24 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.HLP -{ - // TODO - public class Compressor - { - public SystemImpl System { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/HLP/Decompressor.cs b/BurnOutSharp/External/libmspack/HLP/Decompressor.cs deleted file mode 100644 index 82fa31c7..00000000 --- a/BurnOutSharp/External/libmspack/HLP/Decompressor.cs +++ /dev/null @@ -1,23 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.HLP -{ - public class Decompressor : BaseDecompressor - { - // TODO - } -} diff --git a/BurnOutSharp/External/libmspack/KWAJ/Compressor.cs b/BurnOutSharp/External/libmspack/KWAJ/Compressor.cs deleted file mode 100644 index c246a4c3..00000000 --- a/BurnOutSharp/External/libmspack/KWAJ/Compressor.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; - -namespace LibMSPackSharp.KWAJ -{ - /// - /// A compressor for the KWAJ file format. - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Compressor - { - #region Fields - - public SystemImpl System { get; set; } - - /// - /// !!! MATCH THIS TO NUM OF PARAMS IN MSPACK.H !!! - /// - public int[] Param { get; set; } = new int[2]; - - public Error Error { get; set; } - - #endregion - - /// - /// Reads an input file and creates a compressed output file in the - /// KWAJ compressed file format.The KWAJ compression format is quick - /// but gives poor compression.It is possible for the compressed output - /// file to be larger than the input file. - /// - /// - /// the name of the file to compressed. This is passed - /// passed directly to mspack_system::open() - /// - /// - /// the name of the file to write compressed data to. - /// This is passed directly to mspack_system::open(). - /// - /// - /// the length of the uncompressed file, or -1 to indicate - /// that this should be determined automatically by using - /// mspack_system::seek() on the input file. - /// - /// An error code, or MSPACK_ERR_OK if successful - /// - public Error Compress(string input, string output, long length) => throw new NotImplementedException(); - - /// - /// Sets an KWAJ compression engine parameter. - /// - /// The following parameters are defined: - /// - /// - #MSKWAJC_PARAM_COMP_TYPE: the compression method to use. Must - /// be one of #MSKWAJC_COMP_NONE, #MSKWAJC_COMP_XOR, #MSKWAJ_COMP_SZDD - /// or #MSKWAJ_COMP_LZH. The default is #MSKWAJ_COMP_LZH. - /// - /// - #MSKWAJC_PARAM_INCLUDE_LENGTH: a boolean; should the compressed - /// output file should include the uncompressed length of the input - /// file in the header? This adds 4 bytes to the size of the output - /// file. A value of zero says "no", non-zero says "yes". The default - /// is "no". - /// - /// the parameter to set - /// the value to set the parameter to - /// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there - /// is a problem with either parameter or value. - /// - /// - public Error SetParam(Parameters param, int value) => throw new NotImplementedException(); - - /// - /// Sets the original filename of the file before compression, - /// which will be stored in the header of the output file. - /// - /// The filename should be a null-terminated string, it must be an - /// MS-DOS "8.3" type filename (up to 8 bytes for the filename, then - /// optionally a "." and up to 3 bytes for a filename extension). - /// - /// If null is passed as the filename, no filename is included in the - /// header. This is the default. - /// - /// The original filename to use - /// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if the filename is too long - public Error SetFilename(string filename) => throw new NotImplementedException(); - - /// - /// Sets arbitrary data that will be stored in the header of the - /// output file, uncompressed. It can be up to roughly 64 kilobytes, - /// as the overall size of the header must not exceed 65535 bytes. - /// The data can contain null bytes if desired. - /// - /// If null is passed as the data pointer, or zero is passed as the - /// length, no extra data is included in the header. This is the - /// default. - /// - /// a pointer to the data to be stored in the header - /// the length of the data in bytes - /// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS extra data is too long - public Error SetExtraData(byte[] data, int pointer, int bytes) => throw new NotImplementedException(); - } -} diff --git a/BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs b/BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs deleted file mode 100644 index 8d85f023..00000000 --- a/BurnOutSharp/External/libmspack/KWAJ/Decompressor.cs +++ /dev/null @@ -1,352 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; -using System.IO; -using System.Text; -using LibMSPackSharp.Compression; -using static LibMSPackSharp.Constants; - -namespace LibMSPackSharp.KWAJ -{ - /// - /// A decompressor for KWAJ compressed files. - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Decompressor : BaseDecompressor - { - #region Public Functionality - - /// - /// Opens a KWAJ file and reads the header. - /// - /// If the file opened is a valid KWAJ file, all headers will be read and - /// a mskwajd_header structure will be returned. - /// - /// In the case of an error occuring, NULL is returned and the error code - /// is available from last_error(). - /// - /// The filename pointer should be considered "in use" until close() is - /// called on the KWAJ file. - /// - /// - /// the filename of the KWAJ compressed file. This is - /// passed directly to mspack_system::open(). - /// - /// A pointer to a mskwajd_header structure, or NULL on failure - /// - public Header Open(string filename) - { - FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (fh == null) - { - Error = Error.MSPACK_ERR_OPEN; - return null; - } - - Header hdr = new Header() { FileHandle = fh }; - - Error = ReadHeaders(fh, hdr); - if (Error != Error.MSPACK_ERR_OK) - { - System.Close(fh); - hdr = null; - } - - return hdr; - } - - /// - /// Closes a previously opened KWAJ file. - /// - /// This closes a KWAJ file and frees the mskwajd_header associated - /// with it. The KWAJ header pointer is now invalid and cannot be - /// used again. - /// - /// The KWAJ file to close - /// - public void Close(Header hdr) - { - if (System == null || hdr == null) - return; - - // Close the file handle associated - System.Close(hdr.FileHandle); - - Error = Error.MSPACK_ERR_OK; - } - - /// - /// Extracts the compressed data from a KWAJ file. - /// - /// This decompresses the compressed KWAJ data stream and writes it to - /// an output file. - /// - /// The KWAJ file to extract data from - /// - /// the filename to write the decompressed data to. This - /// is passed directly to mspack_system::open(). - /// - /// an error code, or MSPACK_ERR_OK if successful - public Error Extract(Header hdr, string filename) - { - FileStream fh = hdr?.FileHandle; - if (fh == null) - return Error.MSPACK_ERR_ARGS; - - // Seek to the compressed data - if (System.Seek(fh, hdr.KWAJHeader.DataOffset, SeekMode.MSPACK_SYS_SEEK_START)) - return Error = Error.MSPACK_ERR_SEEK; - - // Open file for output - FileStream outfh; - if ((outfh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE)) == null) - return Error = Error.MSPACK_ERR_OPEN; - - Error = Error.MSPACK_ERR_OK; - - // Decompress based on format - if (hdr.KWAJHeader.CompressionType == CompressionType.MSKWAJ_COMP_NONE || - hdr.KWAJHeader.CompressionType == CompressionType.MSKWAJ_COMP_XOR) - { - // NONE is a straight copy. XOR is a copy xored with 0xFF - byte[] buf = new byte[KWAJ_INPUT_SIZE]; - - int read, i; - while ((read = System.Read(fh, buf, 0, KWAJ_INPUT_SIZE)) > 0) - { - if (hdr.KWAJHeader.CompressionType == CompressionType.MSKWAJ_COMP_XOR) - { - for (i = 0; i < read; i++) - { - buf[i] ^= 0xFF; - } - } - - if (System.Write(outfh, buf, 0, read) != read) - { - Error = Error.MSPACK_ERR_WRITE; - break; - } - } - - if (read < 0) - Error = Error.MSPACK_ERR_READ; - } - else if (hdr.KWAJHeader.CompressionType == CompressionType.MSKWAJ_COMP_SZDD) - { - Error = LZSS.Decompress(System, fh, outfh, KWAJ_INPUT_SIZE, LZSSMode.LZSS_MODE_EXPAND); - } - else if (hdr.KWAJHeader.CompressionType == CompressionType.MSKWAJ_COMP_LZH) - { - LZHKWAJ lzh = LZHKWAJ.Init(System, fh, outfh); - Error = (lzh != null) ? lzh.Decompress() : Error.MSPACK_ERR_NOMEMORY; - } - else if (hdr.KWAJHeader.CompressionType == CompressionType.MSKWAJ_COMP_MSZIP) - { - MSZIP zip = MSZIP.Init(System, fh, outfh, KWAJ_INPUT_SIZE, false); - Error = (zip != null) ? zip.DecompressKWAJ() : Error.MSPACK_ERR_NOMEMORY; - } - else - { - Error = Error.MSPACK_ERR_DATAFORMAT; - } - - // Close output file - System.Close(outfh); - - return Error; - } - - /// - /// Decompresses an KWAJ file to an output file in one step. - /// - /// This opens an KWAJ file as input, reads the header, then decompresses - /// the compressed data immediately to an output file, finally closing - /// both the input and output file. It is more convenient to use than - /// open() then extract() then close(), if you do not need to know the - /// KWAJ output size or output filename. - /// - /// - /// a self-referential pointer to the mskwaj_decompressor - /// instance being called - /// - /// - /// the filename of the input KWAJ file. This is passed - /// directly to mspack_system::open(). - /// - /// - /// the filename to write the decompressed data to. This - /// is passed directly to mspack_system::open(). - /// - /// an error code, or MSPACK_ERR_OK if successful - public Error Decompress(string input, string output) - { - Header hdr = Open(input); - if (hdr == null) - return Error; - - Error error = Extract(hdr, output); - Close(hdr); - return Error = error; - } - - #endregion - - #region Helpers - - /// - /// Reads the headers of a KWAJ format file - /// - private Error ReadHeaders(FileStream fh, Header hdr) - { - // Read in the header - byte[] buf = new byte[16]; - if (System.Read(fh, buf, 0, _KWAJHeader.Size) != _KWAJHeader.Size) - return Error.MSPACK_ERR_READ; - - // Create a new header based on that - Error err = _KWAJHeader.Create(buf, out _KWAJHeader kwajHeader); - if (err != Error.MSPACK_ERR_OK) - return Error = err; - - // Assign the header - hdr.KWAJHeader = kwajHeader; - - // Basic header fields - hdr.Length = 0; - hdr.Filename = null; - hdr.Extra = null; - hdr.ExtraLength = 0; - - // Optional headers - - // 4 bytes: length of unpacked file - if (hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASLENGTH)) - { - if (System.Read(fh, buf, 0, 4) != 4) - return Error.MSPACK_ERR_READ; - - hdr.Length = BitConverter.ToUInt32(buf, 0); - } - - // 2 bytes: unknown purpose - if (hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASUNKNOWN1)) - { - if (System.Read(fh, buf, 0, 2) != 2) - return Error.MSPACK_ERR_READ; - } - - // 2 bytes: length of section, then [length] bytes: unknown purpose - if (hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASUNKNOWN2)) - { - if (System.Read(fh, buf, 0, 2) != 2) - return Error.MSPACK_ERR_READ; - - int i = BitConverter.ToUInt16(buf, 0); - if (System.Seek(fh, i, SeekMode.MSPACK_SYS_SEEK_CUR)) - return Error.MSPACK_ERR_SEEK; - } - - // Filename and extension - if (hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILENAME) || hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILEEXT)) - { - int len; - - // Allocate memory for maximum length filename - char[] fn = new char[13]; - int fnPtr = 0; - - // Copy filename if present - if (hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILENAME)) - { - // Read and copy up to 9 bytes of a null terminated string - if ((len = System.Read(fh, buf, 0, 9)) < 2) - return Error.MSPACK_ERR_READ; - - int i = 0; - for (; i < len; i++) - { - if ((fn[fnPtr++] = (char)buf[i]) == '\0') - break; - } - - // If string was 9 bytes with no null terminator, reject it - if (i == 9 && buf[8] != '\0') - return Error.MSPACK_ERR_DATAFORMAT; - - // Seek to byte after string ended in file - if (System.Seek(fh, i + 1 - len, SeekMode.MSPACK_SYS_SEEK_CUR)) - return Error.MSPACK_ERR_SEEK; - - fnPtr--; // Remove the null terminator - } - - // Copy extension if present - if (hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASFILEEXT)) - { - fn[fnPtr++] = '.'; - - // Read and copy up to 4 bytes of a null terminated string - if ((len = System.Read(fh, buf, 0, 4)) < 2) - return Error.MSPACK_ERR_READ; - - int i = 0; - for (; i < len; i++) - { - if ((fn[fnPtr++] = (char)buf[i]) == '\0') - break; - } - - // If string was 4 bytes with no null terminator, reject it - if (i == 4 && buf[3] != '\0') - return Error.MSPACK_ERR_DATAFORMAT; - - // Seek to byte after string ended in file - if (System.Seek(fh, i + 1 - len, SeekMode.MSPACK_SYS_SEEK_CUR)) - return Error.MSPACK_ERR_SEEK; - - fnPtr--; // Remove the null terminator - } - - fn[fnPtr] = '\0'; - } - - // 2 bytes: extra text length then [length] bytes of extra text data - if (hdr.KWAJHeader.Flags.HasFlag(OptionalHeaderFlag.MSKWAJ_HDR_HASEXTRATEXT)) - { - if (System.Read(fh, buf, 0, 2) != 2) - return Error.MSPACK_ERR_READ; - - int i = BitConverter.ToUInt16(buf, 0); - byte[] extra = new byte[i + 1]; - if (System.Read(fh, extra, 0, i) != i) - return Error.MSPACK_ERR_READ; - - extra[i] = 0x00; - hdr.Extra = Encoding.ASCII.GetString(extra, 0, extra.Length); - hdr.ExtraLength = (ushort)i; - } - - return Error.MSPACK_ERR_OK; - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/KWAJ/Enums.cs b/BurnOutSharp/External/libmspack/KWAJ/Enums.cs deleted file mode 100644 index d79f3856..00000000 --- a/BurnOutSharp/External/libmspack/KWAJ/Enums.cs +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.KWAJ -{ - public enum CompressionType - { - /// - /// no compression. - /// - MSKWAJ_COMP_NONE = 0, - - /// - /// no compression, 0xFF XOR "encryption". - /// - MSKWAJ_COMP_XOR = 1, - - /// - /// LZSS (same method as SZDD) - /// - MSKWAJ_COMP_SZDD = 2, - - /// - /// LZ+Huffman compression - /// - MSKWAJ_COMP_LZH = 3, - - /// - /// MSZIP - /// - MSKWAJ_COMP_MSZIP = 4, - } - - [Flags] - public enum OptionalHeaderFlag : ushort - { - /// - /// decompressed file length is included - /// - MSKWAJ_HDR_HASLENGTH = 0x01, - - /// - /// unknown 2-byte structure is included - /// - MSKWAJ_HDR_HASUNKNOWN1 = 0x02, - - /// - /// unknown multi-sized structure is included - /// - MSKWAJ_HDR_HASUNKNOWN2 = 0x04, - - /// - /// file name (no extension) is included - /// - MSKWAJ_HDR_HASFILENAME = 0x08, - - /// - /// file extension is included - /// - MSKWAJ_HDR_HASFILEEXT = 0x10, - - /// - /// extra text is included - /// - MSKWAJ_HDR_HASEXTRATEXT = 0x20, - } - - public enum Parameters - { - /// - /// Compression type - /// - MSKWAJC_PARAM_COMP_TYPE = 0, - - /// - /// Include the length of the uncompressed file in the header? - /// - MSKWAJC_PARAM_INCLUDE_LENGTH = 1, - } -} diff --git a/BurnOutSharp/External/libmspack/KWAJ/Header.cs b/BurnOutSharp/External/libmspack/KWAJ/Header.cs deleted file mode 100644 index 9d9dd4a7..00000000 --- a/BurnOutSharp/External/libmspack/KWAJ/Header.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System.IO; - -namespace LibMSPackSharp.KWAJ -{ - /// - /// A structure which represents an KWAJ compressed file. - /// - /// All fields are READ ONLY. - /// - public class Header : BaseHeader - { - #region Internal - - /// - /// KWAJ header information - /// - internal _KWAJHeader KWAJHeader { get; set; } - - #endregion - - /// - /// Flags indicating which optional headers were included. - /// - public OptionalHeaderFlag Headers { get; set; } - - /// - /// The amount of uncompressed data in the file, or 0 if not present. - /// - public long Length { get; set; } - - /// - /// Output filename, or NULL if not present - /// - public string Filename { get; set; } - - /// - /// Extra uncompressed data (usually text) in the header. - /// This data can contain nulls so use extra_length to get the size. - /// - public string Extra { get; set; } - - /// - /// Length of extra uncompressed data in the header - /// - public ushort ExtraLength { get; set; } - - /// - /// Internal file handle - /// - public FileStream FileHandle { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/KWAJ/_KWAJHeader.cs b/BurnOutSharp/External/libmspack/KWAJ/_KWAJHeader.cs deleted file mode 100644 index d6bd2d4c..00000000 --- a/BurnOutSharp/External/libmspack/KWAJ/_KWAJHeader.cs +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -using System; - -namespace LibMSPackSharp.KWAJ -{ - internal class _KWAJHeader - { - #region Fields - - /// - /// "KWAA" - /// - /// 0x00 - public uint Signature1 { get; private set; } - - /// - /// Signature extension - /// - /// 0x04 - public uint Signature2 { get; private set; } - - /// - /// The compression type - /// - /// 0x08 - public CompressionType CompressionType { get; private set; } - - /// - /// The offset in the file where the compressed data stream begins - /// - /// 0x0a - public ushort DataOffset { get; private set; } - - /// - /// - /// - public OptionalHeaderFlag Flags { get; private set; } - - /// - /// Total size of the KWAJ header in bytes - /// - public const int Size = 0x0e; - - #endregion - - /// - /// Private constructor - /// - private _KWAJHeader() { } - - /// - /// Create a _KWAJHeader from a byte array, if possible - /// - public static Error Create(byte[] buffer, out _KWAJHeader header) - { - header = null; - if (buffer == null || buffer.Length < Size) - return Error.MSPACK_ERR_READ; - - header = new _KWAJHeader(); - - header.Signature1 = BitConverter.ToUInt32(buffer, 0x00); - if (header.Signature1 != 0x4A41574B) - return Error.MSPACK_ERR_SIGNATURE; - - header.Signature2 = BitConverter.ToUInt32(buffer, 0x04); - if (header.Signature1 != 0xD127F088) - return Error.MSPACK_ERR_SIGNATURE; - - header.CompressionType = (CompressionType)BitConverter.ToUInt16(buffer, 0x08); - header.DataOffset = BitConverter.ToUInt16(buffer, 0x0a); - header.Flags = (OptionalHeaderFlag)BitConverter.ToUInt16(buffer, 0x0c); - - return Error.MSPACK_ERR_OK; - } - } -} diff --git a/BurnOutSharp/External/libmspack/LIT/Compressor.cs b/BurnOutSharp/External/libmspack/LIT/Compressor.cs deleted file mode 100644 index 99ce6edb..00000000 --- a/BurnOutSharp/External/libmspack/LIT/Compressor.cs +++ /dev/null @@ -1,24 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.LIT -{ - // TODO - public class Compressor - { - public SystemImpl System { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/LIT/Decompressor.cs b/BurnOutSharp/External/libmspack/LIT/Decompressor.cs deleted file mode 100644 index 02ab30ba..00000000 --- a/BurnOutSharp/External/libmspack/LIT/Decompressor.cs +++ /dev/null @@ -1,23 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -namespace LibMSPackSharp.LIT -{ - public class Decompressor : BaseDecompressor - { - // TODO - } -} diff --git a/BurnOutSharp/External/libmspack/Library.cs b/BurnOutSharp/External/libmspack/Library.cs deleted file mode 100644 index d35a79d7..00000000 --- a/BurnOutSharp/External/libmspack/Library.cs +++ /dev/null @@ -1,499 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/** \mainpage - * - * \section intro Introduction - * - * libmspack is a library which provides compressors and decompressors, - * archivers and dearchivers for Microsoft compression formats. - * - * \section formats Formats supported - * - * The following file formats are supported: - * - SZDD files, which use LZSS compression - * - KWAJ files, which use LZSS, LZSS+Huffman or deflate compression - * - .HLP (MS Help) files, which use LZSS compression - * - .CAB (MS Cabinet) files, which use deflate, LZX or Quantum compression - * - .CHM (HTML Help) files, which use LZX compression - * - .LIT (MS EBook) files, which use LZX compression and DES encryption - * - .LZX (Exchange Offline Addressbook) files, which use LZX compression - * - * To determine the capabilities of the library, and the binary - * compatibility version of any particular compressor or decompressor, use - * the mspack_version() function. The UNIX library interface version is - * defined as the highest-versioned library component. - * - * \section starting Getting started - * - * The macro MSPACK_SYS_SELFTEST() should be used to ensure the library can - * be used. In particular, it checks if the caller is using 32-bit file I/O - * when the library is compiled for 64-bit file I/O and vice versa. - * - * If compiled normally, the library includes basic file I/O and memory - * management functionality using the standard C library. This can be - * customised and replaced entirely by creating a SystemImpl structure. - * - * A compressor or decompressor for the required format must be - * instantiated before it can be used. Each construction function takes - * one parameter, which is either a pointer to a custom SystemImpl - * structure, or null to use the default. The instantiation returned, if - * not null, contains function pointers (methods) to work with the given - * file format. - * - * For compression: - * - CreateCABCompressor() creates a mscab_compressor - * - CreateCHMCompressor() creates a mschm_compressor - * - CreateLITCompressor() creates a mslit_compressor - * - CreateHLPCompressor() creates a mshlp_compressor - * - CreateSZDDCompressor() creates a msszdd_compressor - * - CreateKWAJCompressor() creates a mskwaj_compressor - * - CreateOABCompressor() creates a msoab_compressor - * - * For decompression: - * - mspack_create_cab_decompressor() creates a mscab_decompressor - * - mspack_create_chm_decompressor() creates a mschm_decompressor - * - mspack_create_lit_decompressor() creates a mslit_decompressor - * - mspack_create_hlp_decompressor() creates a mshlp_decompressor - * - mspack_create_szdd_decompressor() creates a msszdd_decompressor - * - mspack_create_kwaj_decompressor() creates a mskwaj_decompressor - * - mspack_create_oab_decompressor() creates a msoab_decompressor - * - * Once finished working with a format, each kind of - * compressor/decompressor has its own specific destructor: - * - mspack_destroy_cab_compressor() - * - mspack_destroy_cab_decompressor() - * - mspack_destroy_chm_compressor() - * - mspack_destroy_chm_decompressor() - * - mspack_destroy_lit_compressor() - * - mspack_destroy_lit_decompressor() - * - mspack_destroy_hlp_compressor() - * - mspack_destroy_hlp_decompressor() - * - mspack_destroy_szdd_compressor() - * - mspack_destroy_szdd_decompressor() - * - mspack_destroy_kwaj_compressor() - * - mspack_destroy_kwaj_decompressor() - * - mspack_destroy_oab_compressor() - * - mspack_destroy_oab_decompressor() - * - * Destroying a compressor or decompressor does not destroy any objects, - * structures or handles that have been created using that compressor or - * decompressor. Ensure that everything created or opened is destroyed or - * closed before compressor/decompressor is itself destroyed. - * - * \section threading Multi-threading - * - * libmspack methods are reentrant and multithreading-safe when each - * thread has its own compressor or decompressor. - * You should not call multiple methods simultaneously on a single - * compressor or decompressor instance. - * - * If this may happen, you can either use one compressor or - * decompressor per thread, or you can use your preferred lock, - * semaphore or mutex library to ensure no more than one method on a - * compressor/decompressor is called simultaneously. libmspack will - * not do this locking for you. - * - * Example of incorrect behaviour: - * - thread 1 calls mspack_create_cab_decompressor() - * - thread 1 calls open() - * - thread 1 calls extract() for one file - * - thread 2 simultaneously calls extract() for another file - * - * Correct behaviour: - * - thread 1 calls mspack_create_cab_decompressor() - * - thread 2 calls mspack_create_cab_decompressor() - * - thread 1 calls its own open() / extract() - * - thread 2 simultaneously calls its own open() / extract() - * - * Also correct behaviour: - * - thread 1 calls mspack_create_cab_decompressor() - * - thread 1 locks a mutex for with the decompressor before - * calling any methods on it, and unlocks the mutex after each - * method returns. - * - thread 1 can share the results of open() with thread 2, and both - * can call extract(), provided they both guard against simultaneous - * use of extract(), and any other methods, with the mutex - */ - -namespace LibMSPackSharp -{ - public static class Library - { - #region CAB - - /// - /// Creates a new CAB compressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static CAB.Compressor CreateCABCompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Creates a new CAB decompressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static CAB.Decompressor CreateCABDecompressor(SystemImpl sys) - { - if (sys == null) - sys = SystemImpl.DefaultSystem; - if (!SystemImpl.ValidSystem(sys)) - return null; - - return new CAB.Decompressor() - { - System = sys, - State = null, - Error = Error.MSPACK_ERR_OK, - - SearchBufferSize = 32768, - FixMSZip = false, - BufferSize = 4096, - Salvage = false, - }; - } - - /// - /// Destroys an existing CAB compressor. - /// - /// the to destroy - public static void DestroyCABCompressor(CAB.Compressor self) - { - // TODO - } - - /// - /// Destroys an existing CAB decompressor. - /// - /// the to destroy - public static void DestroyCABDecompressor(CAB.Decompressor self) - { - if (self != null) - { - SystemImpl sys = self.System; - if (self.State != null) - { - sys.Close(self.State.InputFileHandle); - sys.Close(self.State.OutputFileHandle); - self.FreeDecompressionState(); - } - } - } - - #endregion - - #region CHM - - /// - /// Creates a new CHM compressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static CHM.Compressor CreateCHMCompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Creates a new CHM decompressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static CHM.Decompressor CreateCHMDecompressor(SystemImpl sys) - { - if (sys == null) - sys = SystemImpl.DefaultSystem; - if (!SystemImpl.ValidSystem(sys)) - return null; - - return new CHM.Decompressor() - { - System = sys, - Error = Error.MSPACK_ERR_OK, - State = null, - }; - } - - /// - /// Destroys an existing CHM compressor. - /// - /// the to destroy - public static void DestroyCHMCompressor(CHM.Compressor self) - { - // TODO - } - - /// - /// Destroys an existing CHM decompressor. - /// - /// the to destroy - public static void DestroyCHMDecompressor(CHM.Decompressor self) - { - if (self != null) - { - SystemImpl sys = self.System; - if (self.State != null) - { - sys.Close(self.State.InputFileHandle); - sys.Close(self.State.OutputFileHandle); - } - } - } - - #endregion - - #region LIT - - /// - /// Creates a new LIT compressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static LIT.Compressor CreateLITCompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Creates a new LIT decompressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static LIT.Decompressor CreateLITDecompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Destroys an existing LIT compressor. - /// - /// the to destroy - public static void DestroyLITCompressor(LIT.Compressor c) - { - // TODO - } - - /// - /// Destroys an existing LIT decompressor. - /// - /// the to destroy - public static void DestroyLITDecompressor(LIT.Decompressor d) - { - // TODO - } - - #endregion - - #region HLP - - /// - /// Creates a new HLP compressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static HLP.Compressor CreateHLPCompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Creates a new HLP decompressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static HLP.Decompressor CreateHLPDecompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Destroys an existing HLP compressor. - /// - /// the to destroy - public static void DestroyHLPCompressor(HLP.Compressor c) - { - // TODO - } - - /// - /// Destroys an existing HLP decompressor. - /// - /// the to destroy - public static void DestroyHLPDecompressor(HLP.Decompressor d) - { - // TODO - } - - #endregion - - #region SZDD - - /// - /// Creates a new SZDD compressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static SZDD.Compressor CreateSZDDCompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Creates a new SZDD decompressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static SZDD.Decompressor CreateSZDDDecompressor(SystemImpl sys) - { - if (sys == null) - sys = SystemImpl.DefaultSystem; - if (!SystemImpl.ValidSystem(sys)) - return null; - - return new SZDD.Decompressor() - { - System = sys, - Error = Error.MSPACK_ERR_OK, - }; - } - - /// - /// Destroys an existing SZDD compressor. - /// - /// the to destroy - public static void DestroySZDDCompressor(SZDD.Compressor c) - { - // TODO - } - - /// - /// Destroys an existing SZDD decompressor. - /// - /// the to destroy - public static void DestroySZDDDecompressor(SZDD.Decompressor d) { } - - #endregion - - #region KWAJ - - /// - /// Creates a new KWAJ compressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static KWAJ.Compressor CreateKWAJCompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Creates a new KWAJ decompressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static KWAJ.Decompressor CreateKWAJDecompressor(SystemImpl sys) - { - if (sys == null) - sys = SystemImpl.DefaultSystem; - if (!SystemImpl.ValidSystem(sys)) - return null; - - return new KWAJ.Decompressor() - { - System = sys, - Error = Error.MSPACK_ERR_OK, - }; - } - - /// - /// Destroys an existing KWAJ compressor. - /// - /// the to destroy - public static void DestroyKWAJCompressor(KWAJ.Compressor c) - { - // TODO - } - - /// - /// Destroys an existing KWAJ decompressor. - /// - /// the to destroy - public static void DestroyKWAJDecompressor(KWAJ.Decompressor d) { } - - #endregion - - #region OAB - - /// - /// Creates a new OAB compressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static OAB.Compressor CreateOABCompressor(SystemImpl sys) - { - // TODO - return null; - } - - /// - /// Creates a new OAB decompressor. - /// - /// a custom SystemImpl structure, or null to use the default - /// a or null - public static OAB.Decompressor CreateOABDecompressor(SystemImpl sys) - { - if (sys == null) - sys = SystemImpl.DefaultSystem; - if (!SystemImpl.ValidSystem(sys)) - return null; - - return new OAB.Decompressor() - { - System = sys, - BufferSize = 4096, - }; - } - - /// - /// Destroys an existing OAB compressor. - /// - /// the to destroy - public static void DestroyOABCompressor(OAB.Compressor c) - { - // TODO - } - - /// - /// Destroys an existing OAB decompressor. - /// - /// the to destroy - public static void DestroyOABDecompressor(OAB.Decompressor d) { } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/OAB/Compressor.cs b/BurnOutSharp/External/libmspack/OAB/Compressor.cs deleted file mode 100644 index c1c7abcb..00000000 --- a/BurnOutSharp/External/libmspack/OAB/Compressor.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; - -namespace LibMSPackSharp.OAB -{ - /// - /// A compressor for the Offline Address Book (OAB) format. - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Compressor - { - #region Fields - - public SystemImpl System { get; set; } - - #endregion - - /// - /// Compress a full OAB file. - /// - /// The input file will be read and the compressed contents written to the - /// output file. - /// - /// - /// The filename of the input file. This is passed - /// directly to mspack_system::open(). - /// - /// - /// The filename of the output file. This is passed - /// directly to mspack_system::open(). - /// - /// An error code, or MSPACK_ERR_OK if successful - public Error Compress(string input, string output) => throw new NotImplementedException(); - - /// - /// Generate a compressed incremental OAB patch file. - /// - /// The two uncompressed files "input" and "base" will be read, and an - /// incremental patch to generate "input" from "base" will be written to - /// the output file. - /// - /// - /// The filename of the input file containing the new - /// version of its contents. This is passed directly - /// to mspack_system::open(). - /// - /// - /// The filename of the original base file containing - /// the old version of its contents, against which the - /// incremental patch shall generated. This is passed - /// directly to mspack_system::open(). - /// - /// - /// The filename of the output file. This is passed - /// directly to mspack_system::open(). - /// - /// An error code, or MSPACK_ERR_OK if successful - public Error CompressIncremental(string input, string baseFile, string output) => throw new NotImplementedException(); - } -} diff --git a/BurnOutSharp/External/libmspack/OAB/Decompressor.cs b/BurnOutSharp/External/libmspack/OAB/Decompressor.cs deleted file mode 100644 index 741cd931..00000000 --- a/BurnOutSharp/External/libmspack/OAB/Decompressor.cs +++ /dev/null @@ -1,502 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; -using System.IO; -using LibMSPackSharp.Compression; -using static LibMSPackSharp.Constants; - -namespace LibMSPackSharp.OAB -{ - /// - /// A decompressor for .LZX (Offline Address Book) files - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Decompressor : BaseDecompressor - { - #region Public Functionality - - /// - /// Decompresses a full Offline Address Book file. - /// - /// If the input file is a valid compressed Offline Address Book file, - /// it will be read and the decompressed contents will be written to - /// the output file. - /// - /// - /// The filename of the input file. This is passed - /// directly to mspack_system::open(). - /// - /// - /// The filename of the output file. This is passed - /// directly to mspack_system::open(). - /// - /// An error code, or MSPACK_ERR_OK if successful - public Error Decompress(string input, string output) - { - byte[] hdrbuf = new byte[oabhead_SIZEOF]; - LZX lzx = null; - Error ret = Error.MSPACK_ERR_OK; - - FileStream infh = System.Open(input, OpenMode.MSPACK_SYS_OPEN_READ); - if (infh == null) - { - ret = Error.MSPACK_ERR_OPEN; - System.Close(infh); - return ret; - } - - if (System.Read(infh, hdrbuf, 0, oabhead_SIZEOF) != oabhead_SIZEOF) - { - ret = Error.MSPACK_ERR_READ; - System.Close(infh); - return ret; - } - - if (BitConverter.ToUInt32(hdrbuf, oabhead_VersionHi) != 3 || - BitConverter.ToUInt32(hdrbuf, oabhead_VersionLo) != 1) - { - ret = Error.MSPACK_ERR_SIGNATURE; - System.Close(infh); - return ret; - } - - uint block_max = BitConverter.ToUInt32(hdrbuf, oabhead_BlockMax); - uint target_size = BitConverter.ToUInt32(hdrbuf, oabhead_TargetSize); - - FileStream outfh = System.Open(output, OpenMode.MSPACK_SYS_OPEN_WRITE); - if (outfh == null) - { - ret = Error.MSPACK_ERR_OPEN; - System.Close(outfh); - System.Close(infh); - return ret; - } - - byte[] buf = new byte[BufferSize]; - - SystemImpl oabd_sys = System; - oabd_sys.Read = SysRead; - oabd_sys.Write = SysWrite; - - InternalFile in_ofh = new InternalFile(); - in_ofh.OrigSys = System; - in_ofh.OrigFile = infh; - - InternalFile out_ofh = new InternalFile(); - out_ofh.OrigSys = System; - out_ofh.OrigFile = outfh; - - while (target_size > 0) - { - if (System.Read(infh, buf, 0, oabblk_SIZEOF) != oabblk_SIZEOF) - { - ret = Error.MSPACK_ERR_READ; - System.Close(outfh); - System.Close(infh); - return ret; - } - - uint blk_flags = BitConverter.ToUInt32(buf, oabblk_Flags); - uint blk_csize = BitConverter.ToUInt32(buf, oabblk_CompSize); - uint blk_dsize = BitConverter.ToUInt32(buf, oabblk_UncompSize); - uint blk_crc = BitConverter.ToUInt32(buf, oabblk_CRC); - - if (blk_dsize > block_max || blk_dsize > target_size || blk_flags > 1) - { - ret = Error.MSPACK_ERR_DATAFORMAT; - System.Close(outfh); - System.Close(infh); - return ret; - } - - if (blk_flags == 0) - { - // Uncompressed block - if (blk_dsize != blk_csize) - { - ret = Error.MSPACK_ERR_DATAFORMAT; - System.Close(outfh); - System.Close(infh); - return ret; - } - - ret = CopyFileHandle(infh, outfh, (int)blk_dsize, buf, BufferSize); - if (ret != Error.MSPACK_ERR_OK) - { - System.Close(outfh); - System.Close(infh); - return ret; - } - } - else - { - // LZX compressed block - int window_bits = 17; - - while (window_bits < 25 && (1U << window_bits) < blk_dsize) - { - window_bits++; - } - - in_ofh.Available = (int)blk_csize; - out_ofh.CRC = 0xffffffff; - - lzx = LZX.Init(oabd_sys, in_ofh.OrigFile, out_ofh.OrigFile, window_bits, 0, BufferSize, blk_dsize, true); - if (lzx == null) - { - ret = Error.MSPACK_ERR_NOMEMORY; - System.Close(outfh); - System.Close(infh); - return ret; - } - - ret = lzx.Decompress(blk_dsize); - if (ret != Error.MSPACK_ERR_OK) - { - System.Close(outfh); - System.Close(infh); - return ret; - } - - lzx = null; - - // Consume any trailing padding bytes before the next block - ret = CopyFileHandle(infh, null, in_ofh.Available, buf, BufferSize); - if (ret != Error.MSPACK_ERR_OK) - { - System.Close(outfh); - System.Close(infh); - return ret; - } - - if (out_ofh.CRC != blk_crc) - { - ret = Error.MSPACK_ERR_CHECKSUM; - System.Close(outfh); - System.Close(infh); - return ret; - } - } - - target_size -= blk_dsize; - } - - System.Close(outfh); - System.Close(infh); - - return ret; - } - - /// - /// Decompresses an Offline Address Book with an incremental patch file. - /// - /// This requires both a full UNCOMPRESSED Offline Address Book file to - /// act as the "base", and a compressed incremental patch file as input. - /// If the input file is valid, it will be decompressed with reference to - /// the base file, and the decompressed contents will be written to the - /// output file. - /// - /// There is no way to tell what the right base file is for the given - /// incremental patch, but if you get it wrong, this will usually result - /// in incorrect data being decompressed, which will then fail a checksum - /// test. - /// - /// - /// The filename of the input file. This is passed - /// directly to mspack_system::open(). - /// - /// - /// The filename of the base file to which the - /// incremental patch shall be applied. This is passed - /// directly to mspack_system::open(). - /// - /// - /// The filename of the output file. This is passed - /// directly to mspack_system::open(). - /// - /// An error code, or MSPACK_ERR_OK if successful - public Error DecompressIncremental(string input, string basePath, string output) - { - byte[] hdrbuf = new byte[patchhead_SIZEOF]; - LZX lzx = null; - int window_bits; - uint window_size; - Error ret = Error.MSPACK_ERR_OK; - - FileStream infh = System.Open(input, OpenMode.MSPACK_SYS_OPEN_READ); - if (infh == null) - { - ret = Error.MSPACK_ERR_OPEN; - System.Close(infh); - return ret; - } - - if (System.Read(infh, hdrbuf, 0, patchhead_SIZEOF) != patchhead_SIZEOF) - { - ret = Error.MSPACK_ERR_READ; - System.Close(infh); - return ret; - } - - if (BitConverter.ToUInt32(hdrbuf, patchhead_VersionHi) != 3 || - BitConverter.ToUInt32(hdrbuf, patchhead_VersionLo) != 2) - { - ret = Error.MSPACK_ERR_SIGNATURE; - System.Close(infh); - return ret; - } - - uint block_max = BitConverter.ToUInt32(hdrbuf, patchhead_BlockMax); - uint target_size = BitConverter.ToUInt32(hdrbuf, patchhead_TargetSize); - - // We use it for reading block headers too - if (block_max < patchblk_SIZEOF) - block_max = patchblk_SIZEOF; - - FileStream basefh = System.Open(basePath, OpenMode.MSPACK_SYS_OPEN_READ); - if (basefh == null) - { - ret = Error.MSPACK_ERR_OPEN; - System.Close(basefh); - System.Close(infh); - return ret; - } - - FileStream outfh = System.Open(output, OpenMode.MSPACK_SYS_OPEN_WRITE); - if (outfh == null) - { - ret = Error.MSPACK_ERR_OPEN; - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - byte[] buf = new byte[BufferSize]; - - SystemImpl oabd_sys = System; - oabd_sys.Read = SysRead; - oabd_sys.Write = SysWrite; - - InternalFile in_ofh = new InternalFile(); - in_ofh.OrigSys = System; - in_ofh.OrigFile = infh; - - InternalFile out_ofh = new InternalFile(); - out_ofh.OrigSys = System; - out_ofh.OrigFile = outfh; - - while (target_size > 0) - { - if (System.Read(infh, buf, 0, patchblk_SIZEOF) != patchblk_SIZEOF) - { - ret = Error.MSPACK_ERR_READ; - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - uint blk_csize = BitConverter.ToUInt32(buf, patchblk_PatchSize); - uint blk_dsize = BitConverter.ToUInt32(buf, patchblk_TargetSize); - uint blk_ssize = BitConverter.ToUInt32(buf, patchblk_SourceSize); - uint blk_crc = BitConverter.ToUInt32(buf, patchblk_CRC); - - if (blk_dsize > block_max || blk_dsize > target_size || blk_ssize > block_max) - { - ret = Error.MSPACK_ERR_DATAFORMAT; - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - window_size = (uint)((blk_ssize + 32767) & ~32767); - window_size += blk_dsize; - window_bits = 17; - - while (window_bits < 25 && (1U << window_bits) < window_size) - window_bits++; - - in_ofh.Available = (int)blk_csize; - out_ofh.CRC = 0xffffffff; - - lzx = LZX.Init(oabd_sys, in_ofh.OrigFile, out_ofh.OrigFile, window_bits, 0, 4096, blk_dsize, true); - if (lzx == null) - { - ret = Error.MSPACK_ERR_NOMEMORY; - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - ret = lzx.SetReferenceData(System, basefh, blk_ssize); - if (ret != Error.MSPACK_ERR_OK) - { - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - ret = lzx.Decompress(blk_dsize); - if (ret != Error.MSPACK_ERR_OK) - { - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - lzx = null; - - // Consume any trailing padding bytes before the next block - ret = CopyFileHandle(infh, null, in_ofh.Available, buf, BufferSize); - if (ret != Error.MSPACK_ERR_OK) - { - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - if (out_ofh.CRC != blk_crc) - { - ret = Error.MSPACK_ERR_CHECKSUM; - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - return ret; - } - - target_size -= blk_dsize; - } - - System.Close(outfh); - System.Close(basefh); - System.Close(infh); - - return ret; - } - - /// - /// Sets an OAB decompression engine parameter. Available only in OAB - /// decompressor version 2 and above. - /// - /// - #MSOABD_PARAM_DECOMPBUF: How many bytes should be used as an input - /// buffer by decompressors? The minimum value is 16. The default value - /// is 4096. - /// - /// The parameter to set - /// The value to set the parameter to - /// - /// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there - /// is a problem with either parameter or value. - /// - public Error SetParam(Parameters param, int value) - { - if (param == Parameters.MSOABD_PARAM_DECOMPBUF && value >= 16) - { - // Must be at least 16 bytes (patchblk_SIZEOF, oabblk_SIZEOF) - BufferSize = value; - return Error.MSPACK_ERR_OK; - } - - return Error.MSPACK_ERR_ARGS; - } - - #endregion - - #region I/O Methods - - private static int SysRead(object baseFile, byte[] buf, int pointer, int size) - { - InternalFile file = baseFile as InternalFile; - if (file == null) - return 0; - - int bytes_read; - - if (size > file.Available) - size = file.Available; - - bytes_read = file.OrigSys.Read(file.OrigFile, buf, pointer, size); - if (bytes_read < 0) - return bytes_read; - - file.Available -= bytes_read; - return bytes_read; - } - - private static int SysWrite(object baseFile, byte[] buf, int pointer, int size) - { - // Null output file means skip those bytes - if (baseFile == null) - { - return size; - } - else if (baseFile is InternalFile file) - { - int bytes_written = file.OrigSys.Write(file.OrigFile, buf, pointer, size); - if (bytes_written > 0) - file.CRC = Checksum.CRC32(buf, 0, bytes_written, file.CRC); - - return bytes_written; - } - else if (baseFile is FileStream impl) - { - return SystemImpl.DefaultSystem.Write(impl, buf, pointer, size); - } - - // Unknown file to write to - return -1; - } - - #endregion - - #region Helpers - - /// - /// Copy between the input and output, if possible - /// - private Error CopyFileHandle(FileStream input, FileStream output, int bytesToCopy, byte[] buf, int bufferSize) - { - while (bytesToCopy > 0) - { - int run = bufferSize; - if (run > bytesToCopy) - run = bytesToCopy; - - if (System.Read(input, buf, 0, run) != run) - return Error.MSPACK_ERR_READ; - - if (output != null && System.Write(output, buf, 0, run) != run) - return Error.MSPACK_ERR_WRITE; - - bytesToCopy -= run; - } - - return Error.MSPACK_ERR_OK; - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/OAB/Enums.cs b/BurnOutSharp/External/libmspack/OAB/Enums.cs deleted file mode 100644 index b284c8cb..00000000 --- a/BurnOutSharp/External/libmspack/OAB/Enums.cs +++ /dev/null @@ -1,19 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.OAB -{ - public enum Parameters - { - /// - /// Size of decompression buffer - /// - MSOABD_PARAM_DECOMPBUF = 0, - } -} diff --git a/BurnOutSharp/External/libmspack/OAB/InternalFile.cs b/BurnOutSharp/External/libmspack/OAB/InternalFile.cs deleted file mode 100644 index 4cd8f81e..00000000 --- a/BurnOutSharp/External/libmspack/OAB/InternalFile.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System.IO; - -namespace LibMSPackSharp.OAB -{ - public class InternalFile - { - public SystemImpl OrigSys { get; set; } - - public FileStream OrigFile { get; set; } - - public uint CRC { get; set; } - - public int Available { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/SZDD/Compressor.cs b/BurnOutSharp/External/libmspack/SZDD/Compressor.cs deleted file mode 100644 index f28b984b..00000000 --- a/BurnOutSharp/External/libmspack/SZDD/Compressor.cs +++ /dev/null @@ -1,118 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; - -namespace LibMSPackSharp.SZDD -{ - /// - /// A compressor for the SZDD file format. - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Compressor - { - #region Fields - - public SystemImpl System { get; set; } - - public Error Error { get; set; } - - #endregion - - /// - /// Reads an input file and creates a compressed output file in the - /// SZDD compressed file format. The SZDD compression format is quick - /// but gives poor compression. It is possible for the compressed output - /// file to be larger than the input file. - /// - /// Conventionally, SZDD compressed files have the final character in - /// their filename replaced with an underscore, to show they are - /// compressed. The missing character is stored in the compressed file - /// itself. This is due to the restricted filename conventions of MS-DOS, - /// most operating systems, such as UNIX, simply append another file - /// extension to the existing filename. As mspack does not deal with - /// filenames, this is left up to you. If you wish to set the missing - /// character stored in the file header, use set_param() with the - /// #MSSZDDC_PARAM_MISSINGCHAR parameter. - /// - /// "Stream" compression (where the length of the input data is not - /// known) is not possible. The length of the input data is stored in the - /// header of the SZDD file and must therefore be known before any data - /// is compressed. Due to technical limitations of the file format, the - /// maximum size of uncompressed file that will be accepted is 2147483647 - /// bytes. - /// - /// - /// a self-referential pointer to the msszdd_compressor - /// instance being called - /// - /// - /// the name of the file to compressed. This is passed - /// passed directly to mspack_system::open() - /// - /// - /// the name of the file to write compressed data to. - /// This is passed directly to mspack_system::open(). - /// - /// - /// the length of the uncompressed file, or -1 to indicate - /// that this should be determined automatically by using - /// mspack_system::seek() on the input file. - /// - /// an error code, or MSPACK_ERR_OK if successful - /// - public Func Compress; - - /// - /// Sets an SZDD compression engine parameter. - /// - /// The following parameters are defined: - /// - #MSSZDDC_PARAM_CHARACTER: the "missing character", the last character - /// in the uncompressed file's filename, which is traditionally replaced - /// with an underscore to show the file is compressed. Traditionally, - /// this can only be a character that is a valid part of an MS-DOS, - /// filename, but libmspack permits any character between 0x00 and 0xFF - /// to be stored. 0x00 is the default, and it represents "no character - /// stored". - /// - /// - /// a self-referential pointer to the msszdd_compressor - /// instance being called - /// - /// the parameter to set - /// the value to set the parameter to - /// - /// MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there - /// is a problem with either parameter or value. - /// - /// - public Func SetParam; - - /// - /// Returns the error code set by the most recently called method. - /// - /// - /// a self-referential pointer to the msszdd_compressor - /// instance being called - /// - /// the most recent error code - /// - public Func LastError; - } -} diff --git a/BurnOutSharp/External/libmspack/SZDD/Decompressor.cs b/BurnOutSharp/External/libmspack/SZDD/Decompressor.cs deleted file mode 100644 index 72bffb97..00000000 --- a/BurnOutSharp/External/libmspack/SZDD/Decompressor.cs +++ /dev/null @@ -1,226 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; -using System.IO; -using System.Linq; -using LibMSPackSharp.Compression; -using static LibMSPackSharp.Constants; - -namespace LibMSPackSharp.SZDD -{ - /// - /// A decompressor for SZDD compressed files. - /// - /// All fields are READ ONLY. - /// - /// - /// - public class Decompressor : BaseDecompressor - { - #region Public Functionality - - /// - /// Opens a SZDD file and reads the header. - /// - /// If the file opened is a valid SZDD file, all headers will be read and - /// a msszddd_header structure will be returned. - /// - /// In the case of an error occuring, NULL is returned and the error code - /// is available from last_error(). - /// - /// The filename pointer should be considered "in use" until close() is - /// called on the SZDD file. - /// - /// - /// The filename of the SZDD compressed file. This is - /// passed directly to mspack_system::open(). - /// - /// A pointer to a msszddd_header structure, or NULL on failure - /// - public Header Open(string filename) - { - FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_READ); - Header hdr = new Header(); - if (fh != null && hdr != null) - { - hdr.FileHandle = fh; - Error = ReadHeaders(fh, hdr); - } - else - { - if (fh == null) - Error = Error.MSPACK_ERR_OPEN; - if (hdr == null) - Error = Error.MSPACK_ERR_NOMEMORY; - } - - if (Error != Error.MSPACK_ERR_OK) - { - System.Close(fh); - hdr = null; - } - - return hdr; - } - - /// - /// Closes a previously opened SZDD file. - /// - /// This closes a SZDD file and frees the msszddd_header associated with - /// it. - /// - /// The SZDD header pointer is now invalid and cannot be used again. - /// - /// The SZDD file to close - /// - public void Close(Header hdr) - { - if (System == null || hdr == null) - return; - - // Close the file handle associated - System.Close(hdr.FileHandle); - - Error = Error.MSPACK_ERR_OK; - } - - /// - /// Extracts the compressed data from a SZDD file. - /// - /// This decompresses the compressed SZDD data stream and writes it to - /// an output file. - /// - /// The SZDD file to extract data from - /// - /// The filename to write the decompressed data to. This - /// is passed directly to mspack_system::open(). - /// - /// An error code, or MSPACK_ERR_OK if successful - public Error Extract(Header hdr, string filename) - { - if (hdr == null) - return Error = Error.MSPACK_ERR_ARGS; - - FileStream fh = hdr.FileHandle; - if (fh == null) - return Error.MSPACK_ERR_ARGS; - - // Seek to the compressed data - long dataOffset = (hdr.Format == Format.MSSZDD_FMT_NORMAL) ? 14 : 12; - if (System.Seek(fh, dataOffset, SeekMode.MSPACK_SYS_SEEK_START)) - return Error = Error.MSPACK_ERR_SEEK; - - // Open file for output - FileStream outfh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE); - if (outfh == null) - return Error = Error.MSPACK_ERR_OPEN; - - // Decompress the data - Error = LZSS.Decompress( - System, - fh, - outfh, - SZDD_INPUT_SIZE, - hdr.Format == Format.MSSZDD_FMT_NORMAL - ? LZSSMode.LZSS_MODE_EXPAND - : LZSSMode.LZSS_MODE_QBASIC); - - // Close output file - System.Close(outfh); - - return Error; - } - - /// - /// Decompresses an SZDD file to an output file in one step. - /// - /// This opens an SZDD file as input, reads the header, then decompresses - /// the compressed data immediately to an output file, finally closing - /// both the input and output file. It is more convenient to use than - /// open() then extract() then close(), if you do not need to know the - /// SZDD output size or missing character. - /// - /// - /// The filename of the input SZDD file. This is passed - /// directly to mspack_system::open(). - /// - /// - /// The filename to write the decompressed data to. This - /// is passed directly to mspack_system::open(). - /// - /// An error code, or MSPACK_ERR_OK if successful - public Error Decompress(string input, string output) - { - Header hdr = Open(input) as Header; - if (hdr == null) - return Error; - - Error error = Extract(hdr, output); - Close(hdr); - return Error = error; - } - - #endregion - - #region Helpers - - /// - /// Reads the headers of an SZDD format file - /// - private Error ReadHeaders(FileStream fh, Header hdr) - { - // Read and check signature - byte[] buf = new byte[8]; - if (System.Read(fh, buf, 0, 8) != 8) - return Error.MSPACK_ERR_READ; - - if (buf.SequenceEqual(expandSignature)) - { - // Common SZDD - hdr.Format = Format.MSSZDD_FMT_NORMAL; - - // Read the rest of the header - if (System.Read(fh, buf, 0, 6) != 6) - return Error.MSPACK_ERR_READ; - - if (buf[0] != 0x41) - return Error.MSPACK_ERR_DATAFORMAT; - - hdr.MissingChar = (char)buf[1]; - hdr.Length = BitConverter.ToUInt32(buf, 2); - } - if (buf.SequenceEqual(qbasicSignature)) - { - // Special QBasic SZDD - hdr.Format = Format.MSSZDD_FMT_QBASIC; - if (System.Read(fh, buf, 0, 4) != 4) - return Error.MSPACK_ERR_READ; - - hdr.MissingChar = '\0'; - hdr.Length = BitConverter.ToUInt32(buf, 0); - } - else - { - return Error.MSPACK_ERR_SIGNATURE; - } - - return Error.MSPACK_ERR_OK; - } - - #endregion - } -} diff --git a/BurnOutSharp/External/libmspack/SZDD/Enums.cs b/BurnOutSharp/External/libmspack/SZDD/Enums.cs deleted file mode 100644 index d5d12882..00000000 --- a/BurnOutSharp/External/libmspack/SZDD/Enums.cs +++ /dev/null @@ -1,32 +0,0 @@ -/* This file is part of libmspack. - * (C) 2003-2018 Stuart Caie. - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * For further details, see the file COPYING.LIB distributed with libmspack - */ - -namespace LibMSPackSharp.SZDD -{ - public enum Format - { - /// - /// a regular SZDD file - /// - MSSZDD_FMT_NORMAL = 0, - - /// - /// a special QBasic SZDD file - /// - MSSZDD_FMT_QBASIC = 1, - } - - public enum Parameters - { - /// - /// The missing character - /// - MSSZDDC_PARAM_MISSINGCHAR = 0, - } -} diff --git a/BurnOutSharp/External/libmspack/SZDD/Header.cs b/BurnOutSharp/External/libmspack/SZDD/Header.cs deleted file mode 100644 index 6536e1e0..00000000 --- a/BurnOutSharp/External/libmspack/SZDD/Header.cs +++ /dev/null @@ -1,49 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System.IO; - -namespace LibMSPackSharp.SZDD -{ - /// - /// A structure which represents an SZDD compressed file. - /// - /// All fields are READ ONLY. - /// - public class Header : BaseHeader - { - /// - /// The file format - /// - public Format Format { get; set; } - - /// - /// The amount of data in the SZDD file once uncompressed. - /// - public long Length { get; set; } - - /// - /// The last character in the filename, traditionally replaced with an - /// underscore to show the file is compressed. The null character is used - /// to show that this character has not been stored (e.g. because the - /// filename is not known). Generally, only characters that may appear in - /// an MS-DOS filename (except ".") are valid. - /// - public char MissingChar { get; set; } - - public FileStream FileHandle { get; set; } - } -} diff --git a/BurnOutSharp/External/libmspack/SystemImpl.cs b/BurnOutSharp/External/libmspack/SystemImpl.cs deleted file mode 100644 index 2d8a66d1..00000000 --- a/BurnOutSharp/External/libmspack/SystemImpl.cs +++ /dev/null @@ -1,274 +0,0 @@ -/* libmspack -- a library for working with Microsoft compression formats. - * (C) 2003-2019 Stuart Caie - * - * libmspack is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (LGPL) version 2.1 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -using System; -using System.IO; - -namespace LibMSPackSharp -{ - /// - /// A structure which abstracts file I/O and memory management. - /// - /// The library always uses the SystemImpl structure for interaction - /// with the file system and to allocate, free and copy all memory.It also - /// uses it to send literal messages to the library user. - /// - /// When the library is compiled normally, passing null to a compressor or - /// decompressor constructor will result in a default SystemImpl being - /// used, where all methods are implemented with the standard C library. - /// However, all constructors support being given a custom created - /// SystemImpl structure, with the library user's own methods. This - /// allows for more abstract interaction, such as reading and writing files - /// directly to memory, or from a network socket or pipe. - /// - /// Implementors of an SystemImpl structure should read all - /// documentation entries for every structure member, and write methods - /// which conform to those standards. - /// - public class SystemImpl - { - /// - /// Opens a file for reading, writing, appending or updating. - /// - /// - /// the file to be opened. It is passed directly from the - /// library caller without being modified, so it is up to - /// the caller what this parameter actually represents. - /// - /// One of the values - /// - /// A pointer to a FileStream structure. This structure officially - /// contains no members, its true contents are up to the - /// SystemImpl implementor. It should contain whatever is needed - /// for other SystemImpl methods to operate. Returning the null - /// pointer indicates an error condition. - /// - public FileStream Open(string filename, OpenMode mode) - { - try - { - switch (mode) - { - case OpenMode.MSPACK_SYS_OPEN_READ: - return File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - - case OpenMode.MSPACK_SYS_OPEN_WRITE: - return File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); - - case OpenMode.MSPACK_SYS_OPEN_UPDATE: - return File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); - - case OpenMode.MSPACK_SYS_OPEN_APPEND: - return File.Open(filename, FileMode.Append, FileAccess.ReadWrite, FileShare.ReadWrite); - - default: - return null; - } - } - catch (Exception ex) - { - Message(null, $"Could not open {filename}: {ex}"); - return null; - } - } - - /// - /// Closes a previously opened file. If any memory was allocated for this - /// particular file handle, it should be freed at this time. - /// - /// the file to close - /// - public void Close(FileStream file) => file?.Close(); - - /// - /// Reads a given number of bytes from an open file. - /// - /// the file to read from - /// the location where the read bytes should be stored - /// the number of bytes to read from the file. - /// - /// the number of bytes successfully read (this can be less than - /// the number requested), zero to mark the end of file, or less - /// than zero to indicate an error. The library does not "retry" - /// reads and assumes short reads are due to EOF, so you should - /// avoid returning short reads because of transient errors. - /// - /// - /// - public Func Read; - - /// - /// Writes a given number of bytes to an open file. - /// - /// the file to write to - /// the location where the written bytes should be read from - /// the number of bytes to write to the file. - /// - /// the number of bytes successfully written, this can be less - /// than the number requested. Zero or less can indicate an error - /// where no bytes at all could be written. All cases where less - /// bytes were written than requested are considered by the library - /// to be an error. - /// - /// - /// - public Func Write; - - /// - /// Seeks to a specific file offset within an open file. - /// - /// Sometimes the library needs to know the length of a file. It does - /// this by seeking to the end of the file with seek(file, 0, - /// MSPACK_SYS_SEEK_END), then calling Tell(). Implementations may want - /// to make a special case for this. - /// - /// Due to the potentially varying 32/64 bit datatype int on some - /// architectures, the #MSPACK_SYS_SELFTEST macro MUST be used before - /// using the library. If not, the error caused by the library passing an - /// inappropriate stackframe to Seek() is subtle and hard to trace. - /// - /// the file to be seeked - /// an offset to seek, measured in bytes - /// One of the values - /// zero for success, non-zero for an error - /// - /// - public bool Seek(FileStream self, long offset, SeekMode mode) - { - if (self == null) - return false; - - switch (mode) - { - case SeekMode.MSPACK_SYS_SEEK_START: - try { self.Seek(offset, SeekOrigin.Begin); return true; } - catch { return false; } - - case SeekMode.MSPACK_SYS_SEEK_CUR: - try { self.Seek(offset, SeekOrigin.Current); return true; } - catch { return false; } - - case SeekMode.MSPACK_SYS_SEEK_END: - try { self.Seek(offset, SeekOrigin.End); return true; } - catch { return false; } - - default: - return false; - } - } - - /// - /// Returns the current file position (in bytes) of the given file. - /// - /// the file whose file position is wanted - /// the current file position of the file - /// - /// - public long Tell(FileStream self) => self?.Position ?? 0; - - /// - /// Used to send messages from the library to the user. - /// - /// Occasionally, the library generates warnings or other messages in - /// plain english to inform the human user. These are informational only - /// and can be ignored if not wanted. - /// - /// - /// may be a file handle returned from Open() if this message - /// pertains to a specific open file, or null if not related to - /// a specific file. - /// - /// a printf() style format string. It does NOT include a trailing newline. - /// - public void Message(FileStream file, string format) - { - if (file != null) - Console.Error.Write($"{file.Name}: "); - - Console.Error.Write($"{format}\n"); - } - - #region Helpers - - /// - /// Returns the length of a file opened for reading - /// - public Error GetFileLength(FileStream file, out long length) - { - try - { - length = file?.Length ?? 0; - return Error.MSPACK_ERR_OK; - } - catch - { - length = 0; - return Error.MSPACK_ERR_SEEK; - } - } - - /// - /// Validates a system structure - /// - public static bool ValidSystem(SystemImpl sys) - { - return (sys != null) && (sys.Read != null) && (sys.Write != null); - } - - #endregion - - #region Default Implementation - - public static SystemImpl DefaultSystem => new SystemImpl() - { - Read = DefaultRead, - Write = DefaultWrite, - }; - - private static int DefaultRead(object file, byte[] buffer, int pointer, int bytes) - { - FileStream self = file as FileStream; - if (self != null && buffer != null && bytes >= 0) - { - try { return self.Read(buffer, pointer, bytes); } - catch { } - } - - return -1; - } - - private static int DefaultWrite(object file, byte[] buffer, int pointer, int bytes) - { - // Null output file means skip those bytes - if (file == null) - { - return bytes; - } - - FileStream self = file as FileStream; - if (self != null && buffer != null && bytes >= 0) - { - try { self.Write(buffer, pointer, bytes); } - catch { return -1; } - return bytes; - } - - return -1; - } - - #endregion - } -} \ No newline at end of file diff --git a/LibMSPackSharp b/LibMSPackSharp new file mode 160000 index 00000000..cc083889 --- /dev/null +++ b/LibMSPackSharp @@ -0,0 +1 @@ +Subproject commit cc08388953577807c868ff3dd05f1b112a1ec9e2