From 83ea5ee1bc170ded985a184056c3a7489dfc38c6 Mon Sep 17 00:00:00 2001 From: Nicholas Hayes <0xC0000054@users.noreply.github.com> Date: Thu, 6 Jul 2023 14:52:02 -0600 Subject: [PATCH] Add support for reading Unreal Tournament 2004 DDS files (#371) --- DirectXTex/DirectXTexDDS.cpp | 118 ++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/DirectXTex/DirectXTexDDS.cpp b/DirectXTex/DirectXTexDDS.cpp index 9c042b4..36e3f87 100644 --- a/DirectXTex/DirectXTexDDS.cpp +++ b/DirectXTex/DirectXTexDDS.cpp @@ -191,74 +191,91 @@ namespace constexpr size_t MAP_SIZE = sizeof(g_LegacyDDSMap) / sizeof(LegacyDDS); 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)) - { - // In case of FourCC codes, ignore any other bits in ddpf.flags - if (ddpf.fourCC == entry->ddpf.fourCC) - break; + if (entry->ddpf.flags & DDS_FOURCC) + { + if (ddpf.fourCC == entry->ddpf.fourCC) + 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; } - else if (entry->ddpf.flags & DDS_ALPHA) + else if (ddpfFlags == entry->ddpf.flags) { - if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount - && ddpf.ABitMask == entry->ddpf.ABitMask) - break; - } - else if (entry->ddpf.flags & DDS_LUMINANCE) - { - if (entry->ddpf.flags & DDS_ALPHAPIXELS) + if (entry->ddpf.flags & DDS_PAL8) + { + if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount) + break; + } + else if (entry->ddpf.flags & DDS_ALPHA) { - // LUMINANCEA if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount - && ddpf.RBitMask == entry->ddpf.RBitMask && ddpf.ABitMask == entry->ddpf.ABitMask) break; } - else + else if (entry->ddpf.flags & DDS_LUMINANCE) { - // LUMINANCE - if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount - && ddpf.RBitMask == entry->ddpf.RBitMask) - break; + if (entry->ddpf.flags & DDS_ALPHAPIXELS) + { + // LUMINANCEA + 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) - { - 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) + else if (entry->ddpf.flags & DDS_BUMPDUDV) { - // RGBA - if (ddpf.RBitMask == entry->ddpf.RBitMask + 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 + else if (ddpf.RGBBitCount == entry->ddpf.RGBBitCount) { - // RGB - if (ddpf.RBitMask == entry->ddpf.RBitMask - && ddpf.GBitMask == entry->ddpf.GBitMask - && ddpf.BBitMask == entry->ddpf.BBitMask) - break; + if (entry->ddpf.flags & DDS_ALPHAPIXELS) + { + // RGBA + if (ddpf.RBitMask == entry->ddpf.RBitMask + && 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; } - //------------------------------------------------------------------------------------- // Decodes DDS header including optional DX10 extended header //------------------------------------------------------------------------------------- @@ -320,8 +336,12 @@ namespace auto pHeader = reinterpret_cast(static_cast(pSource) + sizeof(uint32_t)); // Verify header to validate DDS file - if (pHeader->size != sizeof(DDS_HEADER) - || pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT)) + if (pHeader->size != sizeof(DDS_HEADER)) + { + return E_FAIL; + } + + if (pHeader->ddspf.size != 0 && pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT)) { return E_FAIL; }