* FastLZ: 增加了扩展的自定义压缩解压方法

This commit is contained in:
Sunny 2022-07-06 23:22:21 +08:00
parent 665ba89e62
commit 5e09012ad7

View File

@ -25,6 +25,36 @@
* compressed form. * compressed form.
* *
* 2022-03-31: V3.1.2 * 2022-03-31: V3.1.2
******************************************************************************
*
* 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结尾
* 16:8(!FastLZ )+4(maxout)+4()
* 8:4()+1(*)+1(CRC,,0)+2(\r\n)
******************************************************************************/ ******************************************************************************/
using System; using System;
@ -32,7 +62,7 @@ using System.Runtime.InteropServices;
namespace Sunny.UI namespace Sunny.UI
{ {
internal static unsafe class FastLZx86 public static unsafe class FastLZx86
{ {
[DllImport("FastLZx86.dll", EntryPoint = "FastLZ_Compress", CallingConvention = CallingConvention.Cdecl)] [DllImport("FastLZx86.dll", EntryPoint = "FastLZ_Compress", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Compress(void* input, int length, void* output); public static extern int FastLZ_Compress(void* input, int length, void* output);
@ -44,7 +74,7 @@ namespace Sunny.UI
public static extern int FastLZ_Decompress(void* input, int length, void* output, int maxout); public static extern int FastLZ_Decompress(void* input, int length, void* output, int maxout);
} }
internal static unsafe class FastLZx64 public static unsafe class FastLZx64
{ {
[DllImport("FastLZx64.dll", EntryPoint = "FastLZ_Compress", CallingConvention = CallingConvention.Cdecl)] [DllImport("FastLZx64.dll", EntryPoint = "FastLZ_Compress", CallingConvention = CallingConvention.Cdecl)]
public static extern int FastLZ_Compress(void* input, int length, void* output); public static extern int FastLZ_Compress(void* input, int length, void* output);
@ -56,6 +86,12 @@ namespace Sunny.UI
public static extern int FastLZ_Decompress(void* input, int length, void* output, int maxout); public static extern int FastLZ_Decompress(void* input, int length, void* output, int maxout);
} }
public enum FastLZCompressionLevel
{
Level1 = 1,
Level2 = 2
}
/// <summary> /// <summary>
/// FastLZ压缩解压类 /// FastLZ压缩解压类
/// </summary> /// </summary>
@ -65,25 +101,25 @@ namespace Sunny.UI
/// 是否64位 /// 是否64位
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static bool Is64bitApp() private static bool Is64bitApp()
{ {
return IntPtr.Size == 8; return IntPtr.Size == 8;
} }
/// <summary> /// <summary>
/// 压缩 /// 压缩(原生)
/// </summary> /// </summary>
/// <param name="input">输入</param> /// <param name="input">输入</param>
/// <param name="begin">起始位置</param> /// <param name="begin">起始位置</param>
/// <param name="len">长度</param> /// <param name="length">长度</param>
/// <returns>压缩结果</returns> /// <returns>压缩结果</returns>
public static byte[] Compress(byte[] input, int begin, int len) public static byte[] Compress(byte[] input, int begin, int length)
{ {
byte[] output = new byte[input.Length]; byte[] output = new byte[Math.Max(length * 2, 66)];
fixed (void* pSrc1 = &input[begin]) fixed (void* pSrc1 = &input[begin])
fixed (void* pSrc2 = output) fixed (void* pSrc2 = output)
{ {
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Compress(pSrc1, len, pSrc2) : FastLZx86.FastLZ_Compress(pSrc1, len, pSrc2); int outlen = Is64bitApp() ? FastLZx64.FastLZ_Compress(pSrc1, length, pSrc2) : FastLZx86.FastLZ_Compress(pSrc1, length, pSrc2);
byte[] result = new byte[outlen]; byte[] result = new byte[outlen];
Array.Copy(output, 0, result, 0, outlen); Array.Copy(output, 0, result, 0, outlen);
return result; return result;
@ -91,20 +127,20 @@ namespace Sunny.UI
} }
/// <summary> /// <summary>
/// 压缩 /// 压缩(原生)
/// </summary> /// </summary>
/// <param name="level">压缩级别</param> /// <param name="level">压缩级别</param>
/// <param name="input">输入</param> /// <param name="input">输入</param>
/// <param name="begin">起始位置</param> /// <param name="begin">起始位置</param>
/// <param name="len">长度</param> /// <param name="length">长度</param>
/// <returns>压缩结果</returns> /// <returns>压缩结果</returns>
public static byte[] Compress(int level, byte[] input, int begin, int len) public static byte[] Compress(FastLZCompressionLevel level, byte[] input, int begin, int length)
{ {
byte[] output = new byte[input.Length]; byte[] output = new byte[Math.Max(length * 2, 66)];
fixed (void* pSrc1 = &input[begin]) fixed (void* pSrc1 = &input[begin])
fixed (void* pSrc2 = output) fixed (void* pSrc2 = output)
{ {
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Compress_level(level, pSrc1, len, pSrc2) : FastLZx86.FastLZ_Compress_level(level, pSrc1, len, pSrc2); 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]; byte[] result = new byte[outlen];
Array.Copy(output, 0, result, 0, outlen); Array.Copy(output, 0, result, 0, outlen);
return result; return result;
@ -112,7 +148,7 @@ namespace Sunny.UI
} }
/// <summary> /// <summary>
/// 解压缩 /// 解压缩(原生)
/// </summary> /// </summary>
/// <param name="input">输入</param> /// <param name="input">输入</param>
/// <param name="begin">起始位置</param> /// <param name="begin">起始位置</param>
@ -121,15 +157,80 @@ namespace Sunny.UI
/// <returns>解压缩结果</returns> /// <returns>解压缩结果</returns>
public static byte[] Decompress(byte[] input, int begin, int length, int maxout) public static byte[] Decompress(byte[] input, int begin, int length, int maxout)
{ {
byte[] output = new byte[maxout]; byte[] output = new byte[maxout + 66];
fixed (byte* pSrc1 = &input[begin]) fixed (byte* pSrc1 = &input[begin])
fixed (byte* pSrc2 = output) fixed (byte* pSrc2 = output)
{ {
int outlen = Is64bitApp() ? FastLZx64.FastLZ_Decompress(pSrc1, length, pSrc2, maxout) : FastLZx86.FastLZ_Decompress(pSrc1, length, pSrc2, maxout); int outlen = Is64bitApp() ? FastLZx64.FastLZ_Decompress(pSrc1, length, pSrc2, output.Length) : FastLZx86.FastLZ_Decompress(pSrc1, length, pSrc2, output.Length);
byte[] result = new byte[outlen]; byte[] result = new byte[outlen];
Array.Copy(output, 0, result, 0, outlen); Array.Copy(output, 0, result, 0, outlen);
return result; return result;
} }
} }
private static byte[] ExHead = "!FastLZ".ToEnBytes(8);
private const int ExHeadAllLength = 16;
private const int ExTailAllLength = 8;
/// <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)
{
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)output.Length), 0, result, 8, 4);
Array.Copy(BitConverter.GetBytes((int)outlen), 0, result, 12, 4);
Array.Copy(output, 0, result, 16, outlen);
result[result.Length - 1 - 7] = 0; //保留
result[result.Length - 1 - 6] = 0; //保留
result[result.Length - 1 - 5] = 0; //保留
result[result.Length - 1 - 4] = 0; //保留
result[result.Length - 1 - 3] = 42; //*
result[result.Length - 1 - 2] = 0; //CRC
result[result.Length - 1 - 1] = 13; //\r
result[result.Length - 1 - 0] = 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)
{
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 + 12) + 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;
}
}
} }
} }