Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions src/Andre/SoulsFormats/SoulsFormats/Formats/DCX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@ private static byte[] DecompressDCXZSTD(BinaryReaderEx br)
br.AssertInt32(0x4C);

br.AssertASCII("DCS\0");
int uncompressedSize = br.ReadInt32();
br.ReadInt32(); // uncompressed size
int compressedSize = br.ReadInt32();

br.AssertASCII("DCP\0");
br.AssertASCII("ZSTD");
br.AssertInt32(0x20);
br.AssertByte(0x15);
br.ReadByte(); // compression level
br.AssertByte(0);
br.AssertByte(0);
br.AssertByte(0);
Expand Down Expand Up @@ -477,38 +477,42 @@ internal static void Compress(Span<byte> data, BinaryWriterEx bw, Type type)
CompressDCXKRAK(data, bw, 9);
else if (type == Type.ZSTD)
{
// Temporary until proper ZSTD re-compression settings are discovered
CompressDCPDFLT(data, bw);
CompressDCXZSTD(data, bw);
}
else if (type == Type.Unknown)
throw new ArgumentException("You cannot compress a DCX with an unknown type.");
else
throw new NotImplementedException("Compression for the given type is not implemented.");
}

private static void CompressDCXZSTD(Span<byte> data, BinaryWriterEx bw)
private static void CompressDCXZSTD(Span<byte> data, BinaryWriterEx bw, int compressionLevel = 15)
{
// TODO: just a stub for future implementation
/*
byte[] compressed = SFUtil.WriteZstd(data, compressionLevel);

bw.WriteASCII("DCX\0");
bw.WriteInt32(0x11000);
bw.WriteInt32(0x18);
bw.WriteInt32(0x24);
bw.WriteInt32(0x44);
bw.WriteInt32(0x4C);
bw.WriteASCII("DCS\0");
bw.WriteUInt32((uint)data.Length);
bw.WriteUInt32((uint)compressed.Length);
bw.WriteASCII("DCP\0");
bw.WriteASCII("ZSTD");
bw.WriteInt32(0x20);
bw.WriteInt32(0x9000000);
bw.WriteByte((byte)compressionLevel);
bw.WriteByte(0);
bw.WriteByte(0);
bw.WriteByte(0);
bw.WriteInt32(0);
bw.WriteInt32(0);
bw.WriteInt32(0);
bw.WriteInt32(0x00010100);

bw.WriteASCII("DCS\0");
bw.WriteInt32(data.Length);
bw.ReserveInt32("CompressedSize");

int compressedSize = SFUtil.WriteZstd(bw, 3, data);
bw.FillInt32("CompressedSize", compressedSize);

bw.WriteInt32(0x10100);
bw.WriteASCII("DCA\0");
bw.WriteInt32(8);
*/
bw.WriteBytes(compressed);
bw.Pad(0x10);
}

private static void CompressDCPDFLT(Span<byte> data, BinaryWriterEx bw)
Expand Down
8 changes: 8 additions & 0 deletions src/Andre/SoulsFormats/SoulsFormats/Util/SFUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,14 @@ public static byte[] ReadZlib(BinaryReaderEx br, int compressedSize)
return decompressedStream.ToArray();
}
}
public static byte[] WriteZstd(Span<byte> data, int compressionLevel)
{
var options = new CompressionOptions(null, new Dictionary<ZSTD_cParameter, int> { { ZSTD_cParameter.ZSTD_c_contentSizeFlag, 0 }, { ZSTD_cParameter.ZSTD_c_windowLog, 16 } }, compressionLevel);
using (var compressor = new Compressor(options))
{
return compressor.Wrap(data);
}
}
public static byte[] ReadZstd(BinaryReaderEx br, int compressedSize)
{
byte[] compressed = br.ReadBytes(compressedSize);
Expand Down