Implement Zstd support (#1125)

* Implement `Zstd` support.

* Implement requested changes
This commit is contained in:
Razmoth 2023-12-09 12:26:39 +04:00 committed by GitHub
parent 7f38a9548d
commit b126333d49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 1 deletions

View File

@ -10,6 +10,7 @@
<PackageReference Include="AssetRipper.Primitives" Version="2.0.1" /> <PackageReference Include="AssetRipper.Primitives" Version="2.0.1" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.6" /> <PackageReference Include="K4os.Compression.LZ4" Version="1.3.6" />
<PackageReference Include="SharpCompress" Version="0.34.2" /> <PackageReference Include="SharpCompress" Version="0.34.2" />
<PackageReference Include="ZstdSharp.Port" Version="0.7.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -107,7 +107,14 @@ namespace AssetRipper.IO.Files.BundleFiles.FileStream
break; break;
default: default:
UnsupportedBundleDecompression.Throw(entry.PathFixed, compressType); if (ZstdCompression.IsZstd(m_stream))
{
ZstdCompression.DecompressStream(m_stream, block.CompressedSize, m_cachedBlockStream, block.UncompressedSize);
}
else
{
UnsupportedBundleDecompression.Throw(entry.PathFixed, compressType);
}
break; break;
} }
blockStream = m_cachedBlockStream; blockStream = m_cachedBlockStream;

View File

@ -0,0 +1,28 @@
using AssetRipper.IO.Files.Streams;
using ZstdSharp;
namespace AssetRipper.IO.Files.BundleFiles
{
public static class ZstdCompression
{
private static readonly byte[] Signature = [0x28, 0xB5, 0x2F, 0xFD];
public static bool IsZstd(Stream Stream)
{
Span<byte> buffer = stackalloc byte[4];
long pos = Stream.Position;
Stream.ReadExactly(buffer);
Stream.Position = pos;
return buffer.SequenceEqual(Signature);
}
public static void DecompressStream(Stream compressedStream, long compressedSize, Stream decompressedStream, long decompressedSize)
{
using PartialStream compressedPartialStream = new PartialStream(compressedStream, compressedStream.Position, compressedSize, true);
using PartialStream decompressedPartialStream = new PartialStream(decompressedStream, decompressedStream.Position, decompressedSize, true);
using DecompressionStream zstdStream = new DecompressionStream(compressedPartialStream);
zstdStream.CopyTo(decompressedPartialStream);
}
}
}