diff --git a/BurnOutSharp/External/libmspack/CAB/Cabinet.cs b/BurnOutSharp/External/libmspack/CAB/Cabinet.cs
index f7f443de..3b9f10f7 100644
--- a/BurnOutSharp/External/libmspack/CAB/Cabinet.cs
+++ b/BurnOutSharp/External/libmspack/CAB/Cabinet.cs
@@ -74,6 +74,15 @@ namespace LibMSPackSharp.CAB
///
public class Cabinet
{
+ #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
@@ -93,11 +102,6 @@ namespace LibMSPackSharp.CAB
///
public long BaseOffset { get; set; }
- ///
- /// The length of the cabinet file in bytes.
- ///
- public uint Length { get; set; }
-
///
/// The previous cabinet in a cabinet set, or NULL.
///
@@ -137,39 +141,5 @@ namespace LibMSPackSharp.CAB
/// A list of all folders in the cabinet or cabinet set.
///
public Folder Folders { get; set; }
-
- ///
- /// The set ID of the cabinet. All cabinets in the same set should have
- /// the same set ID.
- ///
- public ushort SetID { get; 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.
- ///
- public ushort SetIndex { get; set; }
-
- ///
- /// 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.
- ///
- ///
- public ushort HeaderResv { get; set; }
-
- ///
- /// Header flags.
- ///
- ///
- ///
- ///
- ///
- ///
- public HeaderFlags Flags { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/CAB/CabinetImpl.cs b/BurnOutSharp/External/libmspack/CAB/CabinetImpl.cs
deleted file mode 100644
index dc0d7a89..00000000
--- a/BurnOutSharp/External/libmspack/CAB/CabinetImpl.cs
+++ /dev/null
@@ -1,18 +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
-{
- public class CabinetImpl : Cabinet
- {
- public long BlocksOffset { get; set; }
-
- public int BlockResverved { get; set; }
- }
-}
diff --git a/BurnOutSharp/External/libmspack/CAB/DecompressState.cs b/BurnOutSharp/External/libmspack/CAB/DecompressState.cs
index 4d99cf4d..b8b2d5a2 100644
--- a/BurnOutSharp/External/libmspack/CAB/DecompressState.cs
+++ b/BurnOutSharp/External/libmspack/CAB/DecompressState.cs
@@ -76,12 +76,12 @@ namespace LibMSPackSharp.CAB
///
/// Input data consumed
///
- public int IPtr { get; set; }
+ public int InputPointer { get; set; }
///
/// Input data end
///
- public int IEnd { get; set; }
+ public int InputEnd { get; set; }
///
/// One input block of data
diff --git a/BurnOutSharp/External/libmspack/CAB/Decompressor.cs b/BurnOutSharp/External/libmspack/CAB/Decompressor.cs
index 4df5b439..25095713 100644
--- a/BurnOutSharp/External/libmspack/CAB/Decompressor.cs
+++ b/BurnOutSharp/External/libmspack/CAB/Decompressor.cs
@@ -46,7 +46,7 @@ namespace LibMSPackSharp.CAB
///
///
///
- public Func Open;
+ public Func Open;
///
/// Closes a previously opened cabinet or cabinet set.
diff --git a/BurnOutSharp/External/libmspack/CAB/Folder.cs b/BurnOutSharp/External/libmspack/CAB/Folder.cs
index 0c5c845c..4c6ec590 100644
--- a/BurnOutSharp/External/libmspack/CAB/Folder.cs
+++ b/BurnOutSharp/External/libmspack/CAB/Folder.cs
@@ -27,6 +27,15 @@ namespace LibMSPackSharp.CAB
///
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.
@@ -34,28 +43,18 @@ namespace LibMSPackSharp.CAB
public Folder Next { get; 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".
+ /// Where are the data blocks?
///
- ///
- ///
- public CompressionType CompressionType { get; set; }
+ public FolderData Data { get; 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.
+ /// First file needing backwards merge
///
- public ushort NumBlocks { get; set; }
+ public InternalFile MergePrev { get; set; }
///
- /// Returns the compression method used by a folder.
+ /// First file needing forwards merge
///
- /// a value
- /// a value
- public CompressionType MSCABD_COMP_LEVEL(CompressionType compType) => (CompressionType)((((ushort)compType) >> 8) & 0x1F);
+ public InternalFile MergeNext { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/CAB/FolderImpl.cs b/BurnOutSharp/External/libmspack/CAB/FolderImpl.cs
deleted file mode 100644
index 009b9c07..00000000
--- a/BurnOutSharp/External/libmspack/CAB/FolderImpl.cs
+++ /dev/null
@@ -1,36 +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
-{
- public class FolderImpl : Folder
- {
- ///
- /// 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/Implementation.cs b/BurnOutSharp/External/libmspack/CAB/Implementation.cs
index 7c6b1deb..7e4123cb 100644
--- a/BurnOutSharp/External/libmspack/CAB/Implementation.cs
+++ b/BurnOutSharp/External/libmspack/CAB/Implementation.cs
@@ -71,36 +71,6 @@ namespace LibMSPackSharp.CAB
#region Structure Offsets
- private const int cfhead_Signature = (0x00);
- private const int cfhead_CabinetSize = (0x08);
- private const int cfhead_FileOffset = (0x10);
- private const int cfhead_MinorVersion = (0x18);
- private const int cfhead_MajorVersion = (0x19);
- private const int cfhead_NumFolders = (0x1A);
- private const int cfhead_NumFiles = (0x1C);
- private const int cfhead_Flags = (0x1E);
- private const int cfhead_SetID = (0x20);
- private const int cfhead_CabinetIndex = (0x22);
- private const int cfhead_SIZEOF = (0x24);
-
- private const int cfheadext_HeaderReserved = (0x00);
- private const int cfheadext_FolderReserved = (0x02);
- private const int cfheadext_DataReserved = (0x03);
- private const int cfheadext_SIZEOF = (0x04);
-
- private const int cffold_DataOffset = (0x00);
- private const int cffold_NumBlocks = (0x04);
- private const int cffold_CompType = (0x06);
- private const int cffold_SIZEOF = (0x08);
-
- private const int cffile_UncompressedSize = (0x00);
- private const int cffile_FolderOffset = (0x04);
- private const int cffile_FolderIndex = (0x08);
- private const int cffile_Date = (0x0A);
- private const int cffile_Time = (0x0C);
- private const int cffile_Attribs = (0x0E);
- private const int cffile_SIZEOF = (0x10);
-
private const int cfdata_CheckSum = (0x00);
private const int cfdata_CompressedSize = (0x04);
private const int cfdata_UncompressedSize = (0x06);
@@ -140,10 +110,10 @@ namespace LibMSPackSharp.CAB
///
/// Opens a file and tries to read it as a cabinet file
///
- public static CabinetImpl Open(Decompressor d, string filename)
+ public static Cabinet Open(Decompressor d, string filename)
{
DecompressorImpl self = d as DecompressorImpl;
- CabinetImpl cab = null;
+ Cabinet cab = null;
if (self == null)
return null;
@@ -152,7 +122,7 @@ namespace LibMSPackSharp.CAB
object fileHandle;
if ((fileHandle = system.Open(system, filename, OpenMode.MSPACK_SYS_OPEN_READ)) != null)
{
- cab = new CabinetImpl();
+ cab = new Cabinet();
cab.Filename = filename;
Error error = ReadHeaders(system, fileHandle, cab, 0, self.Salvage, false);
if (error != Error.MSPACK_ERR_OK)
@@ -222,7 +192,7 @@ namespace LibMSPackSharp.CAB
}
// Free folder data segments
- for (dat = (fol as FolderImpl).Data.Next; dat != null; dat = ndat)
+ for (dat = fol.Data.Next; dat != null; dat = ndat)
{
ndat = dat.Next;
sys.Free(dat);
@@ -272,18 +242,17 @@ namespace LibMSPackSharp.CAB
/// Fills out a pre-existing Cabinet structure, allocates memory
/// for folders and files as necessary
///
- public static Error ReadHeaders(SystemImpl sys, object fh, CabinetImpl cab, long offset, bool salvage, bool quiet)
+ public static Error ReadHeaders(SystemImpl sys, object fh, Cabinet cab, long offset, bool salvage, bool quiet)
{
- int num_folders, num_files, folder_resv, i, x;
+ int i, x;
Error err = Error.MSPACK_ERR_OK;
- FileFlags fidx;
- FolderImpl fol, linkfol = null;
+ Folder fol, linkfol = null;
InternalFile file, linkfile = null;
byte[] buf = new byte[64];
// Initialise pointers
if (cab == null)
- cab = new CabinetImpl();
+ cab = new Cabinet();
cab.Next = null;
cab.Files = null;
@@ -299,73 +268,36 @@ namespace LibMSPackSharp.CAB
return Error.MSPACK_ERR_SEEK;
// Read in the CFHEADER
- if (sys.Read(fh, buf, 0, cfhead_SIZEOF) != cfhead_SIZEOF)
+ if (sys.Read(fh, buf, 0, _CabinetHeader.Size) != _CabinetHeader.Size)
return Error.MSPACK_ERR_READ;
- // Check for "MSCF" signature
- if (BitConverter.ToUInt32(buf, cfhead_Signature) != 0x4643534D)
- return Error.MSPACK_ERR_SIGNATURE;
+ // Create a new header based on that
+ err = _CabinetHeader.Create(buf, out _CabinetHeader cabinetHeader);
+ if (err != Error.MSPACK_ERR_OK)
+ return err;
- // Some basic header fields
- cab.Length = BitConverter.ToUInt32(buf, cfhead_CabinetSize);
- cab.SetID = BitConverter.ToUInt16(buf, cfhead_SetID);
- cab.SetIndex = BitConverter.ToUInt16(buf, cfhead_CabinetIndex);
+ // Assign the header
+ cab.Header = cabinetHeader;
- // Get the number of folders
- num_folders = BitConverter.ToUInt16(buf, cfhead_NumFolders);
- if (num_folders == 0)
+ // Check for the extended header
+ if (cab.Header.Flags.HasFlag(HeaderFlags.MSCAB_HDR_RESV))
{
- if (!quiet) sys.Message(fh, "no folders in cabinet.");
- return Error.MSPACK_ERR_DATAFORMAT;
- }
-
- // Get the number of files
- num_files = BitConverter.ToUInt16(buf, cfhead_NumFiles);
- if (num_files == 0)
- {
- if (!quiet) sys.Message(fh, "no files in cabinet.");
- return Error.MSPACK_ERR_DATAFORMAT;
- }
-
- // Check cabinet version
- if ((buf[cfhead_MajorVersion] != 1) && (buf[cfhead_MinorVersion] != 3))
- {
- if (!quiet) sys.Message(fh, "WARNING; cabinet version is not 1.3");
- }
-
- // Read the reserved-sizes part of header, if present
- cab.Flags = (HeaderFlags)BitConverter.ToUInt16(buf, cfhead_Flags);
-
- if (cab.Flags.HasFlag(HeaderFlags.MSCAB_HDR_RESV))
- {
- if (sys.Read(fh, buf, 0, cfheadext_SIZEOF) != cfheadext_SIZEOF)
+ if (sys.Read(fh, buf, 0, _CabinetHeader.ExtendedSize) != _CabinetHeader.ExtendedSize)
return Error.MSPACK_ERR_READ;
- cab.HeaderResv = BitConverter.ToUInt16(buf, cfheadext_HeaderReserved);
- folder_resv = buf[cfheadext_FolderReserved];
- cab.BlockResverved = buf[cfheadext_DataReserved];
-
- if (cab.HeaderResv > 60000)
- {
- if (!quiet) sys.Message(fh, "WARNING; reserved header > 60000.");
- }
+ // Populate the extended header
+ cabinetHeader.PopulateExtendedHeader(buf);
// Skip the reserved header
- if (cab.HeaderResv != 0)
+ if (cab.Header.HeaderReserved != 0)
{
- if (!sys.Seek(fh, cab.HeaderResv, SeekMode.MSPACK_SYS_SEEK_CUR))
+ if (!sys.Seek(fh, cab.Header.HeaderReserved, SeekMode.MSPACK_SYS_SEEK_CUR))
return Error.MSPACK_ERR_SEEK;
}
}
- else
- {
- cab.HeaderResv = 0;
- folder_resv = 0;
- cab.BlockResverved = 0;
- }
// Read name and info of preceeding cabinet in set, if present
- if (cab.Flags.HasFlag(HeaderFlags.MSCAB_HDR_PREVCAB))
+ if (cab.Header.Flags.HasFlag(HeaderFlags.MSCAB_HDR_PREVCAB))
{
cab.PreviousName = ReadString(sys, fh, false, ref err);
if (err != Error.MSPACK_ERR_OK)
@@ -377,7 +309,7 @@ namespace LibMSPackSharp.CAB
}
// Read name and info of next cabinet in set, if present
- if (cab.Flags.HasFlag(HeaderFlags.MSCAB_HDR_NEXTCAB))
+ if (cab.Header.Flags.HasFlag(HeaderFlags.MSCAB_HDR_NEXTCAB))
{
cab.NextName = ReadString(sys, fh, false, ref err);
if (err != Error.MSPACK_ERR_OK)
@@ -389,29 +321,39 @@ namespace LibMSPackSharp.CAB
}
// Read folders
- for (i = 0; i < num_folders; i++)
+ for (i = 0; i < cab.Header.NumFolders; i++)
{
- if (sys.Read(fh, buf, 0, cffold_SIZEOF) != cffold_SIZEOF)
+ // Read in the FOHEADER
+ if (sys.Read(fh, buf, 0, _FolderHeader.Size) != _FolderHeader.Size)
return Error.MSPACK_ERR_READ;
- if (folder_resv != 0)
+ if (cab.Header.FolderReserved != 0)
{
- if (!sys.Seek(fh, folder_resv, SeekMode.MSPACK_SYS_SEEK_CUR))
+ if (!sys.Seek(fh, cab.Header.FolderReserved, SeekMode.MSPACK_SYS_SEEK_CUR))
return Error.MSPACK_ERR_SEEK;
}
- fol = new FolderImpl();
+ // Create an empty folder
+ fol = new Folder()
+ {
+ Next = null,
+ MergePrev = null,
+ MergeNext = null,
+ };
- fol.Next = null;
- fol.CompressionType = (CompressionType)BitConverter.ToUInt16(buf, cffold_CompType);
- fol.NumBlocks = BitConverter.ToUInt16(buf, cffold_NumBlocks);
- fol.MergePrev = null;
- fol.MergeNext = null;
+ // Create a new header based on that
+ 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();
fol.Data.Next = null;
fol.Data.Cab = cab;
- fol.Data.Offset = offset + (int)(BitConverter.ToUInt32(buf, cffold_DataOffset));
+ fol.Data.Offset = offset + fol.Header.DataOffset;
// Link folder into list of folders
if (linkfol == null)
@@ -423,27 +365,30 @@ namespace LibMSPackSharp.CAB
}
// Read files
- for (i = 0; i < num_files; i++)
+ for (i = 0; i < cab.Header.NumFiles; i++)
{
- if (sys.Read(fh, buf, 0, cffile_SIZEOF) != cffile_SIZEOF)
+ // Read in the FIHEADER
+ if (sys.Read(fh, buf, 0, _FileHeader.Size) != _FileHeader.Size)
return Error.MSPACK_ERR_READ;
- file = new InternalFile();
+ file = new InternalFile() { Next = null };
- file.Next = null;
- file.Length = BitConverter.ToUInt32(buf, cffile_UncompressedSize);
- file.Attributes = (FileAttributes)BitConverter.ToUInt16(buf, cffile_Attribs);
- file.Offset = BitConverter.ToUInt32(buf, cffile_FolderOffset);
+ // Create a new header based on that
+ err = _FileHeader.Create(buf, out _FileHeader fileHeader);
+ if (err != Error.MSPACK_ERR_OK)
+ return err;
+
+ // Assign the header
+ file.Header = fileHeader;
// Set folder pointer
- fidx = (FileFlags)BitConverter.ToUInt16(buf, cffile_FolderIndex);
- if (fidx < FileFlags.CONTINUED_FROM_PREV)
+ if (file.Header.FolderIndex < FileFlags.CONTINUED_FROM_PREV)
{
// Normal folder index; count up to the correct folder
- if ((int)fidx < num_folders)
+ if ((int)file.Header.FolderIndex < cab.Header.NumFolders)
{
Folder ifol = cab.Folders;
- while (fidx-- != 0)
+ while (file.Header.FolderIndex-- != 0)
{
if (ifol != null)
ifol = ifol.Next;
@@ -460,7 +405,7 @@ namespace LibMSPackSharp.CAB
else
{
// Either CONTINUED_TO_NEXT, CONTINUED_FROM_PREV or CONTINUED_PREV_AND_NEXT
- if (fidx == FileFlags.CONTINUED_TO_NEXT || fidx == FileFlags.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;
@@ -472,35 +417,23 @@ namespace LibMSPackSharp.CAB
file.Folder = ifol;
// Set "merge next" pointer
- fol = ifol as FolderImpl;
+ fol = ifol;
if (fol.MergeNext == null)
fol.MergeNext = file;
}
- if (fidx == FileFlags.CONTINUED_FROM_PREV || fidx == FileFlags.CONTINUED_PREV_AND_NEXT)
+ 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
- fol = file.Folder as FolderImpl;
+ fol = file.Folder;
if (fol.MergePrev == null)
fol.MergePrev = file;
}
}
- // Get time
- x = BitConverter.ToUInt16(buf, cffile_Time);
- file.LastModifiedTimeHour = (byte)(x >> 11);
- file.LastModifiedTimeMinute = (byte)((x >> 5) & 0x3F);
- file.LastModifiedTimeSecond = (byte)((x << 1) & 0x3E);
-
- // Get date
- x = BitConverter.ToUInt16(buf, cffile_Date);
- file.LastModifiedDateDay = (byte)(x & 0x1F);
- file.LastModifiedDateMonth = (byte)((x >> 5) & 0xF);
- file.LastModifiedDateYear = (x >> 9) + 1980;
-
// Get filename
file.Filename = ReadString(sys, fh, false, ref err);
@@ -528,7 +461,7 @@ namespace LibMSPackSharp.CAB
{
// 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 {num_files} files");
+ Console.WriteLine($"No files found, even though header claimed to have {cab.Header.NumFiles} files");
return Error.MSPACK_ERR_DATAFORMAT;
}
@@ -610,7 +543,7 @@ namespace LibMSPackSharp.CAB
}
// Open file and get its full file length
- object fh; CabinetImpl cab = null;
+ object fh; Cabinet cab = null;
if ((fh = sys.Open(sys, filename, OpenMode.MSPACK_SYS_OPEN_READ)) != null)
{
long firstlen = 0;
@@ -643,10 +576,10 @@ namespace LibMSPackSharp.CAB
/// The inner loop of , to make it easier to
/// break out of the loop and be sure that all resources are freed
///
- public static Error Find(DecompressorImpl self, byte[] buf, object fh, string filename, long flen, ref long firstlen, out CabinetImpl firstcab)
+ public static Error Find(DecompressorImpl self, byte[] buf, object fh, string filename, long flen, ref long firstlen, out Cabinet firstcab)
{
firstcab = null;
- CabinetImpl cab, link = null;
+ Cabinet cab, link = null;
long caboff, offset, length;
SystemImpl sys = self.System;
long p, pend;
@@ -762,8 +695,7 @@ namespace LibMSPackSharp.CAB
(((caboff + cablen_u32) < (flen + 32)) || self.Salvage))
{
// Likely cabinet found -- try reading it
- cab = new CabinetImpl();
- cab.Filename = filename;
+ cab = new Cabinet() { Filename = filename };
if (ReadHeaders(sys, fh, cab, caboff, self.Salvage, quiet: true) != Error.MSPACK_ERR_OK)
{
@@ -842,7 +774,7 @@ namespace LibMSPackSharp.CAB
DecompressorImpl self = d as DecompressorImpl;
FolderData data, ndata;
- FolderImpl lfol, rfol;
+ Folder lfol, rfol;
InternalFile fi, rfi, lfi;
if (self == null)
@@ -884,18 +816,18 @@ namespace LibMSPackSharp.CAB
}
// Warn about odd set IDs or indices
- if (lcab.SetID != rcab.SetID)
+ if (lcab.Header.SetID != rcab.Header.SetID)
sys.Message(null, "WARNING; merged cabinets with differing Set IDs.");
- if (lcab.SetIndex > rcab.SetIndex)
+ if (lcab.Header.CabinetIndex > rcab.Header.CabinetIndex)
sys.Message(null, "WARNING; merged cabinets with odd order.");
// Merging the last folder in lcab with the first folder in rcab
- lfol = lcab.Folders as FolderImpl;
- rfol = rcab.Folders as FolderImpl;
+ lfol = lcab.Folders;
+ rfol = rcab.Folders;
while (lfol.Next != null)
{
- lfol = lfol.Next as FolderImpl;
+ lfol = lfol.Next;
}
// Do we need to merge folders?
@@ -947,14 +879,14 @@ namespace LibMSPackSharp.CAB
// 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.NumBlocks += (ushort)(rfol.NumBlocks - 1);
+ 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 = (FolderImpl)lfol.Next;
+ lfol = lfol.Next;
}
lfol.Next = rfol.Next;
@@ -1015,20 +947,20 @@ namespace LibMSPackSharp.CAB
///
/// Decides if two folders are OK to merge
///
- private static bool CanMergeFolders(SystemImpl sys, FolderImpl lfol, FolderImpl rfol)
+ private static bool CanMergeFolders(SystemImpl sys, Folder lfol, Folder rfol)
{
InternalFile lfi, rfi, l, r;
bool matching = true;
// Check that both folders use the same compression method/settings
- if (lfol.CompressionType != rfol.CompressionType)
+ 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.NumBlocks + rfol.NumBlocks) > CAB_FOLDERMAX)
+ if ((lfol.Header.NumBlocks + rfol.Header.NumBlocks) > CAB_FOLDERMAX)
{
Console.WriteLine("folder merge: too many data blocks in merged folders");
return false;
@@ -1046,7 +978,7 @@ namespace LibMSPackSharp.CAB
// offset and length of each file.
for (l = lfi, r = rfi; l != null; l = l.Next, r = r.Next)
{
- if (r == null || (l.Offset != r.Offset) || (l.Length != r.Length))
+ if (r == null || (l.Header.FolderOffset != r.Header.FolderOffset) || (l.Header.UncompressedSize != r.Header.UncompressedSize))
{
matching = false;
break;
@@ -1064,7 +996,7 @@ namespace LibMSPackSharp.CAB
{
for (r = rfi; r != null; r = r.Next)
{
- if (l.Offset == r.Offset && l.Length == r.Length)
+ if (l.Header.FolderOffset == r.Header.FolderOffset && l.Header.UncompressedSize == r.Header.UncompressedSize)
break;
}
@@ -1095,19 +1027,19 @@ namespace LibMSPackSharp.CAB
return self.Error = Error.MSPACK_ERR_ARGS;
SystemImpl sys = self.System;
- FolderImpl fol = file.Folder as FolderImpl;
+ Folder fol = file.Folder;
// If offset is beyond 2GB, nothing can be extracted
- if (file.Offset > CAB_LENGTHMAX)
+ if (file.Header.FolderOffset > CAB_LENGTHMAX)
return self.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.Length;
- if (filelen > CAB_LENGTHMAX || (file.Offset + filelen) > CAB_LENGTHMAX)
+ long filelen = file.Header.UncompressedSize;
+ if (filelen > CAB_LENGTHMAX || (file.Header.FolderOffset + filelen) > CAB_LENGTHMAX)
{
if (self.Salvage)
- filelen = CAB_LENGTHMAX - file.Offset;
+ filelen = CAB_LENGTHMAX - file.Header.FolderOffset;
else
return self.Error = Error.MSPACK_ERR_DATAFORMAT;
}
@@ -1123,8 +1055,8 @@ namespace LibMSPackSharp.CAB
// In salvage mode, don't assume block sizes, just try decoding
if (!self.Salvage)
{
- long maxlen = fol.NumBlocks * CAB_BLOCKMAX;
- if ((file.Offset + filelen) > maxlen)
+ long maxlen = fol.Header.NumBlocks * CAB_BLOCKMAX;
+ if ((file.Header.FolderOffset + filelen) > maxlen)
{
sys.Message(null, $"ERROR; file \"{file.Filename}\" cannot be extracted, cabinet set is incomplete");
return self.Error = Error.MSPACK_ERR_DECRUNCH;
@@ -1146,7 +1078,7 @@ namespace LibMSPackSharp.CAB
}
// Do we need to change folder or reset the current folder?
- if ((self.State.Folder != fol) || (self.State.Offset > file.Offset) || self.State.DecompressorState == null)
+ if ((self.State.Folder != fol) || (self.State.Offset > file.Header.FolderOffset) || self.State.DecompressorState == null)
{
// Free any existing decompressor
FreeDecompressionState(self);
@@ -1169,7 +1101,7 @@ namespace LibMSPackSharp.CAB
return self.Error = Error.MSPACK_ERR_SEEK;
// Set up decompressor
- if (InitDecompressionState(self, fol.CompressionType) != Error.MSPACK_ERR_OK)
+ if (InitDecompressionState(self, fol.Header.CompType) != Error.MSPACK_ERR_OK)
return self.Error;
// Initialise new folder state
@@ -1178,7 +1110,7 @@ namespace LibMSPackSharp.CAB
self.State.Offset = 0;
self.State.Block = 0;
self.State.Outlen = 0;
- self.State.IPtr = self.State.IEnd = 0;
+ self.State.InputPointer = self.State.InputEnd = 0;
// read_error lasts for the lifetime of a decompressor
self.ReadError = Error.MSPACK_ERR_OK;
@@ -1200,7 +1132,7 @@ namespace LibMSPackSharp.CAB
// - if cabd_sys_read() has an error, it will set self.ReadError
// and pass back MSPACK_ERR_READ
self.State.OutputFileHandle = null;
- if ((bytes = file.Offset - self.State.Offset) != 0)
+ if ((bytes = file.Header.FolderOffset - self.State.Offset) != 0)
{
error = self.State.Decompress(self.State.DecompressorState, bytes);
self.Error = (error == Error.MSPACK_ERR_READ) ? self.ReadError : error;
@@ -1310,7 +1242,11 @@ namespace LibMSPackSharp.CAB
private static int SysRead(object file, byte[] buffer, int pointer, int bytes)
{
DecompressorImpl self = file as DecompressorImpl;
+ if (self == null)
+ return 0;
+
SystemImpl sys = self.System;
+
int avail, todo, outlen = 0;
bool ignore_cksum = self.Salvage ||
@@ -1321,7 +1257,7 @@ namespace LibMSPackSharp.CAB
todo = bytes;
while (todo > 0)
{
- avail = self.State.IEnd - self.State.IPtr;
+ avail = self.State.InputEnd - self.State.InputPointer;
// If out of input data, read a new block
if (avail != 0)
@@ -1330,8 +1266,8 @@ namespace LibMSPackSharp.CAB
if (avail > todo)
avail = todo;
- sys.Copy(self.State.Input, self.State.IPtr, buffer, pointer, avail);
- self.State.IPtr += avail;
+ sys.Copy(self.State.Input, self.State.InputPointer, buffer, pointer, avail);
+ self.State.InputPointer += avail;
pointer += avail;
todo -= avail;
}
@@ -1340,7 +1276,7 @@ namespace LibMSPackSharp.CAB
// Out of data, read a new block
// Check if we're out of input blocks, advance block counter
- if (self.State.Block++ >= self.State.Folder.NumBlocks)
+ if (self.State.Block++ >= self.State.Folder.Header.NumBlocks)
{
if (!self.Salvage)
self.ReadError = Error.MSPACK_ERR_DATAFORMAT;
@@ -1361,10 +1297,10 @@ namespace LibMSPackSharp.CAB
// to realign itself. CAB Quantum blocks, unlike LZX blocks, can have
// anything from 0 to 4 trailing null bytes.
if ((self.State.CompressionType & CompressionType.COMPTYPE_MASK) == CompressionType.COMPTYPE_QUANTUM)
- self.State.Input[self.State.IEnd++] = 0xFF;
+ self.State.Input[self.State.InputEnd++] = 0xFF;
// Is this the last block?
- if (self.State.Block >= self.State.Folder.NumBlocks)
+ if (self.State.Block >= self.State.Folder.Header.NumBlocks)
{
if ((self.State.CompressionType & CompressionType.COMPTYPE_MASK) == CompressionType.COMPTYPE_LZX)
{
@@ -1387,12 +1323,21 @@ namespace LibMSPackSharp.CAB
///
private static int SysWrite(object file, byte[] buffer, int pointer, int bytes)
{
- DecompressorImpl self = file as DecompressorImpl;
- self.State.Offset += (uint)bytes;
- if (self.State.OutputFileHandle != null)
- return self.System.Write(self.State.OutputFileHandle, buffer, pointer, bytes);
+ if (file is DecompressorImpl self)
+ {
+ self.State.Offset += (uint)bytes;
+ if (self.State.OutputFileHandle != null)
+ return self.System.Write(self.State.OutputFileHandle, buffer, pointer, bytes);
- return bytes;
+ return bytes;
+ }
+ else if (file is DefaultFileImpl impl)
+ {
+ return SystemImpl.DefaultSystem.Write(file, buffer, pointer, bytes);
+ }
+
+ // Unknown file to write to
+ return 0;
}
#endregion
@@ -1410,21 +1355,21 @@ namespace LibMSPackSharp.CAB
int len, full_len;
// Reset the input block pointer and end of block pointer
- d.IPtr = d.IEnd = 0;
+ d.InputPointer = d.InputEnd = 0;
do
{
// Read the block header
- if (sys.Read(d.InputFileHandle, hdr, 0, cfdata_SIZEOF) != cfdata_SIZEOF)
+ if (SystemImpl.DefaultSystem.Read(d.InputFileHandle, hdr, 0, cfdata_SIZEOF) != cfdata_SIZEOF)
return Error.MSPACK_ERR_READ;
// Skip any reserved block headers
- if (d.Data.Cab.HeaderResv != 0 && !sys.Seek(d.InputFileHandle, d.Data.Cab.HeaderResv, SeekMode.MSPACK_SYS_SEEK_CUR))
+ if (d.Data.Cab.Header.HeaderReserved != 0 && !sys.Seek(d.InputFileHandle, d.Data.Cab.Header.HeaderReserved, SeekMode.MSPACK_SYS_SEEK_CUR))
return Error.MSPACK_ERR_SEEK;
// Blocks must not be over CAB_INPUTMAX in size
len = BitConverter.ToUInt16(hdr, cfdata_CompressedSize);
- full_len = (d.IEnd - d.IPtr) + len; // Include cab-spanning blocks
+ full_len = (d.InputEnd - d.InputPointer) + len; // Include cab-spanning blocks
if (full_len > CAB_INPUTMAX)
{
Console.WriteLine($"block size {full_len} > CAB_INPUTMAX");
@@ -1443,13 +1388,13 @@ namespace LibMSPackSharp.CAB
}
// Read the block data
- if (sys.Read(d.InputFileHandle, d.Input, d.IEnd, len) != len)
+ if (SystemImpl.DefaultSystem.Read(d.InputFileHandle, d.Input, d.InputEnd, len) != len)
return Error.MSPACK_ERR_READ;
// Perform checksum test on the block (if one is stored)
if ((cksum = BitConverter.ToUInt32(hdr, cfdata_CheckSum)) != 0)
{
- uint sum2 = Checksum(d.Input, d.IEnd, (uint)len, 0);
+ uint sum2 = Checksum(d.Input, d.InputEnd, (uint)len, 0);
if (Checksum(hdr, 4, 4, sum2) != cksum)
{
if (!ignore_cksum)
@@ -1460,7 +1405,7 @@ namespace LibMSPackSharp.CAB
}
// Advance end of block pointer to include newly read data
- d.IEnd += len;
+ d.InputEnd += len;
// 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.
diff --git a/BurnOutSharp/External/libmspack/CAB/InternalFile.cs b/BurnOutSharp/External/libmspack/CAB/InternalFile.cs
index 30a27387..85dd5df8 100644
--- a/BurnOutSharp/External/libmspack/CAB/InternalFile.cs
+++ b/BurnOutSharp/External/libmspack/CAB/InternalFile.cs
@@ -23,6 +23,15 @@ namespace LibMSPackSharp.CAB
///
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.
///
@@ -34,57 +43,12 @@ namespace LibMSPackSharp.CAB
/// 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; }
- ///
- /// The uncompressed length of the file, in bytes.
- ///
- public uint Length { get; set; }
-
- ///
- /// File attributes.
- ///
- public FileAttributes Attributes { get; set; }
-
- ///
- /// File's last modified time, hour field.
- ///
- public byte LastModifiedTimeHour { get; set; }
-
- ///
- /// File's last modified time, minute field.
- ///
- public byte LastModifiedTimeMinute { get; set; }
-
- ///
- /// File's last modified time, second field.
- ///
- public byte LastModifiedTimeSecond { get; set; }
-
- ///
- /// File's last modified date, day field.
- ///
- public byte LastModifiedDateDay { get; set; }
-
- ///
- /// File's last modified date, month field.
- ///
- public byte LastModifiedDateMonth { get; set; }
-
- ///
- /// File's last modified date, year field.
- ///
- public int LastModifiedDateYear { get; set; }
-
///
/// A pointer to the folder that contains this file.
///
public Folder Folder { get; set; }
-
- ///
- /// The uncompressed offset of this file in its folder.
- ///
- public uint Offset { get; set; }
}
}
diff --git a/BurnOutSharp/External/libmspack/CAB/_CabinetHeader.cs b/BurnOutSharp/External/libmspack/CAB/_CabinetHeader.cs
new file mode 100644
index 00000000..0a7b774d
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/CAB/_CabinetHeader.cs
@@ -0,0 +1,204 @@
+/* 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, 0x24);
+ FolderReserved = buffer[0x26];
+ DataReserved = buffer[0x27];
+ }
+ }
+}
diff --git a/BurnOutSharp/External/libmspack/CAB/_FileHeader.cs b/BurnOutSharp/External/libmspack/CAB/_FileHeader.cs
new file mode 100644
index 00000000..24fb8eb9
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/CAB/_FileHeader.cs
@@ -0,0 +1,122 @@
+/* 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 _Folder 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
new file mode 100644
index 00000000..88d7a87f
--- /dev/null
+++ b/BurnOutSharp/External/libmspack/CAB/_FolderHeader.cs
@@ -0,0 +1,72 @@
+/* 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 _Folder 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/Implementation.cs b/BurnOutSharp/External/libmspack/CHM/Implementation.cs
index 2b114e3f..096d468d 100644
--- a/BurnOutSharp/External/libmspack/CHM/Implementation.cs
+++ b/BurnOutSharp/External/libmspack/CHM/Implementation.cs
@@ -1154,12 +1154,21 @@ namespace LibMSPackSharp.CHM
///
private static int SysWrite(object file, byte[] buffer, int offset, int bytes)
{
- DecompressorImpl self = file as DecompressorImpl;
- self.State.Offset += bytes;
- if (self.State.OutputFileHandle != null)
- return self.System.Write(self.State.OutputFileHandle, buffer, offset, bytes);
+ if (file is DecompressorImpl self)
+ {
+ self.State.Offset += (uint)bytes;
+ if (self.State.OutputFileHandle != null)
+ return self.System.Write(self.State.OutputFileHandle, buffer, offset, bytes);
- return bytes;
+ return bytes;
+ }
+ else if (file is DefaultFileImpl impl)
+ {
+ return SystemImpl.DefaultSystem.Write(file, buffer, offset, bytes);
+ }
+
+ // Unknown file to write to
+ return 0;
}
#endregion
diff --git a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
index 38424930..9b0d8fa4 100644
--- a/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
+++ b/BurnOutSharp/External/libmspack/Compression/CompressionStream.cs
@@ -140,77 +140,104 @@ namespace LibMSPackSharp.Compression
InputEnd = 0;
}
- public void STORE_BITS(int inputPointer, int inputLength, uint bitBuffer, uint bitsLeft)
+ public void STORE_BITS(int inputPointer, int inputLength, uint bit_buffer, uint bits_left)
{
InputPointer = inputPointer;
InputLength = inputLength;
- BitBuffer = bitBuffer;
- BitsLeft = bitsLeft;
+ BitBuffer = bit_buffer;
+ BitsLeft = bits_left;
}
- public void RESTORE_BITS(ref int inputPointer, ref int inputLength, ref uint bitBuffer, ref uint bitsLeft)
+ public void RESTORE_BITS(ref int inputPointer, ref int inputLength, ref uint bit_buffer, ref uint bits_left)
{
inputPointer = InputPointer;
inputLength = InputLength;
- bitBuffer = BitBuffer;
- bitsLeft = BitsLeft;
+ bit_buffer = BitBuffer;
+ bits_left = BitsLeft;
}
- public void ENSURE_BITS(int nbits, ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public void ENSURE_BITS(int nbits, ref int i_ptr, ref int i_end, ref uint bits_left, ref uint bit_buffer, bool msb)
{
- while (bitsLeft < nbits)
+ while (bits_left < nbits)
{
- READ_BYTES(ref i_ptr, ref i_end, ref bitsLeft, ref bitBuffer);
+ READ_BYTES(ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
}
+
+ Error = Error.MSPACK_ERR_OK;
}
- public void READ_BITS(ref int val, int nbits, ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public void READ_BITS(ref int val, int nbits, ref int i_ptr, ref int i_end, ref uint bits_left, ref uint bit_buffer, bool msb)
{
- ENSURE_BITS(nbits, ref i_ptr, ref i_end, ref bitsLeft, ref bitBuffer);
- val = PEEK_BITS(nbits, bitBuffer);
- REMOVE_BITS(nbits, ref bitsLeft, ref bitBuffer);
+ ENSURE_BITS(nbits, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
+
+ val = PEEK_BITS(nbits, bit_buffer, msb);
+ REMOVE_BITS(nbits, ref bits_left, ref bit_buffer, msb);
+ Error = Error.MSPACK_ERR_OK;
}
- public Error READ_MANY_BITS(ref uint val, byte bits, ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public void READ_MANY_BITS(ref uint val, byte bits, ref int i_ptr, ref int i_end, ref uint bits_left, ref uint bit_buffer, bool msb)
{
byte needed = bits, bitrun;
val = 0;
while (needed > 0)
{
- if (bitsLeft <= (BITBUF_WIDTH - 16))
+ if (bits_left <= (BITBUF_WIDTH - 16))
{
- Error error = READ_BYTES(ref i_ptr, ref i_end, ref bitsLeft, ref bitBuffer);
- if (error != Error.MSPACK_ERR_OK)
- return error;
+ READ_BYTES(ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
}
- bitrun = (byte)((bitsLeft < needed) ? bitsLeft : needed);
- val = (uint)((val << bitrun) | PEEK_BITS(bitrun, bitBuffer));
- REMOVE_BITS(bitrun, ref bitsLeft, ref bitBuffer);
+ bitrun = (byte)((bits_left < needed) ? bits_left : needed);
+ val = (uint)((val << bitrun) | PEEK_BITS(bitrun, bit_buffer, msb));
+ REMOVE_BITS(bitrun, ref bits_left, ref bit_buffer, msb);
needed -= bitrun;
}
- return Error.MSPACK_ERR_OK;
+ Error = Error.MSPACK_ERR_OK;
}
- public int PEEK_BITS(int nbits, uint bitBuffer)
+ public int PEEK_BITS(int nbits, uint bit_buffer, bool msb)
{
- return (int)(bitBuffer & ((1 << (nbits)) - 1));
+ if (msb)
+ return (int)(bit_buffer >> (BITBUF_WIDTH - (nbits)));
+ else
+ return (int)(bit_buffer & ((1 << (nbits)) - 1));
}
- public void REMOVE_BITS(int nbits, ref uint bitsLeft, ref uint bitBuffer)
+ public void REMOVE_BITS(int nbits, ref uint bits_left, ref uint bit_buffer, bool msb)
{
- bitBuffer >>= nbits;
- bitsLeft -= (uint)nbits;
+ if (msb)
+ {
+ bit_buffer <<= nbits;
+ bits_left -= (uint)nbits;
+ }
+ else
+ {
+ bit_buffer >>= nbits;
+ bits_left -= (uint)nbits;
+ }
}
- public void INJECT_BITS(uint bitdata, int nbits, ref uint bitsLeft, ref uint bitBuffer)
+ public void INJECT_BITS(uint bitdata, int nbits, ref uint bits_left, ref uint bit_buffer, bool msb)
{
- bitBuffer |= bitdata << (int)bitsLeft;
- bitsLeft += (uint)nbits;
+ if (msb)
+ {
+ bit_buffer |= bitdata << (int)bits_left;
+ bits_left += (uint)nbits;
+ }
+ else
+ {
+ bit_buffer |= bitdata << (int)bits_left;
+ bits_left += (uint)nbits;
+ }
}
- public abstract Error READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer);
+ public abstract void READ_BYTES(ref int i_ptr, ref int i_end, ref uint bits_left, ref uint bit_buffer, bool msb);
// lsb_bit_mask[n] = (1 << n) - 1 */
private static readonly ushort[] lsb_bit_mask = new ushort[17]
@@ -224,54 +251,63 @@ namespace LibMSPackSharp.Compression
return (int)(BitBuffer & lsb_bit_mask[nbits]);
}
- public void READ_BITS_T(ref int val, int nbits, ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public void READ_BITS_T(ref int val, int nbits, ref int i_ptr, ref int i_end, ref uint bits_left, ref uint bit_buffer, bool msb)
{
- ENSURE_BITS(nbits, ref i_ptr, ref i_end, ref bitsLeft, ref bitBuffer);
+ ENSURE_BITS(nbits, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
+
val = PEEK_BITS_T(nbits);
- REMOVE_BITS(nbits, ref bitsLeft, ref bitBuffer);
+ REMOVE_BITS(nbits, ref bits_left, ref bit_buffer, msb);
+ Error = Error.MSPACK_ERR_OK;
}
- public Error READ_IF_NEEDED(ref int iPtr, ref int iEnd)
+ public void READ_IF_NEEDED(ref int i_ptr, ref int i_end)
{
- if (iPtr >= iEnd)
+ if (i_ptr >= i_end)
{
- if (ReadInput(this) != Error.MSPACK_ERR_OK)
- return Error;
+ ReadInput();
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
- iPtr = InputPointer;
- iEnd = InputLength;
+ i_ptr = InputPointer;
+ i_end = InputLength;
}
- return Error.MSPACK_ERR_OK;
+ Error = Error.MSPACK_ERR_OK;
}
- private static Error ReadInput(CompressionStream p)
+ private void ReadInput()
{
- int read = p.Sys.Read(p.Input, p.InputBuffer, 0, (int)p.InputBufferSize);
+ int read = Sys.Read(Input, InputBuffer, 0, (int)InputBufferSize);
if (read < 0)
- return p.Error = Error.MSPACK_ERR_READ;
+ {
+ 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 (p.InputEnd != 0)
+ if (InputEnd != 0)
{
Console.WriteLine("out of input bytes");
- return p.Error = Error.MSPACK_ERR_READ;
+ Error = Error.MSPACK_ERR_READ;
+ return;
}
else
{
read = 2;
- p.InputBuffer[0] = p.InputBuffer[1] = 0;
- p.InputEnd = 1;
+ InputBuffer[0] = InputBuffer[1] = 0;
+ InputEnd = 1;
}
}
// Update i_ptr and i_end
- p.InputPointer = 0;
- p.InputLength = read;
- return Error.MSPACK_ERR_OK;
+ InputPointer = 0;
+ InputLength = read;
+ Error = Error.MSPACK_ERR_OK;
}
#endregion
@@ -284,33 +320,50 @@ namespace LibMSPackSharp.Compression
/// 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 int READ_HUFFSYM(ushort[] decodingTable, ref uint var, int tablebits, byte[] lengthTable, int maxsymbols, ref int i, ref ushort sym, ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public int READ_HUFFSYM(ushort[] decodingTable, ref uint var, int tablebits, byte[] lengthTable, int maxsymbols, ref int i, ref int i_ptr, ref int i_end, ref uint bits_left, ref uint bit_buffer, bool msb)
{
- ENSURE_BITS(HUFF_MAXBITS, ref i_ptr, ref i_end, ref bitsLeft, ref bitBuffer);
- sym = decodingTable[PEEK_BITS(tablebits, bitBuffer)];
+ ENSURE_BITS(HUFF_MAXBITS, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb);
+ if (Error != Error.MSPACK_ERR_OK)
+ return (int)Error;
+
+ ushort sym = decodingTable[PEEK_BITS(tablebits, bit_buffer, msb)];
if (sym >= maxsymbols)
{
- int ret = HUFF_TRAVERSE(decodingTable, tablebits, maxsymbols, ref i, ref sym, bitBuffer);
+ int ret = HUFF_TRAVERSE(decodingTable, tablebits, maxsymbols, ref i, ref sym, bit_buffer, msb);
if (ret != 0)
return ret;
}
var = sym;
i = lengthTable[sym];
- REMOVE_BITS(i, ref bitsLeft, ref bitBuffer);
+ REMOVE_BITS(i, ref bits_left, ref bit_buffer, msb);
return (int)Error.MSPACK_ERR_OK;
}
- public int HUFF_TRAVERSE(ushort[] decodingTable, int tablebits, int maxsymbols, ref int i, ref ushort sym, uint bitBuffer)
+ public int HUFF_TRAVERSE(ushort[] decodingTable, int tablebits, int maxsymbols, ref int i, ref ushort sym, uint bit_buffer, bool msb)
{
- i = tablebits - 1;
- do
+ if (msb)
{
- if (i++ > HUFF_MAXBITS)
- return HUFF_ERROR();
+ i = 1 << (BITBUF_WIDTH - tablebits);
+ do
+ {
+ if ((i >>= 1) == 0)
+ return HUFF_ERROR();
- sym = decodingTable[(sym << 1) | ((bitBuffer >> i) & 1)];
- } while (sym >= maxsymbols);
+ sym = decodingTable[(sym << 1) | ((bit_buffer & i) != 0 ? 1 : 0)];
+ } while (sym >= maxsymbols);
+ }
+ else
+ {
+ i = tablebits - 1;
+ do
+ {
+ if (i++ > HUFF_MAXBITS)
+ return HUFF_ERROR();
+
+ try { sym = decodingTable[(sym << 1) | ((bit_buffer >> i) & 1)]; } catch { }
+ } while (sym >= maxsymbols);
+ }
return (int)Error.MSPACK_ERR_OK;
}
@@ -330,94 +383,84 @@ namespace LibMSPackSharp.Compression
/// The table to fill up with decoded symbols and pointers.
/// Should be ((1<
- /// 0 for OK or 1 for error
- public static int MakeDecodeTable(uint nsyms, uint nbits, byte[] length, ushort[] table)
+ /// true for OK or false for error
+ public static bool MakeDecodeTable(int nsyms, int nbits, byte[] length, ushort[] table, bool msb)
{
- 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 << (int)nbits);
- uint bit_mask = table_mask >> 1; // Don't do 0 length codes
+ int next_symbol;
+ long leaf, fill;
+ long reverse; // Only used when !msb
+ long pos = 0; // The current position in the decode table
+ int 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 (byte bit_num = 1; bit_num <= nbits; bit_num++)
{
- for (sym = 0; sym < nsyms; sym++)
+ for (ushort 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
+ if (msb)
{
- leaf <<= 1;
- leaf |= reverse & 1;
- reverse >>= 1;
- } while (--fill != 0);
+ leaf = pos;
+ }
+ else
+ {
+ // Reverse the significant bits
+ fill = length[sym];
+ reverse = pos >> (nbits - (byte)fill);
+ leaf = 0;
+
+ do
+ {
+ leaf <<= 1;
+ leaf |= reverse & 1;
+ reverse >>= 1;
+ } while (--fill != 0);
+ }
if ((pos += bit_mask) > table_mask)
- return 1; // Table overrun
+ 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
+ if (msb)
{
- table[leaf] = sym;
- leaf += next_symbol;
- } while (--fill != 0);
+ for (fill = bit_mask; fill-- > 0;)
+ {
+ table[leaf++] = sym;
+ }
+ }
+ else
+ {
+ fill = bit_mask;
+ next_symbol = 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 0;
+ return true;
// Mark all remaining table entries as unused
- for (sym = (ushort)pos; sym < table_mask; sym++)
+ for (long sym = pos; sym < table_mask; sym++)
{
- reverse = sym;
- leaf = 0;
- fill = nbits;
-
- do
+ if (msb)
{
- leaf <<= 1;
- leaf |= reverse & 1;
- reverse >>= 1;
- } while (--fill != 0);
-
- table[leaf] = 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++)
+ table[sym] = 0xFFFF;
+ }
+ else
{
- if (length[sym] != bit_num)
- continue;
- if (pos >= table_mask)
- return 1; // Table overflow
-
- // Leaf = the first nbits of the code, reversed
- reverse = pos >> 16;
+ reverse = sym;
leaf = 0;
fill = nbits;
@@ -428,19 +471,60 @@ namespace LibMSPackSharp.Compression
reverse >>= 1;
} while (--fill != 0);
+ table[leaf] = 0xFFFF;
+ }
+ }
+
+ // next_symbol = base of allocation for long codes
+ next_symbol = ((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 (int bit_num = nbits + 1; bit_num <= HUFF_MAXBITS; bit_num++)
+ {
+ for (ushort sym = 0; sym < nsyms; sym++)
+ {
+ if (length[sym] != bit_num)
+ continue;
+ if (pos >= table_mask)
+ return false; // Table overflow
+
+ if (msb)
+ {
+ leaf = pos >> 16;
+ }
+ else
+ {
+ // leaf = the first nbits of the code, reversed
+ reverse = pos >> 16;
+ leaf = 0;
+ fill = nbits;
+
+ do
+ {
+ leaf <<= 1;
+ leaf |= reverse & 1;
+ reverse >>= 1;
+ } while (--fill != 0);
+ }
+
for (fill = 0; fill < (bit_num - nbits); fill++)
{
- // Ff this path hasn't been taken yet, 'allocate' two entries
+ // 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++;
+ table[leaf] = (ushort)next_symbol++;
}
// Follow the path and select either left or right for next bit
- leaf = (uint)(table[leaf] << 1);
- if (((pos >> (int)(15 - fill)) & 1) != 0)
+ leaf = table[leaf] << 1;
+ if (((pos >> (15 - (int)fill)) & 1) != 0)
leaf++;
}
@@ -452,7 +536,7 @@ namespace LibMSPackSharp.Compression
}
// Full table?
- return (pos == table_mask) ? 0 : 1;
+ return pos == table_mask;
}
#endregion
diff --git a/BurnOutSharp/External/libmspack/Compression/LZX.cs b/BurnOutSharp/External/libmspack/Compression/LZX.cs
index 550a12df..5b8fe037 100644
--- a/BurnOutSharp/External/libmspack/Compression/LZX.cs
+++ b/BurnOutSharp/External/libmspack/Compression/LZX.cs
@@ -95,13 +95,13 @@ namespace LibMSPackSharp.Compression
// LZX huffman defines: tweak tablebits as desired
public const int LZX_PRETREE_MAXSYMBOLS = LZX_PRETREE_NUM_ELEMENTS;
- public const int LZX_PRETREE_TABLEBITS = 6;
+ public const byte LZX_PRETREE_TABLEBITS = 6;
public const int LZX_MAINTREE_MAXSYMBOLS = LZX_NUM_CHARS + 290 * 8;
- public const int LZX_MAINTREE_TABLEBITS = 12;
+ public const byte LZX_MAINTREE_TABLEBITS = 12;
public const int LZX_LENGTH_MAXSYMBOLS = LZX_NUM_SECONDARY_LENGTHS + 1;
- public const int LZX_LENGTH_TABLEBITS = 12;
+ public const byte LZX_LENGTH_TABLEBITS = 12;
public const int LZX_ALIGNED_MAXSYMBOLS = LZX_ALIGNED_NUM_ELEMENTS;
- public const int LZX_ALIGNED_TABLEBITS = 7;
+ 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
@@ -433,7 +433,6 @@ namespace LibMSPackSharp.Compression
// Bitstream and huffman reading variables
uint bit_buffer = 0, bits_left = 0;
int i_ptr = 0, i_end = 0;
- ushort sym = 0;
int match_length, extra, verbatim_bits = 0, bytes_todo;
int this_run, j = 0, warned = 0;
@@ -502,8 +501,11 @@ namespace LibMSPackSharp.Compression
// LZX DELTA format has chunk_size, not present in LZX format
if (lzx.IsDelta)
{
- lzx.ENSURE_BITS(16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
- lzx.REMOVE_BITS(16, ref bits_left, ref bit_buffer);
+ lzx.ENSURE_BITS(16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ lzx.REMOVE_BITS(16, ref bits_left, ref bit_buffer, msb: true);
}
// Read header if necessary
@@ -512,11 +514,19 @@ namespace LibMSPackSharp.Compression
/* read 1 bit. if bit=0, intel filesize = 0.
* if bit=1, read intel filesize (32 bits) */
j = 0;
- lzx.READ_BITS(ref i, 1, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref i, 1, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
if (i != 0)
{
- lzx.READ_BITS(ref i, 16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
- lzx.READ_BITS(ref j, 16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref i, 16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ lzx.READ_BITS(ref j, 16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
}
lzx.IntelFileSize = (i << 16) | j;
@@ -549,10 +559,19 @@ namespace LibMSPackSharp.Compression
// Read block type (3 bits) and block length (24 bits)
int blockType = 0;
- lzx.READ_BITS(ref blockType, 3, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref blockType, 3, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
lzx.BlockType = (LZXBlockType)blockType;
- lzx.READ_BITS(ref i, 16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
- lzx.READ_BITS(ref j, 8, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref i, 16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ lzx.READ_BITS(ref j, 8, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
lzx.BlockRemaining = lzx.BlockLength = (uint)((i << 8) | j);
// Console.WriteLine("new block t%d len %u", lzx.BlockType, lzx.BlockLength);
@@ -563,12 +582,15 @@ namespace LibMSPackSharp.Compression
case LZXBlockType.LZX_BLOCKTYPE_ALIGNED:
for (i = 0; i < 8; i++)
{
- lzx.READ_BITS(ref j, 3, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref j, 3, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
lzx.ALIGNED_len[i] = (byte)j;
}
//BUILD_TABLE(ALIGNED)
- if (LZXDStream.MakeDecodeTable(LZX_ALIGNED_MAXSYMBOLS, LZX_ALIGNED_TABLEBITS, lzx.ALIGNED_len, lzx.ALIGNED_table) != 0)
+ if (!LZXDStream.MakeDecodeTable(LZX_ALIGNED_MAXSYMBOLS, LZX_ALIGNED_TABLEBITS, lzx.ALIGNED_len, lzx.ALIGNED_table, msb: true))
{
Console.WriteLine("failed to build ALIGNED table");
return lzx.Error = Error.MSPACK_ERR_DECRUNCH;
@@ -589,7 +611,7 @@ namespace LibMSPackSharp.Compression
lzx.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//BUILD_TABLE(MAINTREE)
- if (LZXDStream.MakeDecodeTable(LZX_MAINTREE_MAXSYMBOLS, LZX_MAINTREE_TABLEBITS, lzx.MAINTREE_len, lzx.MAINTREE_table) != 0)
+ if (!LZXDStream.MakeDecodeTable(LZX_MAINTREE_MAXSYMBOLS, LZX_MAINTREE_TABLEBITS, lzx.MAINTREE_len, lzx.MAINTREE_table, msb: true))
{
Console.WriteLine("failed to build MAINTREE table");
return lzx.Error = Error.MSPACK_ERR_DECRUNCH;
@@ -609,7 +631,7 @@ namespace LibMSPackSharp.Compression
//BUILD_TABLE_MAYBE_EMPTY(LENGTH)
lzx.LENGTH_empty = 0;
- if (LZXDStream.MakeDecodeTable(LZX_LENGTH_MAXSYMBOLS, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, lzx.LENGTH_table) != 0)
+ if (!LZXDStream.MakeDecodeTable(LZX_LENGTH_MAXSYMBOLS, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, lzx.LENGTH_table, msb: true))
{
for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)
{
@@ -642,7 +664,7 @@ namespace LibMSPackSharp.Compression
lzx.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
//BUILD_TABLE(MAINTREE)
- if (LZXDStream.MakeDecodeTable(LZX_MAINTREE_MAXSYMBOLS, LZX_MAINTREE_TABLEBITS, lzx.MAINTREE_len, lzx.MAINTREE_table) != 0)
+ if (!LZXDStream.MakeDecodeTable(LZX_MAINTREE_MAXSYMBOLS, LZX_MAINTREE_TABLEBITS, lzx.MAINTREE_len, lzx.MAINTREE_table, msb: true))
{
Console.WriteLine("failed to build MAINTREE table");
return lzx.Error = Error.MSPACK_ERR_DECRUNCH;
@@ -662,7 +684,7 @@ namespace LibMSPackSharp.Compression
//BUILD_TABLE_MAYBE_EMPTY(LENGTH)
lzx.LENGTH_empty = 0;
- if (LZXDStream.MakeDecodeTable(LZX_LENGTH_MAXSYMBOLS, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, lzx.LENGTH_table) != 0)
+ if (!LZXDStream.MakeDecodeTable(LZX_LENGTH_MAXSYMBOLS, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, lzx.LENGTH_table, msb: true))
{
for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)
{
@@ -685,7 +707,11 @@ namespace LibMSPackSharp.Compression
// Read 1-16 (not 0-15) bits to align to bytes
if (bits_left == 0)
- lzx.ENSURE_BITS(16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ {
+ lzx.ENSURE_BITS(16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+ }
bits_left = 0; bit_buffer = 0;
@@ -728,7 +754,9 @@ namespace LibMSPackSharp.Compression
case LZXBlockType.LZX_BLOCKTYPE_VERBATIM:
while (this_run > 0)
{
- lzx.READ_HUFFSYM(lzx.MAINTREE_table, ref main_element, LZX_MAINTREE_TABLEBITS, lzx.MAINTREE_len, LZX_MAINTREE_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzx.READ_HUFFSYM(lzx.MAINTREE_table, ref main_element, LZX_MAINTREE_TABLEBITS, lzx.MAINTREE_len, LZX_MAINTREE_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
+
if (main_element < LZX_NUM_CHARS)
{
// Literal: 0 to LZX_NUM_CHARS-1
@@ -750,7 +778,9 @@ namespace LibMSPackSharp.Compression
return lzx.Error = Error.MSPACK_ERR_DECRUNCH;
}
- lzx.READ_HUFFSYM(lzx.LENGTH_table, ref length_footer, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, LZX_LENGTH_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzx.READ_HUFFSYM(lzx.LENGTH_table, ref length_footer, LZX_LENGTH_TABLEBITS, lzx.LENGTH_len, LZX_LENGTH_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
+
match_length += (int)length_footer;
}
@@ -772,7 +802,10 @@ namespace LibMSPackSharp.Compression
else
{
extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
- lzx.READ_BITS(ref verbatim_bits, extra, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref verbatim_bits, extra, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
match_offset = (uint)(position_base[match_offset] - 2 + verbatim_bits);
}
}
@@ -786,21 +819,31 @@ namespace LibMSPackSharp.Compression
{
// >3: verbatim and aligned bits
extra -= 3;
- lzx.READ_BITS(ref verbatim_bits, extra, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref verbatim_bits, extra, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
match_offset += (uint)(verbatim_bits << 3);
- lzx.READ_HUFFSYM(lzx.ALIGNED_table, ref aligned_bits, LZX_ALIGNED_TABLEBITS, lzx.ALIGNED_len, LZX_ALIGNED_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzx.READ_HUFFSYM(lzx.ALIGNED_table, ref aligned_bits, LZX_ALIGNED_TABLEBITS, lzx.ALIGNED_len, LZX_ALIGNED_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
+
match_offset += aligned_bits;
}
else if (extra == 3)
{
// 3: aligned bits only
- lzx.READ_HUFFSYM(lzx.ALIGNED_table, ref aligned_bits, LZX_ALIGNED_TABLEBITS, lzx.ALIGNED_len, LZX_ALIGNED_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzx.READ_HUFFSYM(lzx.ALIGNED_table, ref aligned_bits, LZX_ALIGNED_TABLEBITS, lzx.ALIGNED_len, LZX_ALIGNED_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
+
match_offset += aligned_bits;
}
else if (extra > 0)
{
// 1-2: verbatim bits only
- lzx.READ_BITS(ref verbatim_bits, extra, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref verbatim_bits, extra, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
match_offset += (uint)verbatim_bits;
}
else
@@ -819,28 +862,43 @@ namespace LibMSPackSharp.Compression
if (match_length == LZX_MAX_MATCH && lzx.IsDelta)
{
int extra_len = 0;
- lzx.ENSURE_BITS(3, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer); /* 4 entry huffman tree */
- if (lzx.PEEK_BITS(1, bit_buffer) == 0)
+
+ /* 4 entry huffman tree */
+ lzx.ENSURE_BITS(3, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ if (lzx.PEEK_BITS(1, bit_buffer, msb: true) == 0)
{
- lzx.REMOVE_BITS(1, ref bits_left, ref bit_buffer); /* '0' . 8 extra length bits */
- lzx.READ_BITS(ref extra_len, 8, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.REMOVE_BITS(1, ref bits_left, ref bit_buffer, msb: true); /* '0' . 8 extra length bits */
+ lzx.READ_BITS(ref extra_len, 8, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
}
- else if (lzx.PEEK_BITS(2, bit_buffer) == 2)
+ else if (lzx.PEEK_BITS(2, bit_buffer, msb: true) == 2)
{
- lzx.REMOVE_BITS(2, ref bits_left, ref bit_buffer); /* '10' . 10 extra length bits + 0x100 */
- lzx.READ_BITS(ref extra_len, 10, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.REMOVE_BITS(2, ref bits_left, ref bit_buffer, msb: true); /* '10' . 10 extra length bits + 0x100 */
+ lzx.READ_BITS(ref extra_len, 10, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
extra_len += 0x100;
}
- else if (lzx.PEEK_BITS(3, bit_buffer) == 6)
+ else if (lzx.PEEK_BITS(3, bit_buffer, msb: true) == 6)
{
- lzx.REMOVE_BITS(3, ref bits_left, ref bit_buffer); /* '110' . 12 extra length bits + 0x500 */
- lzx.READ_BITS(ref extra_len, 12, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.REMOVE_BITS(3, ref bits_left, ref bit_buffer, msb: true); /* '110' . 12 extra length bits + 0x500 */
+ lzx.READ_BITS(ref extra_len, 12, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
extra_len += 0x500;
}
else
{
- lzx.REMOVE_BITS(3, ref bits_left, ref bit_buffer); /* '111' . 15 extra length bits */
- lzx.READ_BITS(ref extra_len, 15, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.REMOVE_BITS(3, ref bits_left, ref bit_buffer, msb: true); /* '111' . 15 extra length bits */
+ lzx.READ_BITS(ref extra_len, 15, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
}
match_length += extra_len;
@@ -960,10 +1018,14 @@ namespace LibMSPackSharp.Compression
// Re-align input bitstream
if (bits_left > 0)
- lzx.ENSURE_BITS(16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ {
+ lzx.ENSURE_BITS(16, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+ }
if ((bits_left & 15) != 0)
- lzx.REMOVE_BITS((int)(bits_left & 15), ref bits_left, ref bit_buffer);
+ lzx.REMOVE_BITS((int)(bits_left & 15), ref bits_left, ref bit_buffer, msb: true);
// Check that we've used all of the previous frame first
if (lzx.OutputPointer != lzx.OutputLength)
@@ -1072,7 +1134,6 @@ namespace LibMSPackSharp.Compression
// Bit buffer and huffman symbol decode variables
uint bit_buffer = 0, bits_left = 0;
int i = 0;
- ushort sym = 0;
int i_ptr = 0, i_end = 0;
int x, y = 0;
@@ -1083,12 +1144,15 @@ namespace LibMSPackSharp.Compression
// Read lengths for pretree (20 symbols, lengths stored in fixed 4 bits)
for (x = 0; x < 20; x++)
{
- lzx.READ_BITS(ref y, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzx.READ_BITS(ref y, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
lzx.PRETREE_len[x] = (byte)y;
}
//BUILD_TABLE(PRETREE)
- if (LZXDStream.MakeDecodeTable(LZX_PRETREE_MAXSYMBOLS, LZX_PRETREE_TABLEBITS, lzx.PRETREE_len, lzx.PRETREE_table) != 0)
+ if (!LZXDStream.MakeDecodeTable(LZX_PRETREE_MAXSYMBOLS, LZX_PRETREE_TABLEBITS, lzx.PRETREE_len, lzx.PRETREE_table, msb: true))
{
Console.WriteLine("failed to build PRETREE table");
return lzx.Error = Error.MSPACK_ERR_DECRUNCH;
@@ -1096,11 +1160,17 @@ namespace LibMSPackSharp.Compression
for (x = (int)first; x < last;)
{
- lzx.READ_HUFFSYM(lzx.PRETREE_table, ref z, LZX_PRETREE_TABLEBITS, lzx.PRETREE_len, LZX_PRETREE_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzx.READ_HUFFSYM(lzx.PRETREE_table, ref z, LZX_PRETREE_TABLEBITS, lzx.PRETREE_len, LZX_PRETREE_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_OK;
+
if (z == 17)
{
// Code = 17, run of ([read 4 bits]+4) zeros
- lzx.READ_BITS(ref y, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); y += 4;
+ lzx.READ_BITS(ref y, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ y += 4;
while (y-- != 0)
{
lens[x++] = 0;
@@ -1109,7 +1179,11 @@ namespace LibMSPackSharp.Compression
else if (z == 18)
{
// Code = 18, run of ([read 5 bits]+20) zeros
- lzx.READ_BITS(ref y, 5, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); y += 20;
+ lzx.READ_BITS(ref y, 5, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ y += 20;
while (y-- != 0)
{
lens[x++] = 0;
@@ -1118,8 +1192,14 @@ namespace LibMSPackSharp.Compression
else if (z == 19)
{
// Code = 19, run of ([read 1 bit]+4) [read huffman symbol]
- lzx.READ_BITS(ref y, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left); y += 4;
- lzx.READ_HUFFSYM(lzx.PRETREE_table, ref z, LZX_PRETREE_TABLEBITS, lzx.PRETREE_len, LZX_PRETREE_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ lzx.READ_BITS(ref y, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (lzx.Error != Error.MSPACK_ERR_OK)
+ return lzx.Error;
+
+ y += 4;
+ if (lzx.READ_HUFFSYM(lzx.PRETREE_table, ref z, LZX_PRETREE_TABLEBITS, lzx.PRETREE_len, LZX_PRETREE_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
+
z = lens[x] - z;
if (z < 0)
z += 17;
diff --git a/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs b/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs
index 8de76563..2e507714 100644
--- a/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs
+++ b/BurnOutSharp/External/libmspack/Compression/LZXDStream.cs
@@ -137,21 +137,21 @@ namespace LibMSPackSharp.Compression
// This is used purely for doing the intel E8 transform
public byte[] e8_buf { get; set; } = new byte[LZX.LZX_FRAME_SIZE];
- public override Error READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public override void READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer, bool msb)
{
- Error error = READ_IF_NEEDED(ref i_ptr, ref i_end);
- if (error != Error.MSPACK_ERR_OK)
- return error;
+ READ_IF_NEEDED(ref i_ptr, ref i_end);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
byte b0 = InputBuffer[i_ptr++];
- error = READ_IF_NEEDED(ref i_ptr, ref i_end);
- if (error != Error.MSPACK_ERR_OK)
- return error;
+ READ_IF_NEEDED(ref i_ptr, ref i_end);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
byte b1 = InputBuffer[i_ptr++];
- INJECT_BITS((uint)((b1 << 8) | b0), 16, ref bitsLeft, ref bitBuffer);
- return Error.MSPACK_ERR_OK;
+ INJECT_BITS((uint)((b1 << 8) | b0), 16, ref bitsLeft, ref bitBuffer, msb);
+ Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)(Error = Error.MSPACK_ERR_DECRUNCH);
diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
index 61403587..ff4f6fc1 100644
--- a/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
+++ b/BurnOutSharp/External/libmspack/Compression/MSZIP.cs
@@ -27,27 +27,12 @@ namespace LibMSPackSharp.Compression
// 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 static int MSZIP_LITERAL_TABLESIZE
- {
- get
- {
- if ((1 << MSZIP_LITERAL_TABLEBITS) < (MSZIP_LITERAL_MAXSYMBOLS * 2))
- return (MSZIP_LITERAL_MAXSYMBOLS * 4);
- else
- return ((1 << MSZIP_LITERAL_TABLEBITS) + (MSZIP_LITERAL_MAXSYMBOLS * 2));
- }
- }
- public static int MSZIP_DISTANCE_TABLESIZE
- {
- get
- {
- if ((1 << MSZIP_DISTANCE_TABLEBITS) < (MSZIP_DISTANCE_MAXSYMBOLS * 2))
- return (MSZIP_DISTANCE_MAXSYMBOLS * 4);
- else
- return ((1 << MSZIP_DISTANCE_TABLEBITS) + (MSZIP_DISTANCE_MAXSYMBOLS * 2));
- }
- }
+ //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
@@ -203,12 +188,15 @@ namespace LibMSPackSharp.Compression
// Skip to next read 'CK' header
i = (int)(bits_left & 7);
- zip.REMOVE_BITS(i, ref bits_left, ref bit_buffer); // Align to bytestream
+ zip.REMOVE_BITS(i, ref bits_left, ref bit_buffer, msb: false); // Align to bytestream
state = 0;
do
{
- zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return zip.Error;
+
if (i == 'C')
state = 1;
else if ((state == 1) && (i == 'K'))
@@ -224,7 +212,7 @@ namespace LibMSPackSharp.Compression
if ((error = (int)Inflate(zip)) != 0)
{
- Console.WriteLine($"inflate error {error}");
+ Console.WriteLine($"inflate error {(InflateErrorCode)error}");
if (zip.RepairMode)
{
// Recover partially-inflated buffers
@@ -249,8 +237,16 @@ namespace LibMSPackSharp.Compression
// Write a frame
i = (out_bytes < zip.BytesOutput) ? (int)out_bytes : zip.BytesOutput;
- if (zip.Sys.Write(zip.Output, zip.Window, zip.OutputPointer, i) != i)
- return zip.Error = Error.MSPACK_ERR_WRITE;
+ if (zip.Output is DefaultFileImpl)
+ {
+ if (SystemImpl.DefaultSystem.Write(zip.Output, zip.Window, zip.OutputPointer, i) != i)
+ return zip.Error = Error.MSPACK_ERR_WRITE;
+ }
+ else
+ {
+ if (zip.Sys.Write(zip.Output, zip.Window, zip.OutputPointer, i) != i)
+ return zip.Error = Error.MSPACK_ERR_WRITE;
+ }
// mspack errors (i.e. read errors) are fatal and can't be recovered
if (error > 0 && zip.RepairMode)
@@ -288,20 +284,30 @@ namespace LibMSPackSharp.Compression
// Align to bytestream, read block_len
i = (int)(bits_left & 7);
- zip.REMOVE_BITS(i, ref bits_left, ref bit_buffer);
- zip.READ_BITS(ref block_len, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.REMOVE_BITS(i, ref bits_left, ref bit_buffer, msb: false);
+ zip.READ_BITS(ref block_len, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return zip.Error;
+
+ zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return zip.Error;
+
block_len |= i << 8;
if (block_len == 0)
break;
// Read "CK" header
- zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return zip.Error;
if (i != 'C')
return Error.MSPACK_ERR_DATAFORMAT;
- zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return zip.Error;
if (i != 'K')
return Error.MSPACK_ERR_DATAFORMAT;
@@ -311,7 +317,7 @@ namespace LibMSPackSharp.Compression
zip.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
if ((error = (int)Inflate(zip)) != 0)
{
- Console.WriteLine($"inflate error {error}");
+ Console.WriteLine($"inflate error {(InflateErrorCode)error}");
return zip.Error = (error > 0) ? (Error)error : Error.MSPACK_ERR_DECRUNCH;
}
@@ -339,7 +345,7 @@ namespace LibMSPackSharp.Compression
}
}
- private static InflateErrorCode ZipReadLens(MSZIPDStream zip)
+ private static InflateErrorCode ReadLens(MSZIPDStream zip)
{
// For the bit buffer and huffman decoding
uint bit_buffer = 0, bits_left = 0;
@@ -355,11 +361,20 @@ namespace LibMSPackSharp.Compression
zip.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
// Read the number of codes
- zip.READ_BITS(ref lit_codes, 5, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref lit_codes, 5, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
+
lit_codes += 257;
- zip.READ_BITS(ref dist_codes, 5, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref dist_codes, 5, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
+
dist_codes += 1;
- zip.READ_BITS(ref bitlen_codes, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref bitlen_codes, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
+
bitlen_codes += 4;
if (lit_codes > MSZIP_LITERAL_MAXSYMBOLS)
@@ -371,7 +386,10 @@ namespace LibMSPackSharp.Compression
for (i = 0; i < bitlen_codes; i++)
{
int blLenTemp = bl_len[bitlen_order[i]];
- zip.READ_BITS(ref blLenTemp, 3, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref blLenTemp, 3, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
+
bl_len[bitlen_order[i]] = (byte)blLenTemp;
}
@@ -380,17 +398,20 @@ namespace LibMSPackSharp.Compression
bl_len[bitlen_order[i++]] = 0;
}
- // Create decoding table with an immediate lookup */
- if (MSZIPDStream.MakeDecodeTable(19, 7, bl_len, bl_table) != 0)
+ // Create decoding table with an immediate lookup
+ if (!MSZIPDStream.MakeDecodeTable(19, 7, bl_len, bl_table, msb: false))
return InflateErrorCode.INF_ERR_BITLENTBL;
// Read literal / distance code lengths
for (i = 0; i < (lit_codes + dist_codes); i++)
{
// Single-level huffman lookup
- zip.ENSURE_BITS(7, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- code = bl_table[zip.PEEK_BITS(7, bit_buffer)];
- zip.REMOVE_BITS(bl_len[code], ref bits_left, ref bit_buffer);
+ zip.ENSURE_BITS(7, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITBUF;
+
+ code = bl_table[zip.PEEK_BITS(7, bit_buffer, msb: false)];
+ zip.REMOVE_BITS(bl_len[code], ref bits_left, ref bit_buffer, msb: false);
if (code < 16)
{
@@ -401,19 +422,28 @@ namespace LibMSPackSharp.Compression
switch (code)
{
case 16:
- zip.READ_BITS(ref run, 2, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref run, 2, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
+
run += 3;
code = last_code;
break;
case 17:
- zip.READ_BITS(ref run, 3, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref run, 3, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
+
run += 3;
code = 0;
break;
case 18:
- zip.READ_BITS(ref run, 7, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref run, 7, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
+
run += 11;
code = 0;
break;
@@ -463,18 +493,22 @@ namespace LibMSPackSharp.Compression
// For the bit buffer and huffman decoding
uint bit_buffer = 0, bits_left = 0;
- ushort sym = 0;
int i_ptr = 0, i_end = 0;
+ InflateErrorCode err;
zip.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
do
{
// Read in last block bit
- zip.READ_BITS(ref last_block, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref last_block, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
// Read in block type
- zip.READ_BITS(ref block_type, 2, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS(ref block_type, 2, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITOVERRUN;
if (block_type == 0)
{
@@ -483,7 +517,7 @@ namespace LibMSPackSharp.Compression
// Go to byte boundary
i = (int)(bits_left & 7);
- zip.REMOVE_BITS(i, ref bits_left, ref bit_buffer);
+ zip.REMOVE_BITS(i, ref bits_left, ref bit_buffer, msb: false);
// Read 4 bytes of data, emptying the bit-buffer if necessary
for (i = 0; (bits_left >= 8); i++)
@@ -491,13 +525,19 @@ namespace LibMSPackSharp.Compression
if (i == 4)
return InflateErrorCode.INF_ERR_BITBUF;
- lens_buf[i] = (byte)zip.PEEK_BITS(8, bit_buffer);
- zip.REMOVE_BITS(8, ref bits_left, ref bit_buffer);
+ lens_buf[i] = (byte)zip.PEEK_BITS(8, bit_buffer, msb: false);
+ zip.REMOVE_BITS(8, ref bits_left, ref bit_buffer, msb: false);
}
- if (bits_left != 0) return InflateErrorCode.INF_ERR_BITBUF;
+
+ if (bits_left != 0)
+ return InflateErrorCode.INF_ERR_BITBUF;
+
while (i < 4)
{
zip.READ_IF_NEEDED(ref i_ptr, ref i_end);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITBUF;
+
lens_buf[i++] = zip.InputBuffer[i_ptr++];
}
@@ -511,9 +551,13 @@ namespace LibMSPackSharp.Compression
while (length > 0)
{
zip.READ_IF_NEEDED(ref i_ptr, ref i_end);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_BITBUF;
this_run = length;
- if (this_run > (uint)(i_end - i_ptr)) this_run = i_end - i_ptr;
+ if (this_run > (uint)(i_end - i_ptr))
+ this_run = i_end - i_ptr;
+
if (this_run > (MSZIP_FRAME_SIZE - zip.WindowPosition))
this_run = (int)(MSZIP_FRAME_SIZE - zip.WindowPosition);
@@ -571,7 +615,7 @@ namespace LibMSPackSharp.Compression
// Block with dynamic Huffman codes
zip.STORE_BITS(i_ptr, i_end, bit_buffer, bits_left);
- if ((i = (int)ZipReadLens(zip)) != 0)
+ if ((i = (int)ReadLens(zip)) != 0)
return (InflateErrorCode)i;
zip.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
@@ -579,16 +623,24 @@ namespace LibMSPackSharp.Compression
// Now huffman lengths are read for either kind of block,
// create huffman decoding tables
- if (MSZIPDStream.MakeDecodeTable(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS, zip.LITERAL_len, zip.LITERAL_table) != 0)
- return InflateErrorCode.INF_ERR_LITERALTBL;
+ if (!MSZIPDStream.MakeDecodeTable(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS, zip.LITERAL_len, zip.LITERAL_table, msb: false))
+ {
+ // TODO: Figure out why this always gets hit
+ //return InflateErrorCode.INF_ERR_LITERALTBL;
+ }
- if (MSZIPDStream.MakeDecodeTable(MSZIP_DISTANCE_MAXSYMBOLS, MSZIP_DISTANCE_TABLEBITS, zip.DISTANCE_len, zip.DISTANCE_table) != 0)
- return InflateErrorCode.INF_ERR_DISTANCETBL;
+ if (!MSZIPDStream.MakeDecodeTable(MSZIP_DISTANCE_MAXSYMBOLS, MSZIP_DISTANCE_TABLEBITS, zip.DISTANCE_len, zip.DISTANCE_table, msb: false))
+ {
+ // TODO: Figure out why this always gets hit
+ //return InflateErrorCode.INF_ERR_DISTANCETBL;
+ }
// Decode forever until end of block code
for (; ; )
{
- zip.READ_HUFFSYM(zip.LITERAL_table, ref code, MSZIP_LITERAL_TABLEBITS, zip.LITERAL_len, MSZIP_LITERAL_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if ((err = (InflateErrorCode)zip.READ_HUFFSYM(zip.LITERAL_table, ref code, MSZIP_LITERAL_TABLEBITS, zip.LITERAL_len, MSZIP_LITERAL_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: false)) != InflateErrorCode.INF_ERR_OK)
+ return err;
+
if (code < 256)
{
zip.Window[zip.WindowPosition++] = (byte)code;
@@ -613,14 +665,22 @@ namespace LibMSPackSharp.Compression
if (code >= 29)
return InflateErrorCode.INF_ERR_LITCODE; // Codes 286-287 are illegal
- zip.READ_BITS_T(ref length, lit_extrabits[code], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS_T(ref length, lit_extrabits[code], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_LITCODE;
+
length += lit_lengths[code];
- zip.READ_HUFFSYM(zip.DISTANCE_table, ref code, MSZIP_DISTANCE_TABLEBITS, zip.DISTANCE_len, MSZIP_DISTANCE_MAXSYMBOLS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if ((err = (InflateErrorCode)zip.READ_HUFFSYM(zip.DISTANCE_table, ref code, MSZIP_DISTANCE_TABLEBITS, zip.DISTANCE_len, MSZIP_DISTANCE_MAXSYMBOLS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: false)) != 0)
+ return err;
+
if (code >= 30)
return InflateErrorCode.INF_ERR_DISTCODE;
- zip.READ_BITS_T(ref distance, dist_extrabits[code], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ zip.READ_BITS_T(ref distance, dist_extrabits[code], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: false);
+ if (zip.Error != Error.MSPACK_ERR_OK)
+ return InflateErrorCode.INF_ERR_DISTCODE;
+
distance += dist_offsets[code];
// Match position is window position minus distance. If distance
diff --git a/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs b/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs
index d07c714b..96d7675a 100644
--- a/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs
+++ b/BurnOutSharp/External/libmspack/Compression/MSZIPDStream.cs
@@ -49,14 +49,14 @@ namespace LibMSPackSharp.Compression
#endregion
- public override Error READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public override void READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer, bool msb)
{
- Error error = READ_IF_NEEDED(ref i_ptr, ref i_end);
- if (error != Error.MSPACK_ERR_OK)
- return error;
+ READ_IF_NEEDED(ref i_ptr, ref i_end);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
- INJECT_BITS(InputBuffer[i_ptr++], 8, ref bitsLeft, ref bitBuffer);
- return Error.MSPACK_ERR_OK;
+ INJECT_BITS(InputBuffer[i_ptr++], 8, ref bitsLeft, ref bitBuffer, msb);
+ Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)InflateErrorCode.INF_ERR_HUFFSYM;
diff --git a/BurnOutSharp/External/libmspack/Compression/QTM.cs b/BurnOutSharp/External/libmspack/Compression/QTM.cs
index 463cf025..3a254ab5 100644
--- a/BurnOutSharp/External/libmspack/Compression/QTM.cs
+++ b/BurnOutSharp/External/libmspack/Compression/QTM.cs
@@ -225,7 +225,7 @@ namespace LibMSPackSharp.Compression
high = 0xFFFF;
low = 0;
int tempCurrent = current;
- qtm.READ_BITS(ref tempCurrent, 16, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ qtm.READ_BITS(ref tempCurrent, 16, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
current = (ushort)tempCurrent;
qtm.HeaderRead = 1;
}
@@ -266,7 +266,10 @@ namespace LibMSPackSharp.Compression
// Selector 4 = fixed length match (3 bytes)
case 4:
GET_SYMBOL(qtm, qtm.Model4, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (qtm.Error != Error.MSPACK_ERR_OK)
+ return qtm.Error;
+
match_offset = position_base[sym] + extra + 1;
match_length = 3;
break;
@@ -274,7 +277,10 @@ namespace LibMSPackSharp.Compression
// Selector 5 = fixed length match (4 bytes)
case 5:
GET_SYMBOL(qtm, qtm.Model5, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (qtm.Error != Error.MSPACK_ERR_OK)
+ return qtm.Error;
+
match_offset = position_base[sym] + extra + 1;
match_length = 4;
break;
@@ -282,11 +288,17 @@ namespace LibMSPackSharp.Compression
// Selector 6 = variable length match
case 6:
GET_SYMBOL(qtm, qtm.Model6Len, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- qtm.READ_MANY_BITS(ref extra, length_extra[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ qtm.READ_MANY_BITS(ref extra, length_extra[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (qtm.Error != Error.MSPACK_ERR_OK)
+ return qtm.Error;
+
match_length = (int)(length_base[sym] + extra + 5);
GET_SYMBOL(qtm, qtm.Model6, ref sym, ref range, ref symf, ref high, ref low, ref current, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ qtm.READ_MANY_BITS(ref extra, extra_bits[sym], ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (qtm.Error != Error.MSPACK_ERR_OK)
+ return qtm.Error;
+
match_offset = position_base[sym] + extra + 1;
break;
@@ -407,14 +419,14 @@ namespace LibMSPackSharp.Compression
{
// Re-align input
if ((bits_left & 7) != 0)
- qtm.REMOVE_BITS((int)bits_left & 7, ref bits_left, ref bit_buffer);
+ qtm.REMOVE_BITS((int)bits_left & 7, ref bits_left, ref bit_buffer, msb: true);
// 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
{
- qtm.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ qtm.READ_BITS(ref i, 8, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
} while (i != 0xFF);
qtm.HeaderRead = 0;
@@ -533,9 +545,13 @@ namespace LibMSPackSharp.Compression
low <<= 1;
high = (ushort)((high << 1) | 1);
- qtm.ENSURE_BITS(1, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
- current = (ushort)((current << 1) | qtm.PEEK_BITS(1, bit_buffer));
- qtm.REMOVE_BITS(1, ref bits_left, ref bit_buffer);
+
+ qtm.ENSURE_BITS(1, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true);
+ if (qtm.Error != Error.MSPACK_ERR_OK)
+ return;
+
+ current = (ushort)((current << 1) | qtm.PEEK_BITS(1, bit_buffer, msb: true));
+ qtm.REMOVE_BITS(1, ref bits_left, ref bit_buffer, msb: true);
}
}
diff --git a/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs b/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs
index d11c09b5..0ab08a4b 100644
--- a/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs
+++ b/BurnOutSharp/External/libmspack/Compression/QTMDStream.cs
@@ -120,21 +120,21 @@ namespace LibMSPackSharp.Compression
public QTMDModelSym[] Model7Symbols { get; set; } = new QTMDModelSym[7 + 1];
- public override Error READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public override void READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer, bool msb)
{
- Error error = READ_IF_NEEDED(ref i_ptr, ref i_end);
- if (error != Error.MSPACK_ERR_OK)
- return error;
+ READ_IF_NEEDED(ref i_ptr, ref i_end);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
byte b0 = InputBuffer[i_ptr++];
- error = READ_IF_NEEDED(ref i_ptr, ref i_end);
- if (error != Error.MSPACK_ERR_OK)
- return error;
+ READ_IF_NEEDED(ref i_ptr, ref i_end);
+ if (Error != Error.MSPACK_ERR_OK)
+ return;
byte b1 = InputBuffer[i_ptr++];
- INJECT_BITS((uint)((b0 << 8) | b1), 16, ref bitsLeft, ref bitBuffer);
- return Error.MSPACK_ERR_OK;
+ INJECT_BITS((uint)((b0 << 8) | b1), 16, ref bitsLeft, ref bitBuffer, msb);
+ Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)Error.MSPACK_ERR_OK;
diff --git a/BurnOutSharp/External/libmspack/KWAJ/Implementation.cs b/BurnOutSharp/External/libmspack/KWAJ/Implementation.cs
index 448f659f..14a5604c 100644
--- a/BurnOutSharp/External/libmspack/KWAJ/Implementation.cs
+++ b/BurnOutSharp/External/libmspack/KWAJ/Implementation.cs
@@ -45,60 +45,21 @@ namespace LibMSPackSharp.KWAJ
// Define decoding table sizes
public const int KWAJ_TABLESIZE = (1 << KWAJ_TABLEBITS);
- public static int KWAJ_MATCHLEN1_TBLSIZE
- {
- get
- {
- if (KWAJ_TABLESIZE < (KWAJ_MATCHLEN1_SYMS * 2))
- return (KWAJ_MATCHLEN1_SYMS * 4);
- else
- return (KWAJ_TABLESIZE + (KWAJ_MATCHLEN1_SYMS * 2));
- }
- }
- public static int KWAJ_MATCHLEN2_TBLSIZE
- {
- get
- {
- if (KWAJ_TABLESIZE < (KWAJ_MATCHLEN2_SYMS * 2))
- return (KWAJ_MATCHLEN2_SYMS * 4);
- else
- return (KWAJ_TABLESIZE + (KWAJ_MATCHLEN2_SYMS * 2));
- }
- }
+ //public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_MATCHLEN1_SYMS * 4);
+ public const int KWAJ_MATCHLEN1_TBLSIZE = (KWAJ_TABLESIZE + (KWAJ_MATCHLEN1_SYMS * 2));
- public static int KWAJ_LITLEN_TBLSIZE
- {
- get
- {
- if (KWAJ_TABLESIZE < (KWAJ_LITLEN_SYMS * 2))
- return (KWAJ_LITLEN_SYMS * 4);
- else
- return (KWAJ_TABLESIZE + (KWAJ_LITLEN_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 static int KWAJ_OFFSET_TBLSIZE
- {
- get
- {
- if (KWAJ_TABLESIZE < (KWAJ_OFFSET_SYMS * 2))
- return (KWAJ_OFFSET_SYMS * 4);
- else
- return (KWAJ_TABLESIZE + (KWAJ_OFFSET_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 static int KWAJ_LITERAL_TBLSIZE
- {
- get
- {
- if (KWAJ_TABLESIZE < (KWAJ_LITERAL_SYMS * 2))
- return (KWAJ_LITERAL_SYMS * 4);
- else
- return (KWAJ_TABLESIZE + (KWAJ_LITERAL_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
@@ -465,7 +426,6 @@ namespace LibMSPackSharp.KWAJ
{
uint bit_buffer = 0, bits_left = 0, len = 0, j = 0;
int i;
- ushort sym = 0;
int i_ptr = 0, i_end = 0;
bool lit_run = false;
int pos = 0, offset;
@@ -483,7 +443,9 @@ namespace LibMSPackSharp.KWAJ
for (i = 0; i < 6; i++)
{
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref types[i], 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref types[i], 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (lzh.Error != Error.MSPACK_ERR_OK)
+ return lzh.Error;
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
}
@@ -497,7 +459,7 @@ namespace LibMSPackSharp.KWAJ
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- if (InternalStream.MakeDecodeTable(KWAJ_MATCHLEN1_SYMS, (uint)KWAJ_MATCHLEN1_TBLSIZE, lzh.MATCHLEN1_len, lzh.MATCHLEN1_table) != 0)
+ if (!InternalStream.MakeDecodeTable(KWAJ_MATCHLEN1_SYMS, KWAJ_MATCHLEN1_TBLSIZE, lzh.MATCHLEN1_len, lzh.MATCHLEN1_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
@@ -507,7 +469,7 @@ namespace LibMSPackSharp.KWAJ
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- if (InternalStream.MakeDecodeTable(KWAJ_MATCHLEN2_SYMS, (uint)KWAJ_MATCHLEN2_TBLSIZE, lzh.MATCHLEN2_len, lzh.MATCHLEN2_table) != 0)
+ if (!InternalStream.MakeDecodeTable(KWAJ_MATCHLEN2_SYMS, KWAJ_MATCHLEN2_TBLSIZE, lzh.MATCHLEN2_len, lzh.MATCHLEN2_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
@@ -517,7 +479,7 @@ namespace LibMSPackSharp.KWAJ
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- if (InternalStream.MakeDecodeTable(KWAJ_LITLEN_SYMS, (uint)KWAJ_LITLEN_TBLSIZE, lzh.LITLEN_len, lzh.LITLEN_table) != 0)
+ if (!InternalStream.MakeDecodeTable(KWAJ_LITLEN_SYMS, KWAJ_LITLEN_TBLSIZE, lzh.LITLEN_len, lzh.LITLEN_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
@@ -527,7 +489,7 @@ namespace LibMSPackSharp.KWAJ
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- if (InternalStream.MakeDecodeTable(KWAJ_OFFSET_SYMS, (uint)KWAJ_OFFSET_TBLSIZE, lzh.OFFSET_len, lzh.OFFSET_table) != 0)
+ if (!InternalStream.MakeDecodeTable(KWAJ_OFFSET_SYMS, KWAJ_OFFSET_TBLSIZE, lzh.OFFSET_len, lzh.OFFSET_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
//BUILD_TREE(tbl, type)
@@ -537,7 +499,7 @@ namespace LibMSPackSharp.KWAJ
return err;
lzh.RESTORE_BITS(ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
- if (InternalStream.MakeDecodeTable(KWAJ_LITERAL_SYMS, (uint)KWAJ_LITERAL_TBLSIZE, lzh.LITERAL_len, lzh.LITERAL_table) != 0)
+ if (!InternalStream.MakeDecodeTable(KWAJ_LITERAL_SYMS, KWAJ_LITERAL_TBLSIZE, lzh.LITERAL_len, lzh.LITERAL_table, msb: true))
return Error.MSPACK_ERR_DATAFORMAT;
while (lzh.InputEnd == 0)
@@ -545,14 +507,16 @@ namespace LibMSPackSharp.KWAJ
if (lit_run)
{
//READ_HUFFSYM_SAFE(tbl, val)
- lzh.READ_HUFFSYM(lzh.MATCHLEN2_table, ref len, KWAJ_MATCHLEN2_TBLSIZE, lzh.MATCHLEN2_len, KWAJ_MATCHLEN2_SYMS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzh.READ_HUFFSYM(lzh.MATCHLEN2_table, ref len, KWAJ_MATCHLEN2_TBLSIZE, lzh.MATCHLEN2_len, KWAJ_MATCHLEN2_SYMS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
}
else
{
//READ_HUFFSYM_SAFE(tbl, val)
- lzh.READ_HUFFSYM(lzh.MATCHLEN1_table, ref len, KWAJ_MATCHLEN1_TBLSIZE, lzh.MATCHLEN1_len, KWAJ_MATCHLEN1_SYMS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzh.READ_HUFFSYM(lzh.MATCHLEN1_table, ref len, KWAJ_MATCHLEN1_TBLSIZE, lzh.MATCHLEN1_len, KWAJ_MATCHLEN1_SYMS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
}
@@ -563,7 +527,8 @@ namespace LibMSPackSharp.KWAJ
lit_run = false; // Not the end of a literal run
//READ_HUFFSYM_SAFE(tbl, val)
- lzh.READ_HUFFSYM(lzh.OFFSET_table, ref j, KWAJ_OFFSET_TBLSIZE, lzh.OFFSET_len, KWAJ_OFFSET_SYMS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzh.READ_HUFFSYM(lzh.OFFSET_table, ref j, KWAJ_OFFSET_TBLSIZE, lzh.OFFSET_len, KWAJ_OFFSET_SYMS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -571,7 +536,9 @@ namespace LibMSPackSharp.KWAJ
//READ_BITS_SAFE(val, n)
int tempj = (int)j;
- lzh.READ_BITS(ref tempj, 6, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref tempj, 6, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
+ if (lzh.Error != Error.MSPACK_ERR_OK)
+ return lzh.Error;
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -591,7 +558,8 @@ namespace LibMSPackSharp.KWAJ
else
{
//READ_HUFFSYM_SAFE(tbl, val)
- lzh.READ_HUFFSYM(lzh.LITLEN_table, ref len, KWAJ_LITLEN_TBLSIZE, lzh.LITLEN_len, KWAJ_LITLEN_SYMS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzh.READ_HUFFSYM(lzh.LITLEN_table, ref len, KWAJ_LITLEN_TBLSIZE, lzh.LITLEN_len, KWAJ_LITLEN_SYMS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -601,7 +569,8 @@ namespace LibMSPackSharp.KWAJ
while (len-- > 0)
{
//READ_HUFFSYM_SAFE(tbl, val)
- lzh.READ_HUFFSYM(lzh.LITERAL_table, ref j, KWAJ_LITERAL_TBLSIZE, lzh.LITERAL_len, KWAJ_LITERAL_SYMS, ref i, ref sym, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer);
+ if (lzh.READ_HUFFSYM(lzh.LITERAL_table, ref j, KWAJ_LITERAL_TBLSIZE, lzh.LITERAL_len, KWAJ_LITERAL_SYMS, ref i, ref i_ptr, ref i_end, ref bits_left, ref bit_buffer, msb: true) != 0)
+ return Error.MSPACK_ERR_DECRUNCH;
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -650,7 +619,7 @@ namespace LibMSPackSharp.KWAJ
case 1:
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -658,7 +627,7 @@ namespace LibMSPackSharp.KWAJ
for (i = 1; i < numsyms; i++)
{
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref sel, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref sel, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -669,7 +638,7 @@ namespace LibMSPackSharp.KWAJ
else
{
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref sel, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref sel, 1, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -680,7 +649,7 @@ namespace LibMSPackSharp.KWAJ
else
{
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -692,7 +661,7 @@ namespace LibMSPackSharp.KWAJ
case 2:
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
@@ -700,14 +669,14 @@ namespace LibMSPackSharp.KWAJ
for (i = 1; i < numsyms; i++)
{
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref sel, 2, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref sel, 2, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
if (sel == 3)
{
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
}
@@ -725,7 +694,7 @@ namespace LibMSPackSharp.KWAJ
for (i = 0; i < numsyms; i++)
{
//READ_BITS_SAFE(val, n)
- lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left);
+ lzh.READ_BITS(ref c, 4, ref i_ptr, ref i_end, ref bit_buffer, ref bits_left, msb: true);
if (lzh.InputEnd != 0 && bits_left < lzh.InputEnd)
return Error.MSPACK_ERR_OK;
diff --git a/BurnOutSharp/External/libmspack/KWAJ/InternalStream.cs b/BurnOutSharp/External/libmspack/KWAJ/InternalStream.cs
index d934b924..027e2c34 100644
--- a/BurnOutSharp/External/libmspack/KWAJ/InternalStream.cs
+++ b/BurnOutSharp/External/libmspack/KWAJ/InternalStream.cs
@@ -33,20 +33,19 @@ namespace LibMSPackSharp.KWAJ
public byte[] Window { get; set; } = new byte[LZSS.LZSS_WINDOW_SIZE];
- public override Error READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer)
+ public override void READ_BYTES(ref int i_ptr, ref int i_end, ref uint bitsLeft, ref uint bitBuffer, bool msb)
{
- Error error = Error.MSPACK_ERR_OK;
if (i_ptr >= i_end)
{
- if ((error = Implementation.LZHReadInput(this)) != Error.MSPACK_ERR_OK)
- return error;
+ if ((Error = Implementation.LZHReadInput(this)) != Error.MSPACK_ERR_OK)
+ return;
i_ptr = InputPointer;
i_end = InputLength;
}
- INJECT_BITS(InputBuffer[i_ptr++], 8, ref bitsLeft, ref bitBuffer);
- return error;
+ INJECT_BITS(InputBuffer[i_ptr++], 8, ref bitsLeft, ref bitBuffer, msb);
+ Error = Error.MSPACK_ERR_OK;
}
public override int HUFF_ERROR() => (int)Error.MSPACK_ERR_DATAFORMAT;
diff --git a/BurnOutSharp/External/libmspack/OAB/Implementation.cs b/BurnOutSharp/External/libmspack/OAB/Implementation.cs
index b185bb4c..ce70c758 100644
--- a/BurnOutSharp/External/libmspack/OAB/Implementation.cs
+++ b/BurnOutSharp/External/libmspack/OAB/Implementation.cs
@@ -85,16 +85,21 @@ namespace LibMSPackSharp.OAB
private static int SysWrite(object baseFile, byte[] buf, int pointer, int size)
{
- InternalFile file = baseFile as InternalFile;
- if (file == null)
- return 0;
+ 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);
- int bytes_written = file.OrigSys.Write(file.OrigFile, buf, pointer, size);
+ return bytes_written;
+ }
+ else if (baseFile is DefaultFileImpl impl)
+ {
+ return SystemImpl.DefaultSystem.Write(impl, buf, pointer, size);
+ }
- if (bytes_written > 0)
- file.CRC = Checksum.CRC32(buf, 0, bytes_written, file.CRC);
-
- return bytes_written;
+ // Unknown file to write to
+ return 0;
}
#endregion