From a0df1dfe6987d2ca30d06ba57435f2e78c22158d Mon Sep 17 00:00:00 2001 From: luizzeroxis Date: Fri, 27 Sep 2024 21:01:17 -0300 Subject: [PATCH] Check size of DDS file to not include padding --- UndertaleModLib/Util/GMImage.cs | 53 +++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/UndertaleModLib/Util/GMImage.cs b/UndertaleModLib/Util/GMImage.cs index d5041aa61..87bf450f9 100644 --- a/UndertaleModLib/Util/GMImage.cs +++ b/UndertaleModLib/Util/GMImage.cs @@ -348,9 +348,56 @@ public static GMImage FromBinaryReader(IBinaryReader reader, long maxEndOfStream // DDS if (header.StartsWith(MagicDds)) { - // Read entire image + // Size int skipped because 8 bytes were already read + uint flags = reader.ReadUInt32(); + uint height = reader.ReadUInt32(); + + //uint width = reader.ReadUInt32(); + reader.Position += 4; + + uint pitchOrLinearSize = reader.ReadUInt32(); + + //uint depth = reader.ReadUInt32(); + //uint mipMapCount = reader.ReadUInt32(); + //byte[] reserved1 = reader.ReadBytes(4 * 11); + //uint pixelFormatSize = reader.ReadUInt32(); + reader.Position += 56; + + uint pixelFormatFlags = reader.ReadUInt32(); + uint pixelFormatFourCC = reader.ReadUInt32(); + + // TODO: Check caps for DDSCAPS_COMPLEX (when there's extra data afterwards) + + // Skip to end of header + reader.Position += 40; + + // Check if DX10 header is present and skip it + // DDPF_FOURCC == 0x4 + // DX10 == 0x30315844 + if ((pixelFormatFlags & 0x4) != 0 && pixelFormatFourCC == 0x30315844) + reader.Position += 20; + + // Check if that int is the size or pitch + // DDSD_LINEARSIZE == 0x80000 + int size = (int)(reader.Position - startAddress); + if ((flags & 0x80000) != 0) + size += (int)pitchOrLinearSize; + else + size += (int)(pitchOrLinearSize * height); + + // Read entire data reader.Position = startAddress; - return FromDds(reader.ReadBytes((int)(maxEndOfStreamPosition - startAddress))); + byte[] bytes = reader.ReadBytes(size); + + // Check if rest of bytes are 0x00 padded + byte[] paddingBytes = reader.ReadBytes((int)(maxEndOfStreamPosition - reader.Position)); + for (int i=0; i