Skip to content

Commit

Permalink
Check size of DDS file to not include padding
Browse files Browse the repository at this point in the history
  • Loading branch information
luizzeroxis committed Sep 28, 2024
1 parent 598d0c1 commit a0df1df
Showing 1 changed file with 50 additions and 3 deletions.
53 changes: 50 additions & 3 deletions UndertaleModLib/Util/GMImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<paddingBytes.Length; i++)
{
if (paddingBytes[i] != 0)
throw new IOException("Non-zero bytes in padding");
}

return FromDds(bytes);
}

throw new IOException("Failed to recognize any known image header");
Expand Down Expand Up @@ -488,7 +535,7 @@ public static GMImage FromDds(byte[] data)
return new GMImage(ImageFormat.Dds, width, height, data);
}

private void AddMagickToPngSettings(MagickReadSettings settings)
private static void AddMagickToPngSettings(MagickReadSettings settings)
{
settings.SetDefine(MagickFormat.Png32, "compression-level", 4);
settings.SetDefine(MagickFormat.Png32, "compression-filter", 5);
Expand Down

0 comments on commit a0df1df

Please sign in to comment.