From e102d0bd3e1a9e59e9aa7276b3ff27c484b783b6 Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Mon, 1 Jul 2024 18:47:31 -0700 Subject: [PATCH] texconv: -ignoremips options for reading some invalid DDS files (#484) --- DirectXTex/DirectXTex.h | 3 +++ DirectXTex/DirectXTexDDS.cpp | 4 ++- Texconv/texconv.cpp | 5 ++++ Texdiag/texdiag.cpp | 48 ++++++++++++++++++++++-------------- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/DirectXTex/DirectXTex.h b/DirectXTex/DirectXTex.h index f7a7e8e..8c680da 100644 --- a/DirectXTex/DirectXTex.h +++ b/DirectXTex/DirectXTex.h @@ -236,6 +236,9 @@ namespace DirectX DDS_FLAGS_PERMISSIVE = 0x80, // Allow some file variants due to common bugs in the header written by various leagcy DDS writers + DDS_FLAGS_IGNORE_MIPS = 0x100, + // Allow some files to be read that have incorrect mipcount values in the header by only reading the top-level mip + DDS_FLAGS_FORCE_DX10_EXT = 0x10000, // Always use the 'DX10' header extension for DDS writer (i.e. don't try to write DX9 compatible DDS files) diff --git a/DirectXTex/DirectXTexDDS.cpp b/DirectXTex/DirectXTexDDS.cpp index bdb50bd..b6fe1b0 100644 --- a/DirectXTex/DirectXTexDDS.cpp +++ b/DirectXTex/DirectXTexDDS.cpp @@ -369,8 +369,10 @@ namespace } metadata.mipLevels = pHeader->mipMapCount; - if (metadata.mipLevels == 0) + if ((metadata.mipLevels == 0) || (flags & DDS_FLAGS_IGNORE_MIPS)) + { metadata.mipLevels = 1; + } // Check for DX10 extension if ((pHeader->ddspf.flags & DDS_FOURCC) diff --git a/Texconv/texconv.cpp b/Texconv/texconv.cpp index 6b3b815..360f28b 100644 --- a/Texconv/texconv.cpp +++ b/Texconv/texconv.cpp @@ -110,6 +110,7 @@ namespace OPT_DDS_DWORD_ALIGN, OPT_DDS_BAD_DXTN_TAILS, OPT_DDS_PERMISSIVE, + OPT_DDS_IGNORE_MIPS, OPT_USE_DX10, OPT_USE_DX9, OPT_TGA20, @@ -211,6 +212,7 @@ namespace { L"dword", OPT_DDS_DWORD_ALIGN }, { L"badtails", OPT_DDS_BAD_DXTN_TAILS }, { L"permissive", OPT_DDS_PERMISSIVE }, + { L"ignoremips", OPT_DDS_IGNORE_MIPS }, { L"dx10", OPT_USE_DX10 }, { L"dx9", OPT_USE_DX9 }, { L"tga20", OPT_TGA20 }, @@ -1013,6 +1015,7 @@ namespace L" -dword Use DWORD instead of BYTE alignment\n" L" -badtails Fix for older DXTn with bad mipchain tails\n" L" -permissive Allow some DX9 variants with unusual header values\n" + L" -ignoremips Reads just the top-level mip which reads some invalid files\n" L" -fixbc4x4 Fix for odd-sized BC files that Direct3D can't load\n" L" -xlum expand legacy L8, L16, and A8P8 formats\n" L"\n" @@ -2240,6 +2243,8 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) ddsFlags |= DDS_FLAGS_BAD_DXTN_TAILS; if (dwOptions & (uint64_t(1) << OPT_DDS_PERMISSIVE)) ddsFlags |= DDS_FLAGS_PERMISSIVE; + if (dwOptions & (uint64_t(1) << OPT_DDS_IGNORE_MIPS)) + ddsFlags |= DDS_FLAGS_IGNORE_MIPS; hr = LoadFromDDSFile(curpath.c_str(), ddsFlags, &info, *image); } diff --git a/Texdiag/texdiag.cpp b/Texdiag/texdiag.cpp index cfdfe4c..dc9c224 100644 --- a/Texdiag/texdiag.cpp +++ b/Texdiag/texdiag.cpp @@ -91,6 +91,8 @@ enum OPTIONS : uint32_t OPT_FILTER, OPT_DDS_DWORD_ALIGN, OPT_DDS_BAD_DXTN_TAILS, + OPT_DDS_PERMISSIVE, + OPT_DDS_IGNORE_MIPS, OPT_OUTPUTFILE, OPT_TOLOWER, OPT_OVERWRITE, @@ -137,25 +139,27 @@ const SValue g_pCommands[] = const SValue g_pOptions[] = { - { L"r", OPT_RECURSIVE }, - { L"f", OPT_FORMAT }, - { L"if", OPT_FILTER }, - { L"dword", OPT_DDS_DWORD_ALIGN }, - { L"badtails", OPT_DDS_BAD_DXTN_TAILS }, - { L"nologo", OPT_NOLOGO }, - { L"o", OPT_OUTPUTFILE }, - { L"l", OPT_TOLOWER }, - { L"y", OPT_OVERWRITE }, - { L"ft", OPT_FILETYPE }, - { L"tu", OPT_TYPELESS_UNORM }, - { L"tf", OPT_TYPELESS_FLOAT }, - { L"xlum", OPT_EXPAND_LUMINANCE }, - { L"targetx", OPT_TARGET_PIXELX }, - { L"targety", OPT_TARGET_PIXELY }, - { L"c", OPT_DIFF_COLOR }, - { L"t", OPT_THRESHOLD }, - { L"flist", OPT_FILELIST }, - { nullptr, 0 } + { L"r", OPT_RECURSIVE }, + { L"f", OPT_FORMAT }, + { L"if", OPT_FILTER }, + { L"dword", OPT_DDS_DWORD_ALIGN }, + { L"badtails", OPT_DDS_BAD_DXTN_TAILS }, + { L"permissive", OPT_DDS_PERMISSIVE }, + { L"ignoremips", OPT_DDS_IGNORE_MIPS }, + { L"nologo", OPT_NOLOGO }, + { L"o", OPT_OUTPUTFILE }, + { L"l", OPT_TOLOWER }, + { L"y", OPT_OVERWRITE }, + { L"ft", OPT_FILETYPE }, + { L"tu", OPT_TYPELESS_UNORM }, + { L"tf", OPT_TYPELESS_FLOAT }, + { L"xlum", OPT_EXPAND_LUMINANCE }, + { L"targetx", OPT_TARGET_PIXELX }, + { L"targety", OPT_TARGET_PIXELY }, + { L"c", OPT_DIFF_COLOR }, + { L"t", OPT_THRESHOLD }, + { L"flist", OPT_FILELIST }, + { nullptr, 0 } }; #define DEFFMT(fmt) { L## #fmt, DXGI_FORMAT_ ## fmt } @@ -706,6 +710,8 @@ namespace L" -t{u|f} TYPELESS format is treated as UNORM or FLOAT\n" L" -dword Use DWORD instead of BYTE alignment\n" L" -badtails Fix for older DXTn with bad mipchain tails\n" + L" -permissive Allow some DX9 variants with unusual header values\n" + L" -ignoremips Reads just the top-level mip which reads some invalid files\n" L" -xlum expand legacy L8, L16, and A8P8 formats\n" L"\n" L" (diff only)\n" @@ -805,6 +811,10 @@ namespace ddsFlags |= DDS_FLAGS_EXPAND_LUMINANCE; if (dwOptions & (1 << OPT_DDS_BAD_DXTN_TAILS)) ddsFlags |= DDS_FLAGS_BAD_DXTN_TAILS; + if (dwOptions & (1 << OPT_DDS_PERMISSIVE)) + ddsFlags |= DDS_FLAGS_PERMISSIVE; + if (dwOptions & (1 << OPT_DDS_IGNORE_MIPS)) + ddsFlags |= DDS_FLAGS_IGNORE_MIPS; HRESULT hr = LoadFromDDSFile(fileName, ddsFlags, &info, *image); if (FAILED(hr))