可参考项目: https://www.nuget.org/packages/DotFastLZ.Compression
This commit is contained in:
Sunny 2024-06-19 21:17:57 +08:00
parent 23ae9da234
commit 91d6601d52
5 changed files with 0 additions and 504 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,146 +0,0 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2024 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UCompress.cs
* :
* : V3.4
* : 2023-07-17
*
* 2023-07-17: V3.4.0
******************************************************************************/
using System;
using System.Runtime.InteropServices;
namespace Sunny.UI
{
public enum DataFrameCompressType
{
[DisplayText("None")]
None = 0,
[DisplayText("FastLZ")]
FastLZ = 1,
[DisplayText("ZLib")]
ZLib = 2,
[DisplayText("GZip")]
GZip = 3,
[DisplayText("Deflate")]
Deflate = 4
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct DataFrame
{
public DateTime DateTime;
public byte[] Data;
public int Index;
public int CRC;
public DataFrame(DateTime dateTime, byte[] data, int index, int crc)
{
DateTime = dateTime;
Data = data;
Index = index;
CRC = crc;
}
public static DataFrame Empty()
{
#if NET40
return new DataFrame(DateTime.MinValue, new byte[0], -1, 0);
#else
return new DataFrame(DateTime.MinValue, Array.Empty<byte>(), -1, 0);
#endif
}
}
public static class DataFrameCompressHelper
{
public static byte[] Compress(DataFrame frame, DataFrameCompressType compressType, out int compressedLength, out int decompressLength)
{
byte[] compressed;
decompressLength = frame.Data.Length;
switch (compressType)
{
case DataFrameCompressType.None:
compressed = frame.Data;
break;
case DataFrameCompressType.FastLZ:
if (FastLZ.CheckFastLZDll())
{
compressed = FastLZ.Compress(frame.Data, 0, frame.Data.Length);
decompressLength = Math.Max(frame.Data.Length * 2, 66);
}
else
{
throw new NullReferenceException("FastLZx86.dll and FastLZx64.dll not exists.");
}
break;
case DataFrameCompressType.ZLib:
compressed = frame.Data.ZLibCompress();
break;
case DataFrameCompressType.GZip:
compressed = frame.Data.GZipCompress();
break;
case DataFrameCompressType.Deflate:
compressed = frame.Data.DeflateCompress();
break;
default:
compressed = frame.Data;
break;
}
compressedLength = compressed.Length;
return compressed;
}
public static byte[] Decompress(byte[] package, DataFrameCompressType compressType, int decompressLength)
{
byte[] data;
switch (compressType)
{
case DataFrameCompressType.None:
data = package;
break;
case DataFrameCompressType.FastLZ:
if (FastLZ.CheckFastLZDll())
{
data = FastLZ.Decompress(package, 0, package.Length, decompressLength);
}
else
{
throw new NullReferenceException("FastLZx86.dll and FastLZx64.dll not exists.");
}
break;
case DataFrameCompressType.ZLib:
data = package.ZLibDecompress();
break;
case DataFrameCompressType.GZip:
data = package.GZipDecompress();
break;
case DataFrameCompressType.Deflate:
data = package.DeflateDecompress();
break;
default:
data = package;
break;
}
return data;
}
}
}

View File

@ -1,356 +0,0 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2024 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : FastLZ.cs
* : FastLZ压缩解压类
* : V3.1
* : 2022-03-31
* : https://ariya.github.io/FastLZ/
*
* FastLZ (MIT license) is an ANSI C/C90 implementation of Lempel-Ziv 77
* algorithm (LZ77) of lossless data compression. It is suitable to compress
* series of text/paragraphs, sequences of raw pixel data, or any other blocks
* of data with lots of repetition. It is not intended to be used on images,
* videos, and other formats of data typically already in an optimal
* compressed form.
*
* 2022-03-31: V3.1.2
* 2022-07-07: V3.2.1
* 2022-07-07: V3.2.1 FastLZx86.dllFastLZx64.dll资源文件
******************************************************************************
*
* int fastlz_compress_level(int level, const void* input, int length, void* output);
*
* level 12
* 1
* 2
* 使fastlz_decompress进行解压缩
*
* input
* length 16
* output 5%66
*
*
******************************************************************************
*
* int fastlz_decompress(const void* input, int length, void* output, int maxout);
*
* input
* length
* output
* maxout maxout中指定的值
*
* 0
*
******************************************************************************
* CompressExDecompressEx
* 168!\r\n结尾
* 20:
* 4(!FLZ)
* 4SecondsUnix时间戳Jan1st1970开始的秒数
* 4Milliseconds
* 4(maxout)
* 4()
* 8:
* 4
* 1(*)
* 1(CRC,,0)
* 2(\r\n)
******************************************************************************
* FastLZx86.dllFastLZx64.dll见项目 https://gitee.com/yhuse/SunnyUI.FastLZ
******************************************************************************/
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Sunny.UI
{
public static unsafe class FastLZx86
{
[DllImport("FastLZx86.dll", EntryPoint = "FastLZ_Compress", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Compress(void* input, int length, void* output);
[DllImport("FastLZx86.dll", EntryPoint = "FastLZ_Compress_level", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Compress_level(int level, void* input, int length, void* output);
[DllImport("FastLZx86.dll", EntryPoint = "FastLZ_Decompress", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Decompress(void* input, int length, void* output, int maxout);
}
public static unsafe class FastLZx64
{
[DllImport("FastLZx64.dll", EntryPoint = "FastLZ_Compress", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Compress(void* input, int length, void* output);
[DllImport("FastLZx64.dll", EntryPoint = "FastLZ_Compress_level", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Compress_level(int level, void* input, int length, void* output);
[DllImport("FastLZx64.dll", EntryPoint = "FastLZ_Decompress", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Decompress(void* input, int length, void* output, int maxout);
}
public enum FastLZCompressionLevel
{
Level1 = 1,
Level2 = 2
}
/// <summary>
/// FastLZ压缩解压类
/// </summary>
public static unsafe class FastLZ
{
/// <summary>
/// 是否64位
/// </summary>
/// <returns></returns>
private static bool Is64bitApp()
{
return IntPtr.Size == 8;
}
/// <summary>
/// 压缩(原生)
/// </summary>
/// <param name="input">输入</param>
/// <param name="begin">起始位置</param>
/// <param name="length">长度</param>
/// <returns>压缩结果</returns>
public static byte[] Compress(byte[] input, int begin, int length)
{
CheckFastLZDll();
byte[] output = new byte[Math.Max(length * 2, 66)];
fixed (void* pSrc1 = &input[begin])
fixed (void* pSrc2 = output)
{
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Compress(pSrc1, length, pSrc2) : FastLZx86.FastLZ_Compress(pSrc1, length, pSrc2);
byte[] result = new byte[outlen];
Array.Copy(output, 0, result, 0, outlen);
return result;
}
}
/// <summary>
/// 压缩(原生)
/// </summary>
/// <param name="level">压缩级别</param>
/// <param name="input">输入</param>
/// <param name="begin">起始位置</param>
/// <param name="length">长度</param>
/// <returns>压缩结果</returns>
public static byte[] Compress(FastLZCompressionLevel level, byte[] input, int begin, int length)
{
CheckFastLZDll();
byte[] output = new byte[Math.Max(length * 2, 66)];
fixed (void* pSrc1 = &input[begin])
fixed (void* pSrc2 = output)
{
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Compress_level((int)level, pSrc1, length, pSrc2) : FastLZx86.FastLZ_Compress_level((int)level, pSrc1, length, pSrc2);
byte[] result = new byte[outlen];
Array.Copy(output, 0, result, 0, outlen);
return result;
}
}
/// <summary>
/// 解压缩(原生)
/// </summary>
/// <param name="input">输入</param>
/// <param name="begin">起始位置</param>
/// <param name="length">长度</param>
/// <param name="maxout">解压结果最大长度</param>
/// <returns>解压缩结果</returns>
public static byte[] Decompress(byte[] input, int begin, int length, int maxout)
{
CheckFastLZDll();
byte[] output = new byte[maxout + 66];
fixed (byte* pSrc1 = &input[begin])
fixed (byte* pSrc2 = output)
{
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Decompress(pSrc1, length, pSrc2, output.Length) : FastLZx86.FastLZ_Decompress(pSrc1, length, pSrc2, output.Length);
byte[] result = new byte[outlen];
Array.Copy(output, 0, result, 0, outlen);
return result;
}
}
private static byte[] ExHead = "!FLZ".ToEnBytes(4);
private const int ExHeadAllLength = 20;
private const int ExTailAllLength = 8;
private static DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// 压缩(扩展)
/// </summary>
/// <param name="input">输入</param>
/// <param name="begin">起始位置</param>
/// <param name="length">长度</param>
/// <param name="datetime">时间</param>
/// <param name="index">索引</param>
/// <returns>压缩结果</returns>
public static byte[] CompressEx(byte[] input, int begin, int length, DateTime dateTime, int index)
{
CheckFastLZDll();
byte[] result = CompressEx(input, begin, length);
if (result.Length > 0)
{
TimeSpan span = dateTime - Jan1st1970;
int totalSeconds = (int)span.TotalSeconds;
int milliseconds = span.Milliseconds;
Array.Copy(BitConverter.GetBytes(totalSeconds), 0, result, 4, 4);
Array.Copy(BitConverter.GetBytes(milliseconds), 0, result, 8, 4);
Array.Copy(BitConverter.GetBytes(index), 0, result, result.Length - 8, 4);
}
return result;
}
/// <summary>
/// 压缩(扩展)
/// </summary>
/// <param name="input">输入</param>
/// <param name="begin">起始位置</param>
/// <param name="length">长度</param>
/// <returns>压缩结果</returns>
public static byte[] CompressEx(byte[] input, int begin, int length)
{
CheckFastLZDll();
byte[] result = new byte[0];
if (begin + length > input.Length) return result;
byte[] output = new byte[Math.Max(length * 2, 66)];
fixed (void* pSrc1 = &input[begin])
fixed (void* pSrc2 = output)
{
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Compress(pSrc1, length, pSrc2) : FastLZx86.FastLZ_Compress(pSrc1, length, pSrc2);
result = new byte[outlen + ExHeadAllLength + ExTailAllLength];
Array.Copy(ExHead, 0, result, 0, ExHead.Length);
Array.Copy(BitConverter.GetBytes((int)0), 0, result, 4, 4);
Array.Copy(BitConverter.GetBytes((int)0), 0, result, 8, 4);
Array.Copy(BitConverter.GetBytes((int)output.Length), 0, result, 12, 4);
Array.Copy(BitConverter.GetBytes((int)outlen), 0, result, 16, 4);
Array.Copy(output, 0, result, ExHeadAllLength, outlen);
Array.Copy(BitConverter.GetBytes((int)0), 0, result, result.Length - 8, 4);
result[result.Length - 4] = 42; //*
result[result.Length - 3] = 0; //CRC
result[result.Length - 2] = 13; //\r
result[result.Length - 1] = 10; //\n
return result;
}
}
/// <summary>
/// 解压缩(扩展)
/// </summary>
/// <param name="input">输入</param>
/// <param name="begin">起始位置</param>
/// <param name="length">长度</param>
/// <returns>解压缩结果</returns>
public static byte[] DecompressEx(byte[] input, int begin, int length)
{
CheckFastLZDll();
byte[] result = new byte[0];
if (input.Length <= 2 + ExHeadAllLength + ExTailAllLength) return result;
if (begin + length > input.Length) return result;
if (input[begin] != 33) return result;
if (input[begin + length - 4] != 42) return result;
if (length != BitConverter.ToInt32(input, begin + 16) + ExHeadAllLength + ExTailAllLength) return result;
byte[] output = new byte[BitConverter.ToInt32(input, begin + ExHead.Length)];
fixed (byte* pSrc1 = &input[begin + ExHeadAllLength])
fixed (byte* pSrc2 = output)
{
length = length - ExHeadAllLength - ExTailAllLength;
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Decompress(pSrc1, length, pSrc2, output.Length) : FastLZx86.FastLZ_Decompress(pSrc1, length, pSrc2, output.Length);
result = new byte[outlen];
Array.Copy(output, 0, result, 0, outlen);
return result;
}
}
/// <summary>
/// 解压缩(扩展)
/// </summary>
/// <param name="input">输入</param>
/// <param name="begin">起始位置</param>
/// <param name="length">长度</param>
/// <param name="datetime">时间</param>
/// <param name="index">索引</param>
/// <returns>解压缩结果</returns>
public static byte[] DecompressEx(byte[] input, int begin, int length, out DateTime datetime, out int index)
{
CheckFastLZDll();
byte[] result = DecompressEx(input, begin, length);
datetime = Jan1st1970;
index = 0;
if (result.Length > 0)
{
datetime = Jan1st1970.AddSeconds(BitConverter.ToInt32(input, begin + 4)).AddMilliseconds(BitConverter.ToInt32(input, begin + 8));
index = BitConverter.ToInt32(input, begin + length - 8);
}
return result;
}
private static bool FileExist = false;
public static bool CheckFastLZDll()
{
if (FileExist) return true;
if (File.Exists(DirEx.CurrentDir() + "FastLZx86.dll") && File.Exists(DirEx.CurrentDir() + "FastLZx64.dll"))
{
FileExist = true;
return true;
}
try
{
CreateResourceToFile(DirEx.CurrentDir() + "FastLZx86.dll", "Sunny.UI.Common.FastLZx86.dat");
CreateResourceToFile(DirEx.CurrentDir() + "FastLZx64.dll", "Sunny.UI.Common.FastLZx64.dat");
}
catch
{
return false;
}
FileExist = File.Exists(DirEx.CurrentDir() + "FastLZx86.dll") && File.Exists(DirEx.CurrentDir() + "FastLZx64.dll");
return FileExist;
}
/// <summary>
/// 从系统资源中保存文件
/// </summary>
/// <param name="file">文件名</param>
/// <param name="resource">资源名称</param>
private static void CreateResourceToFile(string file, string resource)
{
if (!File.Exists(file))
{
Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
if (stream != null)
{
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
stream.Close();
File.WriteAllBytes(file, buffer);
}
}
}
}
}

View File

@ -50,8 +50,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Common\FastLZx64.dat" />
<EmbeddedResource Include="Common\FastLZx86.dat" />
<EmbeddedResource Include="Font\ElegantIcons.ttf" /> <EmbeddedResource Include="Font\ElegantIcons.ttf" />
<EmbeddedResource Include="Font\fa-brands-400.ttf" /> <EmbeddedResource Include="Font\fa-brands-400.ttf" />
<EmbeddedResource Include="Font\fa-regular-400.ttf" /> <EmbeddedResource Include="Font\fa-regular-400.ttf" />