Add support for reading Unreal Tournament 2004 DDS files (#371)

This commit is contained in:
Nicholas Hayes 2023-07-06 14:52:02 -06:00 committed by GitHub
parent 70909fd6be
commit 83ea5ee1bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -191,74 +191,91 @@ namespace
constexpr size_t MAP_SIZE = sizeof(g_LegacyDDSMap) / sizeof(LegacyDDS); constexpr size_t MAP_SIZE = sizeof(g_LegacyDDSMap) / sizeof(LegacyDDS);
size_t index = 0; size_t index = 0;
for (index = 0; index < MAP_SIZE; ++index) if (ddpf.size == 0 && ddpf.flags == 0 && ddpf.fourCC != 0)
{ {
const LegacyDDS* entry = &g_LegacyDDSMap[index]; // Handle some DDS files where the DDPF_PIXELFORMAT is mostly zero
for (index = 0; index < MAP_SIZE; ++index)
{
const LegacyDDS* entry = &g_LegacyDDSMap[index];
if ((ddpfFlags & DDS_FOURCC) && (entry->ddpf.flags & DDS_FOURCC)) if (entry->ddpf.flags & DDS_FOURCC)
{ {
// In case of FourCC codes, ignore any other bits in ddpf.flags if (ddpf.fourCC == entry->ddpf.fourCC)
if (ddpf.fourCC == entry->ddpf.fourCC) break;
break; }
} }
else if (ddpfFlags == entry->ddpf.flags) }
else
{
for (index = 0; index < MAP_SIZE; ++index)
{ {
if (entry->ddpf.flags & DDS_PAL8) const LegacyDDS* entry = &g_LegacyDDSMap[index];
if ((ddpfFlags & DDS_FOURCC) && (entry->ddpf.flags & DDS_FOURCC))
{ {
if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount) // In case of FourCC codes, ignore any other bits in ddpf.flags
if (ddpf.fourCC == entry->ddpf.fourCC)
break; break;
} }
else if (entry->ddpf.flags & DDS_ALPHA) else if (ddpfFlags == entry->ddpf.flags)
{ {
if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount if (entry->ddpf.flags & DDS_PAL8)
&& ddpf.ABitMask == entry->ddpf.ABitMask) {
break; if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount)
} break;
else if (entry->ddpf.flags & DDS_LUMINANCE) }
{ else if (entry->ddpf.flags & DDS_ALPHA)
if (entry->ddpf.flags & DDS_ALPHAPIXELS)
{ {
// LUMINANCEA
if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount
&& ddpf.RBitMask == entry->ddpf.RBitMask
&& ddpf.ABitMask == entry->ddpf.ABitMask) && ddpf.ABitMask == entry->ddpf.ABitMask)
break; break;
} }
else else if (entry->ddpf.flags & DDS_LUMINANCE)
{ {
// LUMINANCE if (entry->ddpf.flags & DDS_ALPHAPIXELS)
if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount {
&& ddpf.RBitMask == entry->ddpf.RBitMask) // LUMINANCEA
break; if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount
&& ddpf.RBitMask == entry->ddpf.RBitMask
&& ddpf.ABitMask == entry->ddpf.ABitMask)
break;
}
else
{
// LUMINANCE
if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount
&& ddpf.RBitMask == entry->ddpf.RBitMask)
break;
}
} }
} else if (entry->ddpf.flags & DDS_BUMPDUDV)
else if (entry->ddpf.flags & DDS_BUMPDUDV)
{
if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount
&& ddpf.RBitMask == entry->ddpf.RBitMask
&& ddpf.GBitMask == entry->ddpf.GBitMask
&& ddpf.BBitMask == entry->ddpf.BBitMask
&& ddpf.ABitMask == entry->ddpf.ABitMask)
break;
}
else if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount)
{
if (entry->ddpf.flags & DDS_ALPHAPIXELS)
{ {
// RGBA if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount
if (ddpf.RBitMask == entry->ddpf.RBitMask && ddpf.RBitMask == entry->ddpf.RBitMask
&& ddpf.GBitMask == entry->ddpf.GBitMask && ddpf.GBitMask == entry->ddpf.GBitMask
&& ddpf.BBitMask == entry->ddpf.BBitMask && ddpf.BBitMask == entry->ddpf.BBitMask
&& ddpf.ABitMask == entry->ddpf.ABitMask) && ddpf.ABitMask == entry->ddpf.ABitMask)
break; break;
} }
else else if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount)
{ {
// RGB if (entry->ddpf.flags & DDS_ALPHAPIXELS)
if (ddpf.RBitMask == entry->ddpf.RBitMask {
&& ddpf.GBitMask == entry->ddpf.GBitMask // RGBA
&& ddpf.BBitMask == entry->ddpf.BBitMask) if (ddpf.RBitMask == entry->ddpf.RBitMask
break; && ddpf.GBitMask == entry->ddpf.GBitMask
&& ddpf.BBitMask == entry->ddpf.BBitMask
&& ddpf.ABitMask == entry->ddpf.ABitMask)
break;
}
else
{
// RGB
if (ddpf.RBitMask == entry->ddpf.RBitMask
&& ddpf.GBitMask == entry->ddpf.GBitMask
&& ddpf.BBitMask == entry->ddpf.BBitMask)
break;
}
} }
} }
} }
@ -289,7 +306,6 @@ namespace
return format; return format;
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decodes DDS header including optional DX10 extended header // Decodes DDS header including optional DX10 extended header
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -320,8 +336,12 @@ namespace
auto pHeader = reinterpret_cast<const DDS_HEADER*>(static_cast<const uint8_t*>(pSource) + sizeof(uint32_t)); auto pHeader = reinterpret_cast<const DDS_HEADER*>(static_cast<const uint8_t*>(pSource) + sizeof(uint32_t));
// Verify header to validate DDS file // Verify header to validate DDS file
if (pHeader->size != sizeof(DDS_HEADER) if (pHeader->size != sizeof(DDS_HEADER))
|| pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT)) {
return E_FAIL;
}
if (pHeader->ddspf.size != 0 && pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT))
{ {
return E_FAIL; return E_FAIL;
} }