diff --git a/BaseHandlers/BaseHandlers.csproj b/BaseHandlers/BaseHandlers.csproj index 4e7a0e8..1dcee7e 100644 --- a/BaseHandlers/BaseHandlers.csproj +++ b/BaseHandlers/BaseHandlers.csproj @@ -17,6 +17,7 @@ + diff --git a/BundleFormat/BundleFormat.csproj b/BundleFormat/BundleFormat.csproj index fa223cd..c742b6f 100644 --- a/BundleFormat/BundleFormat.csproj +++ b/BundleFormat/BundleFormat.csproj @@ -7,9 +7,9 @@ true - + - + \ No newline at end of file diff --git a/BundleFormat/Extensions.cs b/BundleFormat/Extensions.cs index 0ce0d8a..ebb3080 100644 --- a/BundleFormat/Extensions.cs +++ b/BundleFormat/Extensions.cs @@ -1,16 +1,19 @@ using System; +using System.Buffers; using System.Buffers.Binary; using System.Collections.Generic; -using System.IO; using System.Numerics; using System.Text; using System.Windows.Forms; -using Ionic.Zlib; +using LibDeflate; namespace BundleFormat { public static class Extensions { + private static Decompressor decompressor = new ZlibDecompressor(); + private static Compressor compressor = new ZlibCompressor(9); + public static string AsString(this byte[] self) { if (self == null) @@ -42,64 +45,18 @@ public static string MakePreview(this byte[] self, int start, int end) public static byte[] Compress(this byte[] self) { - byte[] compressedData = new byte[self.Length]; // Size not known yet, use uncompressed size as upper bound - ZlibStream zlibStream = new ZlibStream(new MemoryStream(self), CompressionMode.Compress, CompressionLevel.BestCompression); - zlibStream.Read(compressedData, 0, self.Length); - return new ArraySegment(compressedData, 0, (int)zlibStream.TotalOut).ToArray(); // Size known, return correctly sized segment + return compressor.Compress(self).Memory.ToArray(); } public static byte[] Decompress(this byte[] self, int uncompressedSize) { - byte[] uncompressedData = new byte[uncompressedSize]; - ZlibStream zlibStream = new ZlibStream(new MemoryStream(uncompressedData), CompressionMode.Decompress); - try - { - zlibStream.Write(self, 0, self.Length); - } - catch (Exception e) - { - if (self[self.Length - 1] == 0 - && e.Message == "Bad state (incorrect data check)") // Likely a bugged resource - { - uncompressedData = GetDataFromBadAlignedResource(self, uncompressedSize); - if (uncompressedData != null) - return uncompressedData; - } - MessageBox.Show(e.ToString(), e.Source, MessageBoxButtons.OK); - return null; - } - return uncompressedData; - } - - // Validate resources from BM versions <0.3.0 where alignment corrupted the checksum - public static byte[] GetDataFromBadAlignedResource(byte[] original, int uncompressedSize) - { - // For some reason, the data validates when length is 1 less than it should be. - // Use this to get the correct uncompressed data. - byte[] uncompressedData = new byte[uncompressedSize]; - ZlibStream zlibStream = new ZlibStream(new MemoryStream(uncompressedData), CompressionMode.Decompress); - byte[] trimmed = new ArraySegment(original, 0, original.Length - 1).ToArray(); - try - { - zlibStream.Write(trimmed, 0, trimmed.Length); - } - catch (Exception) + var status = decompressor.Decompress(self, uncompressedSize, out var owner, out var bytesRead); + if (status != OperationStatus.Done) { + MessageBox.Show("Error decompressing data, status: " + status.ToString() + ", read: " + bytesRead.ToString(), "Error", MessageBoxButtons.OK); return null; } - - byte[] compressed = Compress(uncompressedData); - - // Test first three checksum bytes - if (original[original.Length - 4] == compressed[compressed.Length - 4] - && original[original.Length - 3] == compressed[compressed.Length - 3] - && original[original.Length - 2] == compressed[compressed.Length - 2]) - { - // Testing of data not necessary, likelihood of 24 bits matching without data matching is negligible - return uncompressedData; - } - - return null; + return owner.Memory.ToArray(); } public static bool Matches(this byte[] self, byte[] other) diff --git a/BundleManager/BundleManager.csproj b/BundleManager/BundleManager.csproj index 8e930c6..9a8bb7b 100644 --- a/BundleManager/BundleManager.csproj +++ b/BundleManager/BundleManager.csproj @@ -68,6 +68,7 @@ + diff --git a/BurnoutImage/BurnoutImage.csproj b/BurnoutImage/BurnoutImage.csproj index 9ae23fb..a80164e 100644 --- a/BurnoutImage/BurnoutImage.csproj +++ b/BurnoutImage/BurnoutImage.csproj @@ -18,5 +18,6 @@ + \ No newline at end of file diff --git a/PVSFormat/PVSEditor.Designer.cs b/PVSFormat/PVSEditor.Designer.cs index cf59fb0..0658173 100644 --- a/PVSFormat/PVSEditor.Designer.cs +++ b/PVSFormat/PVSEditor.Designer.cs @@ -287,8 +287,8 @@ private void InitializeComponent() point2YNumericUpDown.DecimalPlaces = 3; point2YNumericUpDown.Enabled = false; point2YNumericUpDown.Location = new System.Drawing.Point(115, 265); - point2YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point2YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point2YNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point2YNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point2YNumericUpDown.Name = "point2YNumericUpDown"; point2YNumericUpDown.Size = new System.Drawing.Size(70, 23); point2YNumericUpDown.TabIndex = 11; @@ -299,8 +299,8 @@ private void InitializeComponent() point2XNumericUpDown.DecimalPlaces = 3; point2XNumericUpDown.Enabled = false; point2XNumericUpDown.Location = new System.Drawing.Point(24, 265); - point2XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point2XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point2XNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point2XNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point2XNumericUpDown.Name = "point2XNumericUpDown"; point2XNumericUpDown.Size = new System.Drawing.Size(70, 23); point2XNumericUpDown.TabIndex = 10; @@ -320,8 +320,8 @@ private void InitializeComponent() point3YNumericUpDown.DecimalPlaces = 3; point3YNumericUpDown.Enabled = false; point3YNumericUpDown.Location = new System.Drawing.Point(115, 294); - point3YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point3YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point3YNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point3YNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point3YNumericUpDown.Name = "point3YNumericUpDown"; point3YNumericUpDown.Size = new System.Drawing.Size(70, 23); point3YNumericUpDown.TabIndex = 8; @@ -332,8 +332,8 @@ private void InitializeComponent() point3XNumericUpDown.DecimalPlaces = 3; point3XNumericUpDown.Enabled = false; point3XNumericUpDown.Location = new System.Drawing.Point(24, 294); - point3XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point3XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point3XNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point3XNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point3XNumericUpDown.Name = "point3XNumericUpDown"; point3XNumericUpDown.Size = new System.Drawing.Size(70, 23); point3XNumericUpDown.TabIndex = 7; @@ -353,8 +353,8 @@ private void InitializeComponent() point4YNumericUpDown.DecimalPlaces = 3; point4YNumericUpDown.Enabled = false; point4YNumericUpDown.Location = new System.Drawing.Point(115, 323); - point4YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point4YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point4YNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point4YNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point4YNumericUpDown.Name = "point4YNumericUpDown"; point4YNumericUpDown.Size = new System.Drawing.Size(70, 23); point4YNumericUpDown.TabIndex = 5; @@ -365,8 +365,8 @@ private void InitializeComponent() point4XNumericUpDown.DecimalPlaces = 3; point4XNumericUpDown.Enabled = false; point4XNumericUpDown.Location = new System.Drawing.Point(24, 323); - point4XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point4XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point4XNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point4XNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point4XNumericUpDown.Name = "point4XNumericUpDown"; point4XNumericUpDown.Size = new System.Drawing.Size(70, 23); point4XNumericUpDown.TabIndex = 4; @@ -386,8 +386,8 @@ private void InitializeComponent() point1YNumericUpDown.DecimalPlaces = 3; point1YNumericUpDown.Enabled = false; point1YNumericUpDown.Location = new System.Drawing.Point(115, 236); - point1YNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point1YNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point1YNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point1YNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point1YNumericUpDown.Name = "point1YNumericUpDown"; point1YNumericUpDown.Size = new System.Drawing.Size(70, 23); point1YNumericUpDown.TabIndex = 2; @@ -398,8 +398,8 @@ private void InitializeComponent() point1XNumericUpDown.DecimalPlaces = 3; point1XNumericUpDown.Enabled = false; point1XNumericUpDown.Location = new System.Drawing.Point(24, 236); - point1XNumericUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 }); - point1XNumericUpDown.Minimum = new decimal(new int[] { 10000, 0, 0, int.MinValue }); + point1XNumericUpDown.Maximum = new decimal(new int[] { 50000, 0, 0, 0 }); + point1XNumericUpDown.Minimum = new decimal(new int[] { 50000, 0, 0, int.MinValue }); point1XNumericUpDown.Name = "point1XNumericUpDown"; point1XNumericUpDown.Size = new System.Drawing.Size(70, 23); point1XNumericUpDown.TabIndex = 1; diff --git a/PVSFormat/PVSFormat.csproj b/PVSFormat/PVSFormat.csproj index 6123774..b5e056a 100644 --- a/PVSFormat/PVSFormat.csproj +++ b/PVSFormat/PVSFormat.csproj @@ -19,6 +19,7 @@ + diff --git a/Readme.md b/Readme.md index bb5f553..1fb7120 100644 --- a/Readme.md +++ b/Readme.md @@ -4,7 +4,7 @@ A Program to work with Burnout Paradise Bundle files. # Libraries Used * [BCnEncoder](https://github.com/Nominom/BCnEncoder.NET) * [DebugHelper](https://gitlab.com/mattparizeau/DebugHelper) -* [DotNetZip](https://github.com/haf/DotNetZip.Semverd) +* [LibDeflate.NET](https://github.com/jzebedee/LibDeflate.NET) * [OpenTK](https://github.com/opentk/opentk) # Credits