Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix decompression of assets larger than 65536 bytes #4

Merged
merged 2 commits into from
Aug 21, 2024
Merged
Changes from 1 commit
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
62 changes: 46 additions & 16 deletions Galanthus/SdfToc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,8 @@

public unsafe Block<byte>? GetData(Asset inAsset)
{
int outBufferSize = 0;

// get final file size
int outBufferSize = 0;
if (inAsset.DdsIndex != -1)
{
outBufferSize += m_ddsHeaders[inAsset.DdsIndex].Size;
Expand All @@ -385,7 +384,7 @@
}
Block<byte> outBuffer = new(outBufferSize);

// add dds header
// add dds header data
if (inAsset.DdsIndex != -1)
{
m_ddsHeaders[inAsset.DdsIndex].CopyTo(outBuffer);
Expand All @@ -402,7 +401,7 @@

using (DataStream stream = BlockStream.FromFile(path, dataSlice.Offset, (int)dataSlice.CompressedSize))
{
// read slice
// read whole slice into buffer
Block<byte> compressedBuffer = new((int)dataSlice.CompressedSize);
stream.ReadExactly(compressedBuffer);

Expand Down Expand Up @@ -439,27 +438,58 @@
}
}

// decompress slice
// decompress slice if needed
if (dataSlice.IsCompressed)
{
if (!dataSlice.IsOodle)
{
ZStd.Decompress(compressedBuffer, ref outBuffer);
}
else
int pageSize = 0x10000;
int decompressedOffset = 0;
int compressedOffset = 0;

// iterate through pages
for (int i = 0; i < dataSlice.PageSizes.Count; i++)

Check warning on line 449 in Galanthus/SdfToc.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
CosmicDreamsOfCode marked this conversation as resolved.
Show resolved Hide resolved
{
Block<byte> tempBuffer = new(outBuffer.Ptr, (int)dataSlice.DecompressedSize);
tempBuffer.MarkMemoryAsFragile();
Oodle.Decompress(compressedBuffer, ref tempBuffer);
tempBuffer.Dispose();
int decompressedSize = (int)Math.Min(dataSlice.DecompressedSize - decompressedOffset, pageSize);

if (dataSlice.PageSizes[i] == 0 || decompressedSize == dataSlice.PageSizes[i])
{
// uncompressed page
compressedOffset = decompressedSize;
compressedBuffer.CopyTo(outBuffer, decompressedSize);
}
else
{
// compressed page
// set up temp buffer with only the page data
Block<byte> tempBuffer = new(compressedBuffer.Ptr, dataSlice.PageSizes[i]);
tempBuffer.MarkMemoryAsFragile();
compressedOffset = dataSlice.PageSizes[i];
CosmicDreamsOfCode marked this conversation as resolved.
Show resolved Hide resolved

if (!dataSlice.IsOodle)
{
ZStd.Decompress(tempBuffer, ref outBuffer);
}
else
{
// oodle is annoying and won't work unless the output buffer is exactly as big as the decompressed data
Block<byte> oodleOutBuffer = new(outBuffer.Ptr, decompressedSize);
oodleOutBuffer.MarkMemoryAsFragile();
Oodle.Decompress(tempBuffer, ref oodleOutBuffer);
oodleOutBuffer.Dispose();
}
tempBuffer.Dispose();
}

decompressedOffset += decompressedSize;
compressedBuffer.Shift(compressedOffset);
outBuffer.Shift(decompressedSize);
}
}
else
{
compressedBuffer.CopyTo(outBuffer);
compressedBuffer.CopyTo(outBuffer, (int)dataSlice.DecompressedSize);
outBuffer.Shift((int)dataSlice.DecompressedSize);
}

outBuffer.Shift((int)dataSlice.DecompressedSize);
compressedBuffer.Dispose();
}
}
Expand Down
Loading