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