4 Commits
0.1.1 ... 0.2.0

Author SHA1 Message Date
Matt Nadareski
07b50e8c46 Support ancient .NET 2023-11-14 14:53:50 -05:00
Matt Nadareski
8eb82384d6 Expand supported RIDs 2023-11-08 22:51:25 -05:00
Matt Nadareski
dd6cc0e2f3 Fix whitespace in project file 2023-11-08 10:59:30 -05:00
Matt Nadareski
58502e0362 Enable latest language version 2023-11-07 22:12:51 -05:00
7 changed files with 29 additions and 180 deletions

View File

@@ -33,11 +33,7 @@ namespace SabreTools.Compression
/// <summary>
/// Create a new BitStream from a source Stream
/// </summary>
#if NET48
public BitStream(Stream source)
#else
public BitStream(Stream? source)
#endif
{
if (source == null || !source.CanRead || !source.CanSeek)
throw new ArgumentException(nameof(source));
@@ -210,11 +206,7 @@ namespace SabreTools.Compression
/// <param name="bytes">Number of bytes to read</param>
/// <returns>The next <paramref name="bytes"/> bytes, null on error or end of stream</returns>
/// <remarks>Assumes the stream is byte-aligned</remarks>
#if NET48
public byte[] ReadBytes(int bytes)
#else
public byte[]? ReadBytes(int bytes)
#endif
{
try
{

View File

@@ -17,11 +17,7 @@ namespace SabreTools.Compression.LZ
/// </summary>
/// <param name="compressed">Byte array representing the compressed data</param>
/// <returns>Decompressed data as a byte array, null on error</returns>
#if NET48
public static byte[] Decompress(byte[] compressed)
#else
public static byte[]? Decompress(byte[]? compressed)
#endif
{
// If we have and invalid input
if (compressed == null || compressed.Length == 0)
@@ -37,11 +33,7 @@ namespace SabreTools.Compression.LZ
/// </summary>
/// <param name="compressed">Stream representing the compressed data</param>
/// <returns>Decompressed data as a byte array, null on error</returns>
#if NET48
public static byte[] Decompress(Stream compressed)
#else
public static byte[]? Decompress(Stream? compressed)
#endif
{
// If we have and invalid input
if (compressed == null || compressed.Length == 0)
@@ -87,11 +79,7 @@ namespace SabreTools.Compression.LZ
/// <summary>
/// Reconstructs the full filename of the compressed file
/// </summary>
#if NET48
public static string GetExpandedName(string input, out LZERROR error)
#else
public static string? GetExpandedName(string input, out LZERROR error)
#endif
{
// Try to open the file as a compressed stream
var fileStream = File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
@@ -137,11 +125,7 @@ namespace SabreTools.Compression.LZ
/// <param name="error">Output representing the last error</param>
/// <returns>An initialized State, null on error</returns>
/// <remarks>Uncompressed streams are represented by a State with no buffer</remarks>
#if NET48
public State Open(Stream stream, out LZERROR error)
#else
public State? Open(Stream stream, out LZERROR error)
#endif
{
var lzs = Init(stream, out error);
if (error == LZERROR.LZERROR_OK || error == LZERROR.LZERROR_NOT_LZ)
@@ -170,11 +154,7 @@ namespace SabreTools.Compression.LZ
/// <param name="error">Output representing the last error</param>
/// <returns>An initialized State, null on error</returns>
/// <remarks>Uncompressed streams are represented by a State with no buffer</remarks>
#if NET48
public State Init(Stream source, out LZERROR error)
#else
public State? Init(Stream? source, out LZERROR error)
#endif
{
// If we have an invalid source
if (source == null)
@@ -540,11 +520,7 @@ namespace SabreTools.Compression.LZ
/// <param name="data">Stream to parse</param>
/// <param name="error">Output representing the last error</param>
/// <returns>Filled file header on success, null on error</returns>
#if NET48
private FileHeaader ParseFileHeader(Stream data, out LZERROR error)
#else
private FileHeaader? ParseFileHeader(Stream data, out LZERROR error)
#endif
{
error = LZERROR.LZERROR_OK;
var fileHeader = new FileHeaader();

View File

@@ -19,11 +19,7 @@ namespace SabreTools.Compression.MSZIP
/// Create a new Decompressor from a byte array
/// </summary>
/// <param name="input">Byte array to decompress</param>
#if NET48
public DeflateDecompressor(byte[] input)
#else
public DeflateDecompressor(byte[]? input)
#endif
{
// If we have an invalid stream
if (input == null || input.Length == 0)
@@ -40,11 +36,7 @@ namespace SabreTools.Compression.MSZIP
/// Create a new Decompressor from a Stream
/// </summary>
/// <param name="input">Stream to decompress</param>
#if NET48
public DeflateDecompressor(Stream input)
#else
public DeflateDecompressor(Stream? input)
#endif
{
// If we have an invalid stream
if (input == null || !input.CanRead || !input.CanSeek)
@@ -58,11 +50,7 @@ namespace SabreTools.Compression.MSZIP
/// Decompress a stream into a <see cref="Block"/>
/// </summary>
/// <returns>Block containing the decompressed data on success, null on error</returns>
#if NET48
public Block Process()
#else
public Block? Process()
#endif
{
// Create a new block
var block = new Block();
@@ -85,11 +73,7 @@ namespace SabreTools.Compression.MSZIP
deflateBlocks.Add(deflateBlock);
// If we're at the final block, exit out of the loop
#if NET48
if (deflateBlock.Header.BFINAL)
#else
if (deflateBlock.Header!.BFINAL)
#endif
break;
}
@@ -187,11 +171,7 @@ namespace SabreTools.Compression.MSZIP
/// <summary>
/// Read an RFC1951 block
/// </summary>
#if NET48
private DeflateBlock ReadDeflateBlock()
#else
private DeflateBlock? ReadDeflateBlock()
#endif
{
var deflateBlock = new DeflateBlock();
@@ -241,11 +221,7 @@ namespace SabreTools.Compression.MSZIP
/// <summary>
/// Read an RFC1951 block with no compression
/// </summary>
#if NET48
private (NonCompressedBlockHeader, byte[]) ReadNoCompression()
#else
private (NonCompressedBlockHeader?, byte[]?) ReadNoCompression()
#endif
{
// Skip any remaining bits in current partially processed byte
_bitStream.Discard();
@@ -262,11 +238,7 @@ namespace SabreTools.Compression.MSZIP
/// <summary>
/// Read an RFC1951 block with fixed Huffman compression
/// </summary>
#if NET48
private (FixedCompressedDataHeader, byte[]) ReadFixedHuffman()
#else
private (FixedCompressedDataHeader, byte[]?) ReadFixedHuffman()
#endif
{
var bytes = new List<byte>();
@@ -284,11 +256,7 @@ namespace SabreTools.Compression.MSZIP
/// <summary>
/// Read an RFC1951 block with dynamic Huffman compression
/// </summary>
#if NET48
private (DynamicCompressedDataHeader, byte[]) ReadDynamicHuffman()
#else
private (DynamicCompressedDataHeader?, byte[]?) ReadDynamicHuffman()
#endif
{
// Get the dynamic huffman header
(var header, uint numLiteral, uint numDistance) = ReadDynamicCompressedDataHeader();
@@ -304,11 +272,7 @@ namespace SabreTools.Compression.MSZIP
/// <summary>
/// Read an RFC1951 block with Huffman compression
/// </summary>
#if NET48
private byte[] ReadHuffmanBlock(HuffmanDecoder literalTree, HuffmanDecoder distanceTree)
#else
private byte[]? ReadHuffmanBlock(HuffmanDecoder literalTree, HuffmanDecoder distanceTree)
#endif
{
// Now loop and decode
var bytes = new List<byte>();

View File

@@ -16,22 +16,14 @@ namespace SabreTools.Compression.MSZIP
/// </summary>
/// <param name="lengths">Array representing the number of bits for each value</param>
/// <param name="numCodes">Number of Huffman codes encoded</param>
#if NET48
public HuffmanDecoder(uint[] lengths, uint numCodes)
#else
public HuffmanDecoder(uint[]? lengths, uint numCodes)
#endif
{
// Ensure we have lengths
if (lengths == null)
throw new ArgumentNullException(nameof(lengths));
// Set the root to null for now
#if NET48
HuffmanNode root = null;
#else
HuffmanNode? root = null;
#endif
// Determine the value for max_bits
uint max_bits = lengths.Max();
@@ -83,11 +75,7 @@ namespace SabreTools.Compression.MSZIP
}
// Assign the root value
#if NET48
_root = root;
#else
_root = root!;
#endif
}
/// <summary>
@@ -125,11 +113,7 @@ namespace SabreTools.Compression.MSZIP
/// <param name="length">Length of the current encoding</param>
/// <param name="code">Encoding of the value to traverse</param>
/// <returns>New instance of the node with value appended</returns>
#if NET48
private static HuffmanNode Insert(HuffmanNode node, int value, uint length, int code)
#else
private static HuffmanNode Insert(HuffmanNode? node, int value, uint length, int code)
#endif
{
// If no node is provided, create a new one
if (node == null)

View File

@@ -8,20 +8,12 @@ namespace SabreTools.Compression.MSZIP
/// <summary>
/// Left child of the current node
/// </summary>
#if NET48
public HuffmanNode Left { get; set; }
#else
public HuffmanNode? Left { get; set; }
#endif
/// <summary>
/// Right child of the current node
/// </summary>
#if NET48
public HuffmanNode Right { get; set; }
#else
public HuffmanNode? Right { get; set; }
#endif
/// <summary>
/// Value of the current node

View File

@@ -87,11 +87,7 @@ namespace SabreTools.Compression.Quantum
/// </summary>
/// <param name="input">Byte array to decompress</param>
/// <param name="windowBits">Number of bits in the sliding window</param>
#if NET48
public Decompressor(byte[] input, uint windowBits)
#else
public Decompressor(byte[]? input, uint windowBits)
#endif
{
// If we have an invalid stream
if (input == null || input.Length == 0)
@@ -134,11 +130,7 @@ namespace SabreTools.Compression.Quantum
/// </summary>
/// <param name="input">Stream to decompress</param>
/// <param name="windowBits">Number of bits in the sliding window</param>
#if NET48
public Decompressor(Stream input, uint windowBits)
#else
public Decompressor(Stream? input, uint windowBits)
#endif
{
// If we have an invalid stream
if (input == null || !input.CanRead || !input.CanSeek)
@@ -293,36 +285,20 @@ namespace SabreTools.Compression.Quantum
/// </summary>
private int GetSymbol(Model model)
{
#if NET48
int freq = GetFrequency(model.Symbols[0].CumulativeFrequency);
#else
int freq = GetFrequency(model.Symbols![0]!.CumulativeFrequency);
#endif
int i;
for (i = 1; i < model.Entries; i++)
{
#if NET48
if (model.Symbols[i].CumulativeFrequency <= freq)
#else
if (model.Symbols[i]!.CumulativeFrequency <= freq)
#endif
break;
}
#if NET48
int sym = model.Symbols[i - 1].Symbol;
GetCode(model.Symbols[i - 1].CumulativeFrequency,
model.Symbols[i].CumulativeFrequency,
model.Symbols[0].CumulativeFrequency);
#else
int sym = model.Symbols![i - 1]!.Symbol;
GetCode(model.Symbols![i - 1]!.CumulativeFrequency,
model.Symbols![i]!.CumulativeFrequency,
model.Symbols![0]!.CumulativeFrequency);
#endif
UpdateModel(model, i);
@@ -369,20 +345,12 @@ namespace SabreTools.Compression.Quantum
// Update cumulative frequencies
for (int i = 0; i < lastUpdated; i++)
{
#if NET48
var sym = model.Symbols[i];
#else
var sym = model.Symbols![i]!;
#endif
sym.CumulativeFrequency += 8;
}
// Decrement reordering time, if needed
#if NET48
if (model.Symbols[0].CumulativeFrequency > 3800)
#else
if (model.Symbols![0]!.CumulativeFrequency > 3800)
#endif
model.TimeToReorder--;
// If we haven't hit the reordering time
@@ -392,21 +360,12 @@ namespace SabreTools.Compression.Quantum
for (int i = model.Entries - 1; i >= 0; i--)
{
// Divide with truncation by 2
#if NET48
var sym = model.Symbols[i];
#else
var sym = model.Symbols![i]!;
#endif
sym.CumulativeFrequency >>= 1;
// If we are lower the next frequency
#if NET48
if (i != 0 && sym.CumulativeFrequency <= model.Symbols[i + 1].CumulativeFrequency)
sym.CumulativeFrequency = (ushort)(model.Symbols[i + 1].CumulativeFrequency + 1);
#else
if (i != 0 && sym.CumulativeFrequency <= model.Symbols![i + 1]!.CumulativeFrequency)
sym.CumulativeFrequency = (ushort)(model.Symbols![i + 1]!.CumulativeFrequency + 1);
#endif
}
}
@@ -416,19 +375,11 @@ namespace SabreTools.Compression.Quantum
// Calculate frequencies from cumulative frequencies
for (int i = 0; i < model.Entries; i++)
{
#if NET48
if (i != model.Entries - 1)
model.Symbols[i].CumulativeFrequency -= model.Symbols[i + 1].CumulativeFrequency;
model.Symbols[i].CumulativeFrequency++;
model.Symbols[i].CumulativeFrequency >>= 1;
#else
if (i != model.Entries - 1)
model.Symbols![i]!.CumulativeFrequency -= model.Symbols![i + 1]!.CumulativeFrequency;
model.Symbols![i]!.CumulativeFrequency++;
model.Symbols![i]!.CumulativeFrequency >>= 1;
#endif
}
// Sort frequencies in decreasing order
@@ -436,11 +387,7 @@ namespace SabreTools.Compression.Quantum
{
for (int j = i + 1; j < model.Entries; j++)
{
#if NET48
if (model.Symbols[i].CumulativeFrequency < model.Symbols[j].CumulativeFrequency)
#else
if (model.Symbols![i]!.CumulativeFrequency < model.Symbols![j]!.CumulativeFrequency)
#endif
{
var temp = model.Symbols[i];
model.Symbols[i] = model.Symbols[j];
@@ -453,11 +400,7 @@ namespace SabreTools.Compression.Quantum
for (int i = model.Entries - 1; i >= 0; i--)
{
if (i != model.Entries - 1)
#if NET48
model.Symbols[i].CumulativeFrequency += model.Symbols[i + 1].CumulativeFrequency;
#else
model.Symbols![i]!.CumulativeFrequency += model.Symbols![i + 1]!.CumulativeFrequency;
#endif
}
// Reset the time to reorder

View File

@@ -1,36 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net48;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Version>0.1.1</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>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.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
<Description>Clean compression implementations</Description>
<Copyright>Copyright (c) Matt Nadareski 2022-2023</Copyright>
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Printing</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>compression decompression lz mszip</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
<Description>Clean compression implementations</Description>
<Copyright>Copyright (c) Matt Nadareski 2022-2023</Copyright>
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Printing</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>compression decompression lz mszip</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='net48'">
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath=""/>
</ItemGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath=""/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.IO" Version="1.1.1" />
<PackageReference Include="SabreTools.Models" Version="1.1.5" />
</ItemGroup>
</Project>
<ItemGroup>
<PackageReference Include="SabreTools.IO" Version="1.2.0" />
<PackageReference Include="SabreTools.Models" Version="1.2.0" />
</ItemGroup>
</Project>