mirror of
https://github.com/sp-tarkov/modules.git
synced 2025-02-13 09:50:43 -05:00
127 lines
2.4 KiB
C#
127 lines
2.4 KiB
C#
using System;
|
|
using System.IO;
|
|
using ComponentAce.Compression.Libs.zlib;
|
|
|
|
namespace Aki.Common.Utils
|
|
{
|
|
public enum ZlibCompression
|
|
{
|
|
Store = 0,
|
|
Fastest = 1,
|
|
Fast = 3,
|
|
Normal = 5,
|
|
Ultra = 7,
|
|
Maximum = 9
|
|
}
|
|
|
|
public static class Zlib
|
|
{
|
|
// Level | CM/CI FLG
|
|
// ----- | ---------
|
|
// 1 | 78 01
|
|
// 2 | 78 5E
|
|
// 3 | 78 5E
|
|
// 4 | 78 5E
|
|
// 5 | 78 5E
|
|
// 6 | 78 9C
|
|
// 7 | 78 DA
|
|
// 8 | 78 DA
|
|
// 9 | 78 DA
|
|
|
|
/// <summary>
|
|
/// Check if the file is ZLib compressed
|
|
/// </summary>
|
|
/// <param name="Data">Data</param>
|
|
/// <returns>If the file is Zlib compressed</returns>
|
|
public static bool IsCompressed(byte[] Data)
|
|
{
|
|
// We need the first two bytes;
|
|
// First byte: Info (CM/CINFO) Header, should always be 0x78
|
|
// Second byte: Flags (FLG) Header, should define our compression level.
|
|
|
|
if (Data == null || Data.Length < 3 || Data[0] != 0x78)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
switch (Data[1])
|
|
{
|
|
case 0x01: // fastest
|
|
case 0x5E: // low
|
|
case 0x9C: // normal
|
|
case 0xDA: // max
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deflate data.
|
|
/// </summary>
|
|
public static byte[] Compress(byte[] data, ZlibCompression level)
|
|
{
|
|
byte[] buffer = new byte[data.Length + 24];
|
|
|
|
ZStream zs = new ZStream()
|
|
{
|
|
avail_in = data.Length,
|
|
next_in = data,
|
|
next_in_index = 0,
|
|
avail_out = buffer.Length,
|
|
next_out = buffer,
|
|
next_out_index = 0
|
|
};
|
|
|
|
zs.deflateInit((int)level);
|
|
zs.deflate(zlibConst.Z_FINISH);
|
|
|
|
data = new byte[zs.next_out_index];
|
|
Array.Copy(zs.next_out, 0, data, 0, zs.next_out_index);
|
|
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inflate data.
|
|
/// </summary>
|
|
public static byte[] Decompress(byte[] data)
|
|
{
|
|
byte[] buffer = new byte[4096];
|
|
|
|
ZStream zs = new ZStream()
|
|
{
|
|
avail_in = data.Length,
|
|
next_in = data,
|
|
next_in_index = 0,
|
|
avail_out = buffer.Length,
|
|
next_out = buffer,
|
|
next_out_index = 0
|
|
};
|
|
|
|
zs.inflateInit();
|
|
|
|
using (MemoryStream ms = new MemoryStream())
|
|
{
|
|
do
|
|
{
|
|
zs.avail_out = buffer.Length;
|
|
zs.next_out = buffer;
|
|
zs.next_out_index = 0;
|
|
|
|
int result = zs.inflate(0);
|
|
|
|
if (result != 0 && result != 1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
ms.Write(zs.next_out, 0, zs.next_out_index);
|
|
}
|
|
while (zs.avail_in > 0 || zs.avail_out == 0);
|
|
|
|
return ms.ToArray();
|
|
}
|
|
}
|
|
}
|
|
} |