DDS_FLAGS_PERMISSIVE flag to allow some file variants with header bugs (#394)

This commit is contained in:
Chuck Walbourn 2023-09-11 23:13:35 -07:00 коммит произвёл GitHub
Родитель 41eb26fb0c
Коммит 3754a77d87
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 34 добавлений и 4 удалений

Просмотреть файл

@ -226,6 +226,9 @@ namespace DirectX
DDS_FLAGS_BAD_DXTN_TAILS = 0x40,
// Some older DXTn DDS files incorrectly handle mipchain tails for blocks smaller than 4x4
DDS_FLAGS_PERMISSIVE = 0x80,
// Allow some file variants due to common bugs in the header written by various leagcy DDS writers
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)

Просмотреть файл

@ -346,11 +346,18 @@ namespace
return E_FAIL;
}
if (pHeader->ddspf.size != 0 /* Known variant */
&& pHeader->ddspf.size != 24 /* Known variant */
&& pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT))
if (flags & DDS_FLAGS_PERMISSIVE)
{
return E_FAIL;
if (pHeader->ddspf.size != 0 /* Known variant */
&& pHeader->ddspf.size != 24 /* Known variant */
&& pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT))
{
return HRESULT_E_NOT_SUPPORTED;
}
}
else if (pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT))
{
return HRESULT_E_NOT_SUPPORTED;
}
metadata.mipLevels = pHeader->mipMapCount;
@ -460,6 +467,14 @@ namespace
metadata.height = pHeader->height;
metadata.depth = pHeader->depth;
metadata.dimension = TEX_DIMENSION_TEXTURE3D;
if (flags & DDS_FLAGS_PERMISSIVE)
{
// Allow cases where mipCount was computed incorrectly
size_t maxMips = 0;
std::ignore = Internal::CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, maxMips);
metadata.mipLevels = std::min(metadata.mipLevels, maxMips);
}
}
else
{
@ -479,6 +494,14 @@ namespace
metadata.dimension = TEX_DIMENSION_TEXTURE2D;
// Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
if (flags & DDS_FLAGS_PERMISSIVE)
{
// Allow cases where mipCount was computed incorrectly
size_t maxMips = 0;
std::ignore = Internal::CalculateMipLevels(metadata.width, metadata.height, maxMips);
metadata.mipLevels = std::min(metadata.mipLevels, maxMips);
}
}
metadata.format = GetDXGIFormat(*pHeader, pHeader->ddspf, flags, convFlags);

Просмотреть файл

@ -94,6 +94,7 @@ namespace
OPT_VFLIP,
OPT_DDS_DWORD_ALIGN,
OPT_DDS_BAD_DXTN_TAILS,
OPT_DDS_PERMISSIVE,
OPT_USE_DX10,
OPT_USE_DX9,
OPT_TGA20,
@ -190,6 +191,7 @@ namespace
{ L"vflip", OPT_VFLIP },
{ L"dword", OPT_DDS_DWORD_ALIGN },
{ L"badtails", OPT_DDS_BAD_DXTN_TAILS },
{ L"permissive", OPT_DDS_PERMISSIVE },
{ L"dx10", OPT_USE_DX10 },
{ L"dx9", OPT_USE_DX9 },
{ L"tga20", OPT_TGA20 },
@ -2104,6 +2106,8 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
ddsFlags |= DDS_FLAGS_EXPAND_LUMINANCE;
if (dwOptions & (uint64_t(1) << OPT_DDS_BAD_DXTN_TAILS))
ddsFlags |= DDS_FLAGS_BAD_DXTN_TAILS;
if (dwOptions & (uint64_t(1) << OPT_DDS_PERMISSIVE))
ddsFlags |= DDS_FLAGS_PERMISSIVE;
hr = LoadFromDDSFile(curpath.c_str(), ddsFlags, &info, *image);
if (FAILED(hr))