From 5a8a88140826313bda31914f10720eca55ffe22d Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Thu, 20 Feb 2025 11:20:43 -0800 Subject: [PATCH] Support loading another DX10 DDS variant with permissive --- DirectXTex/DirectXTexDDS.cpp | 50 +++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/DirectXTex/DirectXTexDDS.cpp b/DirectXTex/DirectXTexDDS.cpp index 4533eca2..bbda42f9 100644 --- a/DirectXTex/DirectXTexDDS.cpp +++ b/DirectXTex/DirectXTexDDS.cpp @@ -2006,10 +2006,36 @@ HRESULT DirectX::LoadFromDDSMemoryEx( return E_FAIL; } + size_t remaining = size - offset; + if (remaining == 0) + return E_FAIL; + hr = image.Initialize(mdata); if (FAILED(hr)) return hr; + if (flags & DDS_FLAGS_PERMISSIVE) + { + // For cubemaps, DDS_HEADER_DXT10.arraySize is supposed to be 'number of cubes'. + // This handles cases where the value is incorrectly written as the original 6*numCubes value. + if ((mdata.miscFlags & TEX_MISC_TEXTURECUBE) + && (convFlags & CONV_FLAGS_DX10) + && (image.GetPixelsSize() > remaining) + && ((mdata.arraySize % 6) == 0)) + { + mdata.arraySize = mdata.arraySize / 6; + hr = image.Initialize(mdata); + if (FAILED(hr)) + return hr; + + if (image.GetPixelsSize() > remaining) + { + image.Release(); + return HRESULT_E_HANDLE_EOF; + } + } + } + CP_FLAGS cflags = CP_FLAGS_NONE; if (flags & DDS_FLAGS_LEGACY_DWORD) { @@ -2195,6 +2221,28 @@ HRESULT DirectX::LoadFromDDSFileEx( if (FAILED(hr)) return hr; + if (flags & DDS_FLAGS_PERMISSIVE) + { + // For cubemaps, DDS_HEADER_DXT10.arraySize is supposed to be 'number of cubes'. + // This handles cases where the value is incorrectly written as the original 6*numCubes value. + if ((mdata.miscFlags & TEX_MISC_TEXTURECUBE) + && (convFlags & CONV_FLAGS_DX10) + && (image.GetPixelsSize() > remaining) + && ((mdata.arraySize % 6) == 0)) + { + mdata.arraySize = mdata.arraySize / 6; + hr = image.Initialize(mdata); + if (FAILED(hr)) + return hr; + + if (image.GetPixelsSize() > remaining) + { + image.Release(); + return HRESULT_E_HANDLE_EOF; + } + } + } + if ((convFlags & CONV_FLAGS_EXPAND) || (flags & (DDS_FLAGS_LEGACY_DWORD | DDS_FLAGS_BAD_DXTN_TAILS))) { std::unique_ptr temp(new (std::nothrow) uint8_t[remaining]); @@ -2370,7 +2418,7 @@ HRESULT DirectX::SaveToDDSMemory( size_t remaining = blob.GetBufferSize() - required; pDestination += required; - if (!remaining) + if (remaining == 0) { blob.Release(); return E_FAIL;