mirror of
https://github.com/SabreTools/SabreTools.Compression.git
synced 2026-02-04 05:36:03 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
daf27b9175 | ||
|
|
daaf157bc5 | ||
|
|
163b2483f9 | ||
|
|
8ed85d52ed | ||
|
|
042fc18aa7 | ||
|
|
16d8d9839c | ||
|
|
dfcbce8874 | ||
|
|
fa5084d067 | ||
|
|
d9e1748ec1 | ||
|
|
84a3e515c0 |
6
.github/workflows/build_nupkg.yml
vendored
6
.github/workflows/build_nupkg.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
@@ -28,13 +28,13 @@ jobs:
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'Nuget Package'
|
||||
path: 'bin/Release/*.nupkg'
|
||||
path: 'SabreTools.Compression/bin/Release/*.nupkg'
|
||||
|
||||
- name: Upload to rolling
|
||||
uses: ncipollo/release-action@v1.14.0
|
||||
with:
|
||||
allowUpdates: True
|
||||
artifacts: 'bin/Release/*.nupkg'
|
||||
artifacts: 'SabreTools.Compression/bin/Release/*.nupkg'
|
||||
body: 'Last built commit: ${{ github.sha }}'
|
||||
name: 'Rolling Release'
|
||||
prerelease: True
|
||||
|
||||
2
.github/workflows/check_pr.yml
vendored
2
.github/workflows/check_pr.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Build
|
||||
run: dotnet build
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static SabreTools.Compression.Blast.Constants;
|
||||
|
||||
namespace SabreTools.Compression.Blast
|
||||
@@ -148,7 +147,9 @@ namespace SabreTools.Compression.Blast
|
||||
{
|
||||
try
|
||||
{
|
||||
OutHow.AddRange(Output.Take((int)Next));
|
||||
byte[] next = new byte[Next];
|
||||
Array.Copy(Output, next, next.Length);
|
||||
OutHow.AddRange(next);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
|
||||
9
SabreTools.Compression/ExtensionAttribute.cs
Normal file
9
SabreTools.Compression/ExtensionAttribute.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
#if NET20
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
internal sealed class ExtensionAttribute : Attribute {}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.Compression.LZ;
|
||||
@@ -181,7 +181,8 @@ namespace SabreTools.Compression.LZ
|
||||
}
|
||||
|
||||
// Initialize the table with all spaces
|
||||
byte[] table = Enumerable.Repeat((byte)' ', LZ_TABLE_SIZE).ToArray();
|
||||
byte[] table = new byte[LZ_TABLE_SIZE];
|
||||
table = Array.ConvertAll(table, b => (byte)' ');
|
||||
|
||||
// Build the state
|
||||
var state = new State
|
||||
@@ -247,7 +248,8 @@ namespace SabreTools.Compression.LZ
|
||||
state.RealCurrent = 0;
|
||||
state.ByteType = 0;
|
||||
state.StringLength = 0;
|
||||
state.Table = Enumerable.Repeat((byte)' ', LZ_TABLE_SIZE).ToArray();
|
||||
state.Table = new byte[LZ_TABLE_SIZE];
|
||||
state.Table = Array.ConvertAll(state.Table, b => (byte)' ');
|
||||
state.CurrentTableEntry = 0xFF0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SabreTools.IO.Streams;
|
||||
using SabreTools.Models.Compression.MSZIP;
|
||||
using static SabreTools.Models.Compression.MSZIP.Constants;
|
||||
@@ -121,22 +120,24 @@ namespace SabreTools.Compression.MSZIP
|
||||
/// <summary>
|
||||
/// Read a FixedHuffmanCompressedBlockHeader from the input stream
|
||||
/// </summary>
|
||||
private (FixedCompressedDataHeader, uint, uint) RaadFixedCompressedDataHeader()
|
||||
private FixedCompressedDataHeader ReadFixedCompressedDataHeader(out uint numLiteral, out uint numDistance)
|
||||
{
|
||||
// Nothing needs to be read, all values are fixed
|
||||
return (new FixedCompressedDataHeader(), 288, 30);
|
||||
numLiteral = 288;
|
||||
numDistance = 30;
|
||||
return new FixedCompressedDataHeader();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a DynamicHuffmanCompressedBlockHeader from the input stream
|
||||
/// </summary>
|
||||
private (DynamicCompressedDataHeader, uint, uint) ReadDynamicCompressedDataHeader()
|
||||
private DynamicCompressedDataHeader ReadDynamicCompressedDataHeader(out uint numLiteral, out uint numDistance)
|
||||
{
|
||||
var header = new DynamicCompressedDataHeader();
|
||||
|
||||
// Setup the counts first
|
||||
uint numLiteral = 257 + _bitStream.ReadBitsLSB(5) ?? 0;
|
||||
uint numDistance = 1 + _bitStream.ReadBitsLSB(5) ?? 0;
|
||||
numLiteral = 257 + _bitStream.ReadBitsLSB(5) ?? 0;
|
||||
numDistance = 1 + _bitStream.ReadBitsLSB(5) ?? 0;
|
||||
uint numLength = 4 + _bitStream.ReadBitsLSB(4) ?? 0;
|
||||
|
||||
// Convert the alphabet based on lengths
|
||||
@@ -162,7 +163,7 @@ namespace SabreTools.Compression.MSZIP
|
||||
uint leftover = ReadHuffmanLengths(lengthTree, header.LiteralLengths, numLiteral, 0, ref repeatCode);
|
||||
_ = ReadHuffmanLengths(lengthTree, header.DistanceCodes, numDistance, leftover, ref repeatCode);
|
||||
|
||||
return (header, numLiteral, numDistance);
|
||||
return header;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -182,7 +183,7 @@ namespace SabreTools.Compression.MSZIP
|
||||
{
|
||||
// If stored with no compression
|
||||
case CompressionType.NoCompression:
|
||||
(var header00, var bytes00) = ReadNoCompression();
|
||||
var header00 = ReadNoCompression(out byte[]? bytes00);
|
||||
if (header00 == null || bytes00 == null)
|
||||
return null;
|
||||
|
||||
@@ -192,7 +193,7 @@ namespace SabreTools.Compression.MSZIP
|
||||
|
||||
// If compressed with fixed Huffman codes
|
||||
case CompressionType.FixedHuffman:
|
||||
(var header01, var bytes01) = ReadFixedHuffman();
|
||||
var header01 = ReadFixedHuffman(out byte[]? bytes01);
|
||||
if (header01 == null || bytes01 == null)
|
||||
return null;
|
||||
|
||||
@@ -202,7 +203,7 @@ namespace SabreTools.Compression.MSZIP
|
||||
|
||||
// If compressed with dynamic Huffman codes
|
||||
case CompressionType.DynamicHuffman:
|
||||
(var header10, var bytes10) = ReadDynamicHuffman();
|
||||
var header10 = ReadDynamicHuffman(out byte[]? bytes10);
|
||||
if (header10 == null || bytes10 == null)
|
||||
return null;
|
||||
|
||||
@@ -222,7 +223,7 @@ namespace SabreTools.Compression.MSZIP
|
||||
/// <summary>
|
||||
/// Read an RFC1951 block with no compression
|
||||
/// </summary>
|
||||
private (NonCompressedBlockHeader?, byte[]?) ReadNoCompression()
|
||||
private NonCompressedBlockHeader? ReadNoCompression(out byte[]? data)
|
||||
{
|
||||
// Skip any remaining bits in current partially processed byte
|
||||
_bitStream.Discard();
|
||||
@@ -230,44 +231,50 @@ namespace SabreTools.Compression.MSZIP
|
||||
// Read LEN and NLEN
|
||||
var header = ReadNonCompressedBlockHeader();
|
||||
if (header.LEN == 0 && header.NLEN == 0)
|
||||
return (null, null);
|
||||
{
|
||||
data = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Copy LEN bytes of data to output
|
||||
return (header, _bitStream.ReadBytes(header.LEN));
|
||||
data = _bitStream.ReadBytes(header.LEN);
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read an RFC1951 block with fixed Huffman compression
|
||||
/// </summary>
|
||||
private (FixedCompressedDataHeader, byte[]?) ReadFixedHuffman()
|
||||
private FixedCompressedDataHeader? ReadFixedHuffman(out byte[]? data)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
|
||||
// Get the fixed huffman header
|
||||
(var header, uint numLiteral, uint numDistance) = RaadFixedCompressedDataHeader();
|
||||
var header = ReadFixedCompressedDataHeader(out uint numLiteral, out uint numDistance);
|
||||
|
||||
// Make the literal and distance trees
|
||||
var literalTree = new HuffmanDecoder(header.LiteralLengths, numLiteral);
|
||||
var distanceTree = new HuffmanDecoder(header.DistanceCodes, numDistance);
|
||||
|
||||
// Now loop and decode
|
||||
return (header, ReadHuffmanBlock(literalTree, distanceTree));
|
||||
data = ReadHuffmanBlock(literalTree, distanceTree);
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read an RFC1951 block with dynamic Huffman compression
|
||||
/// </summary>
|
||||
private (DynamicCompressedDataHeader?, byte[]?) ReadDynamicHuffman()
|
||||
private DynamicCompressedDataHeader? ReadDynamicHuffman(out byte[]? data)
|
||||
{
|
||||
// Get the dynamic huffman header
|
||||
(var header, uint numLiteral, uint numDistance) = ReadDynamicCompressedDataHeader();
|
||||
var header = ReadDynamicCompressedDataHeader(out uint numLiteral, out uint numDistance);
|
||||
|
||||
// Make the literal and distance trees
|
||||
var literalTree = new HuffmanDecoder(header.LiteralLengths, numLiteral);
|
||||
var distanceTree = new HuffmanDecoder(header.DistanceCodes, numDistance);
|
||||
|
||||
// Now loop and decode
|
||||
return (header, ReadHuffmanBlock(literalTree, distanceTree));
|
||||
data = ReadHuffmanBlock(literalTree, distanceTree);
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -308,13 +315,15 @@ namespace SabreTools.Compression.MSZIP
|
||||
if (distance == null)
|
||||
return null;
|
||||
|
||||
byte[] arr = bytes.Skip(bytes.Count - (int)distance).Take((int)length).ToArray();
|
||||
byte[] bytesArr = [.. bytes];
|
||||
byte[] arr = new byte[(int)length];
|
||||
Array.Copy(bytesArr, bytes.Count - (int)distance, arr, 0, (int)length);
|
||||
bytes.AddRange(arr);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the decoded array
|
||||
return bytes.ToArray();
|
||||
return [.. bytes];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
#if NET35_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using SabreTools.IO.Streams;
|
||||
|
||||
namespace SabreTools.Compression.MSZIP
|
||||
@@ -27,7 +29,15 @@ namespace SabreTools.Compression.MSZIP
|
||||
HuffmanNode? root = null;
|
||||
|
||||
// Determine the value for max_bits
|
||||
#if NET20
|
||||
uint max_bits = 0;
|
||||
foreach (uint u in lengths)
|
||||
{
|
||||
max_bits = u > max_bits ? u : max_bits;
|
||||
}
|
||||
#else
|
||||
uint max_bits = lengths.Max();
|
||||
#endif
|
||||
|
||||
// Count the number of codes for each code length
|
||||
int[] bl_count = new int[max_bits + 1];
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>0.5.1</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Clean compression implementations</Description>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2022-2024</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Compression</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>compression decompression lz mszip zlib blast</PackageTags>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="../README.md" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.IO" Version="1.4.5" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.5" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>0.6.1</Version>
|
||||
|
||||
</Project>
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Clean compression implementations</Description>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2022-2024</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Compression</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>compression decompression lz mszip zlib blast</PackageTags>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="../README.md" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.IO" Version="1.5.1" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,19 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
<OutputType>Exe</OutputType>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SabreTools.Compression\SabreTools.Compression.csproj" />
|
||||
</ItemGroup>
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
|
||||
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SabreTools.Compression\SabreTools.Compression.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This batch file assumes the following:
|
||||
# - .NET 8.0 (or newer) SDK is installed and in PATH
|
||||
# - .NET 9.0 (or newer) SDK is installed and in PATH
|
||||
#
|
||||
# If any of these are not satisfied, the operation may fail
|
||||
# in an unpredictable way and result in an incomplete output.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This batch file assumes the following:
|
||||
# - .NET 8.0 (or newer) SDK is installed and in PATH
|
||||
# - .NET 9.0 (or newer) SDK is installed and in PATH
|
||||
#
|
||||
# If any of these are not satisfied, the operation may fail
|
||||
# in an unpredictable way and result in an incomplete output.
|
||||
|
||||
Reference in New Issue
Block a user