From 06a121f7cf6658ea3989b3478b6275ce8c1c7b6d Mon Sep 17 00:00:00 2001 From: mo Date: Mon, 19 Oct 2026 11:11:10 +0100 Subject: [PATCH] fix: distinguish DDS formats by pixel bit depth (#1048) Match bit depth as well as channel masks. --- src/ObjImage/Image/DdsLoader.cpp | 7 +++-- test/ObjCommonTests/Image/DdsLoaderTests.cpp | 32 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 test/ObjCommonTests/Image/DdsLoaderTests.cpp diff --git a/src/ObjImage/Image/DdsLoader.cpp b/src/ObjImage/Image/DdsLoader.cpp index 8126ef92..fc8af93a 100644 --- a/src/ObjImage/Image/DdsLoader.cpp +++ b/src/ObjImage/Image/DdsLoader.cpp @@ -172,9 +172,10 @@ namespace const auto* unsignedImageFormat = dynamic_cast(imageFormat); - if (unsignedImageFormat->m_r_offset == rOffset && unsignedImageFormat->m_r_size == rSize && unsignedImageFormat->m_g_offset == gOffset - && unsignedImageFormat->m_g_size == gSize && unsignedImageFormat->m_b_offset == bOffset && unsignedImageFormat->m_b_size == bSize - && unsignedImageFormat->m_a_offset == aOffset && unsignedImageFormat->m_a_size == aSize) + if (unsignedImageFormat->m_bits_per_pixel == pf.dwRGBBitCount && unsignedImageFormat->m_r_offset == rOffset + && unsignedImageFormat->m_r_size == rSize && unsignedImageFormat->m_g_offset == gOffset && unsignedImageFormat->m_g_size == gSize + && unsignedImageFormat->m_b_offset == bOffset && unsignedImageFormat->m_b_size == bSize && unsignedImageFormat->m_a_offset == aOffset + && unsignedImageFormat->m_a_size == aSize) { m_format = imageFormat; return true; diff --git a/test/ObjCommonTests/Image/DdsLoaderTests.cpp b/test/ObjCommonTests/Image/DdsLoaderTests.cpp new file mode 100644 index 00000000..f6dc6fd3 --- /dev/null +++ b/test/ObjCommonTests/Image/DdsLoaderTests.cpp @@ -0,0 +1,32 @@ +#include "Image/DdsLoader.h" +#include "Image/DdsWriter.h" +#include "Image/Texture.h" + +#include +#include +#include +#include + +TEST_CASE("DDS loading distinguishes BGR pixel strides with identical channel masks", "[image][dds]") +{ + const auto* format = GENERATE(&image::format::B8_G8_R8, &image::format::B8_G8_R8_X8); + image::Texture2D source(format, 4, 4, true); + source.Allocate(); + for (auto mip = 0; mip < source.GetMipMapCount(); ++mip) + for (auto i = 0uz; i < source.GetSizeOfMipLevel(mip); ++i) + source.GetBufferForMipLevel(mip, 0)[i] = static_cast(i * 13 + mip); + + std::stringstream file(std::ios::in | std::ios::out | std::ios::binary); + image::DdsWriter writer; + writer.DumpImage(file, &source); + file.seekg(0); + const auto loaded = image::LoadDds(file); + REQUIRE(loaded); + REQUIRE(loaded->GetFormat()->GetId() == format->GetId()); + REQUIRE(loaded->GetMipMapCount() == source.GetMipMapCount()); + for (auto mip = 0; mip < source.GetMipMapCount(); ++mip) + { + REQUIRE(loaded->GetSizeOfMipLevel(mip) == source.GetSizeOfMipLevel(mip)); + CHECK(std::memcmp(loaded->GetBufferForMipLevel(mip), source.GetBufferForMipLevel(mip, 0), source.GetSizeOfMipLevel(mip)) == 0); + } +}