├── .editorconfig
├── .gitattributes
├── .gitignore
├── AuroraLib.Compression.sln
├── Benchmarks.md
├── Benchmarks
├── Benchmarks.csproj
├── Benchmarks
│ ├── TestAlgorithm.cs
│ └── TestAllAlgorithms.cs
├── Program.cs
└── Test.bmp
├── CompressionTest
├── CompressionAlgorithmTest.cs
├── CompressionUnitTest.csproj
├── Test.bmp
└── Test.lz
├── LICENSE
├── README.md
├── icon-ex.png
├── icon.png
└── src
├── AuroraLib.Compression-Extended
├── Algorithms
│ ├── AKLZ.cs
│ ├── AsuraZlb.cs
│ ├── CLZ0.cs
│ ├── CNS.cs
│ ├── CNX2.cs
│ ├── COMP.cs
│ ├── CXLZ.cs
│ ├── ECD.cs
│ ├── FCMP.cs
│ ├── GCLZ.cs
│ ├── HWGZ.cs
│ ├── IECP.cs
│ ├── LZ00.cs
│ ├── LZ01.cs
│ ├── LZ02.cs
│ ├── LZ4.Frame.cs
│ ├── LZ4.FrameDescriptor.cs
│ ├── LZ4.cs
│ ├── LZ40.cs
│ ├── LZ4Legacy.cs
│ ├── LZ60.cs
│ ├── LZHudson.cs
│ ├── LZSega.cs
│ ├── LZShrek.cs
│ ├── Level5.cs
│ ├── MDF0.cs
│ ├── RLHudson.cs
│ ├── SSZL.cs
│ └── ZLB.cs
├── AuroraLib.Compression-Extended.csproj
└── Helper.cs
└── AuroraLib.Compression
├── Algorithms
├── ALLZ.cs
├── CompressionExtension.cs
├── GZip.cs
├── HUF20.cs
├── LZ10.cs
├── LZ11.cs
├── LZ77.cs
├── LZO.cs
├── LZOn.cs
├── LZSS.cs
├── MIO0.cs
├── PRS.cs
├── RLE30.cs
├── RefPack.cs
├── YAY0.cs
├── YAZ0.cs
├── YAZ1.cs
└── ZLib.cs
├── AuroraLib.Compression.csproj
├── Exceptions
└── DecompressedSizeException.cs
├── Helper.cs
├── Huffman
├── HuffmanNode.cs
└── HuffmanTree.cs
├── IO
├── FlagReader.cs
├── FlagWriter.cs
└── LzWindows.cs
├── Interfaces
├── ICompressionAlgorithm.cs
├── ICompressionDecoder.cs
├── ICompressionEncoder.cs
├── IEndianDependentFormat.cs
├── ILzSettings.cs
└── IProvidesDecompressedSize.cs
├── LzProperties.cs
└── MatchFinder
├── LzMatch.cs
├── LzMatchFinder.cs
└── RleMatchFinder.cs
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | indent_style = space
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | [*.{sln,csproj}]
11 | end_of_line = crlf
12 | charset = utf-8-bom
13 |
14 | [*.sln]
15 | indent_style = tab
16 |
17 | [*.csproj]
18 | indent_size = 2
19 |
20 | [*.cs]
21 | indent_size = 4
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto eol=lf
3 |
4 | # Source files
5 | *.cs text diff=csharp
6 | *.cshtml text diff=html
7 | *.csx text diff=csharp
8 |
9 | # Project and solution files
10 | *.sln text eol=crlf
11 | *.csproj text eol=crlf
12 | *.vbproj text eol=crlf
13 | *.vcxproj text eol=crlf
14 | *.vcproj text eol=crlf
15 | *.dbproj text eol=crlf
16 | *.fsproj text eol=crlf
17 | *.lsproj text eol=crlf
18 | *.wixproj text eol=crlf
19 | *.modelproj text eol=crlf
20 | *.sqlproj text eol=crlf
21 | *.wwaproj text eol=crlf
22 | *.xproj text eol=crlf
23 | *.props text eol=crlf
24 | *.filters text eol=crlf
25 | *.vcxitems text eol=crlf
26 |
--------------------------------------------------------------------------------
/AuroraLib.Compression.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.7.34024.191
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuroraLib.Compression", "src\AuroraLib.Compression\AuroraLib.Compression.csproj", "{90CFBCD7-EE97-46B1-A4E1-21521BACFC77}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompressionUnitTest", "CompressionTest\CompressionUnitTest.csproj", "{D9D66680-45F4-4DBD-9965-350E98160329}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{AEF632EF-EF3F-4314-B9DB-A70354AF214F}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuroraLib.Compression-Extended", "src\AuroraLib.Compression-Extended\AuroraLib.Compression-Extended.csproj", "{D0CE9878-C8E9-4E5F-9EEC-E20A504083C5}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Optimized|Any CPU = Optimized|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {90CFBCD7-EE97-46B1-A4E1-21521BACFC77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {90CFBCD7-EE97-46B1-A4E1-21521BACFC77}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {90CFBCD7-EE97-46B1-A4E1-21521BACFC77}.Optimized|Any CPU.ActiveCfg = Release|Any CPU
24 | {90CFBCD7-EE97-46B1-A4E1-21521BACFC77}.Optimized|Any CPU.Build.0 = Release|Any CPU
25 | {90CFBCD7-EE97-46B1-A4E1-21521BACFC77}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {90CFBCD7-EE97-46B1-A4E1-21521BACFC77}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {D9D66680-45F4-4DBD-9965-350E98160329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {D9D66680-45F4-4DBD-9965-350E98160329}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {D9D66680-45F4-4DBD-9965-350E98160329}.Optimized|Any CPU.ActiveCfg = Release|Any CPU
30 | {D9D66680-45F4-4DBD-9965-350E98160329}.Optimized|Any CPU.Build.0 = Release|Any CPU
31 | {D9D66680-45F4-4DBD-9965-350E98160329}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {D9D66680-45F4-4DBD-9965-350E98160329}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {AEF632EF-EF3F-4314-B9DB-A70354AF214F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {AEF632EF-EF3F-4314-B9DB-A70354AF214F}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {AEF632EF-EF3F-4314-B9DB-A70354AF214F}.Optimized|Any CPU.ActiveCfg = Release|Any CPU
36 | {AEF632EF-EF3F-4314-B9DB-A70354AF214F}.Optimized|Any CPU.Build.0 = Release|Any CPU
37 | {AEF632EF-EF3F-4314-B9DB-A70354AF214F}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {AEF632EF-EF3F-4314-B9DB-A70354AF214F}.Release|Any CPU.Build.0 = Release|Any CPU
39 | {D0CE9878-C8E9-4E5F-9EEC-E20A504083C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {D0CE9878-C8E9-4E5F-9EEC-E20A504083C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {D0CE9878-C8E9-4E5F-9EEC-E20A504083C5}.Optimized|Any CPU.ActiveCfg = Optimized|Any CPU
42 | {D0CE9878-C8E9-4E5F-9EEC-E20A504083C5}.Optimized|Any CPU.Build.0 = Optimized|Any CPU
43 | {D0CE9878-C8E9-4E5F-9EEC-E20A504083C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {D0CE9878-C8E9-4E5F-9EEC-E20A504083C5}.Release|Any CPU.Build.0 = Release|Any CPU
45 | EndGlobalSection
46 | GlobalSection(SolutionProperties) = preSolution
47 | HideSolutionNode = FALSE
48 | EndGlobalSection
49 | GlobalSection(ExtensibilityGlobals) = postSolution
50 | SolutionGuid = {3E284A3C-F433-424B-A6F4-97DE84B9DCBD}
51 | EndGlobalSection
52 | EndGlobal
53 |
--------------------------------------------------------------------------------
/Benchmarks.md:
--------------------------------------------------------------------------------
1 | BenchmarkDotNet v0.14.0, Windows 10, AMD Ryzen 7 3800X, 1 CPU, 16 logical and 8 physical cores. NET SDK 8.0.400
2 |
3 | | Method | Algorithm | MB | Mean | Error | StdDev | Gen0 | Allocated |
4 | |----------- |---------- |--- |-------------:|------------:|------------:|--------:|----------:|
5 | | Compress | ALLZ | 1 | 72,736.5 us | 1,434.81 us | 2,147.56 us | - | 7087 B |
6 | | Decompress | ALLZ | 1 | 3,455.3 us | 48.01 us | 42.56 us | - | 141 B |
7 | | Compress | CLZ0 | 1 | 21,654.8 us | 424.41 us | 471.74 us | - | 6856 B |
8 | | Decompress | CLZ0 | 1 | 3,901.3 us | 46.34 us | 43.34 us | - | 213 B |
9 | | Compress | CNS | 1 | 5,601.4 us | 77.30 us | 68.52 us | - | 6805 B |
10 | | Decompress | CNS | 1 | 3,598.0 us | 42.41 us | 39.67 us | - | 197 B |
11 | | Compress | CNX2 | 1 | 19,876.6 us | 348.84 us | 309.24 us | - | 6976 B |
12 | | Decompress | CNX2 | 1 | 3,653.0 us | 43.65 us | 40.83 us | - | 245 B |
13 | | Compress | HUF20 | 1 | 17,689.6 us | 201.15 us | 188.16 us | 31.2500 | 398903 B |
14 | | Decompress | HUF20 | 1 | 9,574.7 us | 185.77 us | 241.56 us | - | 106 B |
15 | | Compress | HWGZ | 1 | 7,394.5 us | 92.70 us | 86.71 us | - | 4182 B |
16 | | Decompress | HWGZ | 1 | 1,174.0 us | 14.27 us | 12.65 us | - | 6105 B |
17 | | Compress | LZ00 | 1 | 23,128.5 us | 434.20 us | 445.90 us | - | 6968 B |
18 | | Decompress | LZ00 | 1 | 4,205.2 us | 50.96 us | 47.66 us | - | 299 B |
19 | | Compress | LZ02 | 1 | 44,243.8 us | 881.28 us | 1,114.54 us | - | 6889 B |
20 | | Decompress | LZ02 | 1 | 2,986.9 us | 34.56 us | 32.33 us | - | 215 B |
21 | | Compress | LZ10 | 1 | 37,801.3 us | 669.52 us | 771.02 us | - | 6864 B |
22 | | Decompress | LZ10 | 1 | 3,828.9 us | 6.12 us | 5.73 us | - | 189 B |
23 | | Compress | LZ11 | 1 | 35,927.7 us | 697.26 us | 618.10 us | - | 6891 B |
24 | | Decompress | LZ11 | 1 | 3,500.1 us | 3.03 us | 2.68 us | - | 189 B |
25 | | Compress | LZ40 | 1 | 20,452.9 us | 319.00 us | 298.39 us | - | 6950 B |
26 | | Decompress | LZ40 | 1 | 3,532.6 us | 6.55 us | 6.13 us | - | 141 B |
27 | | Compress | LZ4Legacy | 1 | 131,799.8 us | 2,470.23 us | 4,578.74 us | - | 7218 B |
28 | | Decompress | LZ4Legacy | 1 | 2,649.3 us | 32.52 us | 30.41 us | - | 141 B |
29 | | Compress | LZO | 1 | 129,463.7 us | 2,415.20 us | 5,832.97 us | - | 7156 B |
30 | | Decompress | LZO | 1 | 2,902.7 us | 39.59 us | 37.03 us | - | 142 B |
31 | | Compress | LZSS | 1 | 21,672.2 us | 391.68 us | 347.22 us | - | 6922 B |
32 | | Decompress | LZSS | 1 | 3,741.9 us | 39.14 us | 36.61 us | - | 213 B |
33 | | Compress | LZShrek | 1 | 39,688.8 us | 792.59 us | 778.43 us | - | 7010 B |
34 | | Decompress | LZShrek | 1 | 2,603.3 us | 29.79 us | 27.86 us | - | 141 B |
35 | | Compress | MIO0 | 1 | 40,157.3 us | 779.19 us | 985.42 us | - | 7103 B |
36 | | Decompress | MIO0 | 1 | 2,284.3 us | 19.84 us | 18.56 us | - | 165 B |
37 | | Compress | PRS | 1 | 34,021.8 us | 580.83 us | 543.30 us | - | 6879 B |
38 | | Decompress | PRS | 1 | 2,131.5 us | 28.23 us | 26.40 us | - | 237 B |
39 | | Compress | RLE30 | 1 | 3,810.5 us | 38.89 us | 36.38 us | - | 91 B |
40 | | Decompress | RLE30 | 1 | 662.6 us | 6.05 us | 5.66 us | - | 65 B |
41 | | Compress | RefPack | 1 | 69,832.0 us | 1,364.97 us | 2,164.98 us | - | 6967 B |
42 | | Decompress | RefPack | 1 | 1,254.7 us | 14.06 us | 13.15 us | - | 139 B |
43 | | Compress | Yay0 | 1 | 23,130.2 us | 439.65 us | 431.79 us | - | 7050 B |
44 | | Decompress | Yay0 | 1 | 3,241.4 us | 31.60 us | 29.56 us | - | 478 B |
45 | | Compress | Yaz0 | 1 | 23,597.2 us | 470.32 us | 461.92 us | - | 6872 B |
46 | | Decompress | Yaz0 | 1 | 2,653.0 us | 33.51 us | 31.34 us | - | 213 B |
--------------------------------------------------------------------------------
/Benchmarks/Benchmarks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 | true
9 | Debug;Release;Optimized
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Always
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Benchmarks/Benchmarks/TestAlgorithm.cs:
--------------------------------------------------------------------------------
1 | using AuroraLib.Compression.Algorithms;
2 | using AuroraLib.Compression.Interfaces;
3 | using AuroraLib.Core.IO;
4 | using BenchmarkDotNet.Attributes;
5 |
6 | namespace Benchmarks.Benchmarks
7 | {
8 | [MemoryDiagnoser]
9 | public class TestAlgorithm where T : ICompressionAlgorithm, new()
10 | {
11 | public const string TestFile = "Test.bmp";
12 | public Stream TestRawData = Stream.Null;
13 | public Stream TestComData = Stream.Null;
14 | public T Instance = new();
15 |
16 | [Params(1)]
17 | public int MB;
18 |
19 | [GlobalSetup]
20 | public void GlobalSetup()
21 | {
22 | using FileStream input = new(TestFile, FileMode.Open, FileAccess.Read);
23 | TestRawData = new MemoryPoolStream(input, 1024 * 1024); //read 1mb
24 | TestComData = Instance.Compress(TestRawData);
25 | }
26 |
27 | [GlobalCleanup]
28 | public void GlobalCleanup()
29 | {
30 | TestRawData.Dispose();
31 | TestComData.Dispose();
32 | }
33 |
34 | [Benchmark]
35 | public void Compress()
36 | {
37 | using MemoryPoolStream output = new();
38 | for (int i = 0; i < MB; i++)
39 | {
40 | TestRawData.Position = 0;
41 | output.Position = 0;
42 | Instance.Compress(TestRawData, output);
43 | }
44 | }
45 |
46 | [Benchmark]
47 | public void Decompress()
48 | {
49 | using MemoryPoolStream output = new();
50 | for (int i = 0; i < MB; i++)
51 | {
52 | TestComData.Position = 0;
53 | output.Position = 0;
54 | Instance.Decompress(TestComData, output);
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Benchmarks/Benchmarks/TestAllAlgorithms.cs:
--------------------------------------------------------------------------------
1 | using AuroraLib.Compression.Algorithms;
2 | using AuroraLib.Compression.Interfaces;
3 | using AuroraLib.Core.IO;
4 | using BenchmarkDotNet.Attributes;
5 |
6 | namespace Benchmarks.Benchmarks
7 | {
8 | [MemoryDiagnoser]
9 | public class TestAllAlgorithms
10 | {
11 | public const string TestFile = "Test.bmp";
12 | public Stream TestRawData = Stream.Null;
13 | public Stream TestComData = Stream.Null;
14 |
15 | // Test all unique algorithm.
16 | [Params(typeof(ALLZ), typeof(CLZ0), typeof(CNS), typeof(CNX2), typeof(LZ00), typeof(LZ02), typeof(LZ10), typeof(LZ11), typeof(LZ40), typeof(LZO), typeof(LZShrek), typeof(LZSS), typeof(MIO0), typeof(PRS), typeof(RefPack), typeof(RLE30), typeof(Yay0), typeof(Yaz0), typeof(LZ4Legacy), typeof(HWGZ), typeof(HUF20))]
17 | public Type Algorithm = null!;
18 |
19 | public ICompressionAlgorithm Instance = null!;
20 |
21 | [Params(1)]
22 | public int MB;
23 |
24 | [GlobalSetup]
25 | public void GlobalSetup()
26 | {
27 | Instance = (ICompressionAlgorithm)Activator.CreateInstance(Algorithm)!;
28 | using FileStream input = new(TestFile, FileMode.Open, FileAccess.Read);
29 | TestRawData = new MemoryPoolStream(input, 1024 * 1024); //read 1mb
30 | TestComData = Instance.Compress(TestRawData);
31 | }
32 |
33 | [GlobalCleanup]
34 | public void GlobalCleanup()
35 | {
36 | TestRawData.Dispose();
37 | TestComData.Dispose();
38 | }
39 |
40 | [Benchmark]
41 | public void Compress()
42 | {
43 | using MemoryPoolStream output = new();
44 | for (int i = 0; i < MB; i++)
45 | {
46 | TestRawData.Position = 0;
47 | output.Position = 0;
48 | Instance.Compress(TestRawData, output);
49 | }
50 | }
51 |
52 | [Benchmark]
53 | public void Decompress()
54 | {
55 | using MemoryPoolStream output = new();
56 | for (int i = 0; i < MB; i++)
57 | {
58 | TestComData.Position = 0;
59 | output.Position = 0;
60 | Instance.Decompress(TestComData, output);
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Benchmarks/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 | using Benchmarks.Benchmarks;
3 |
4 | //BenchmarkRunner.Run>();
5 |
6 | BenchmarkRunner.Run();
--------------------------------------------------------------------------------
/Benchmarks/Test.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Venomalia/AuroraLib.Compression/1a2c6607500ade4705b5bf48f66514380d258732/Benchmarks/Test.bmp
--------------------------------------------------------------------------------
/CompressionTest/CompressionAlgorithmTest.cs:
--------------------------------------------------------------------------------
1 | using AuroraLib.Compression;
2 | using AuroraLib.Compression.Algorithms;
3 | using AuroraLib.Compression.Interfaces;
4 | using AuroraLib.Core.Buffers;
5 | using AuroraLib.Core.Format;
6 | using AuroraLib.Core.IO;
7 | using HashDepot;
8 | using Microsoft.VisualStudio.TestTools.UnitTesting;
9 | using System;
10 | using System.Buffers;
11 | using System.Collections.Generic;
12 | using System.IO;
13 | using System.IO.Compression;
14 | using System.Linq;
15 |
16 | namespace CompressionTest
17 | {
18 | [TestClass]
19 | public class CompressionAlgorithmTest
20 | {
21 | static CompressionAlgorithmTest()
22 | {
23 | LZ4.HashAlgorithm = b => XXHash.Hash32(b);
24 | }
25 |
26 | [TestMethod]
27 | public void LzssStaticDecodingTest()
28 | {
29 | using (FileStream compressData = new FileStream("Test.lz", FileMode.Open, FileAccess.Read))
30 | {
31 | LZSS lz = new LZSS(new LzProperties((byte)10, 6, 2));
32 | int decompressedSize = (int)lz.GetDecompressedSize(compressData);
33 | byte[] data = ArrayPool.Shared.Rent(decompressedSize);
34 | try
35 | {
36 | Span buffer = data.AsSpan(0, decompressedSize);
37 | lz.Decompress(compressData, buffer);
38 | ulong decompressDataHash = XXHash.Hash64(buffer);
39 | Assert.AreEqual(11520079745250749767, decompressDataHash);
40 | }
41 | finally
42 | {
43 | ArrayPool.Shared.Return(data);
44 | }
45 | }
46 | }
47 |
48 | public static IEnumerable