diff --git a/Core/DDSTextureLoader.cpp b/Core/DDSTextureLoader.cpp index b71414d..6b805df 100644 --- a/Core/DDSTextureLoader.cpp +++ b/Core/DDSTextureLoader.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -43,6 +44,8 @@ using namespace DirectX; // // See DDS.h in the 'Texconv' sample and the 'DirectXTex' library //-------------------------------------------------------------------------------------- +namespace +{ #pragma pack(push,1) constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS " @@ -116,9 +119,15 @@ struct DDS_HEADER_DXT10 #pragma pack(pop) + static_assert(sizeof(DDS_PIXELFORMAT) == 32, "DDS pixel format size mismatch"); + static_assert(sizeof(DDS_HEADER) == 124, "DDS Header size mismatch"); + static_assert(sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch"); + + constexpr size_t DDS_MIN_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER); + constexpr size_t DDS_DX10_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); + static_assert(DDS_DX10_HEADER_SIZE > DDS_MIN_HEADER_SIZE, "DDS DX10 Header should be larger than standard header"); + //-------------------------------------------------------------------------------------- -namespace -{ struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } }; using ScopedHandle = std::unique_ptr; @@ -134,8 +143,7 @@ namespace #else template inline void SetDebugObjectName(_In_ ID3D11DeviceChild*, _In_ const char(&)[TNameLength]) noexcept - { - } + {} #endif //-------------------------------------------------------------------------------------- @@ -158,13 +166,13 @@ namespace return E_FAIL; } - if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) + if (ddsDataSize < DDS_MIN_HEADER_SIZE) { return E_FAIL; } // DDS files always start with the same magic number ("DDS ") - auto const dwMagicNumber = *reinterpret_cast(ddsData); + const auto dwMagicNumber = *reinterpret_cast(ddsData); if (dwMagicNumber != DDS_MAGIC) { return E_FAIL; @@ -185,7 +193,7 @@ namespace (MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC)) { // Must be long enough for both headers and magic value - if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10))) + if (ddsDataSize < DDS_DX10_HEADER_SIZE) { return E_FAIL; } @@ -195,8 +203,7 @@ namespace // setup the pointers in the process request *header = hdr; - auto offset = sizeof(uint32_t) - + sizeof(DDS_HEADER) + auto offset = DDS_MIN_HEADER_SIZE + (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0u); *bitData = ddsData + offset; *bitSize = ddsDataSize - offset; @@ -254,7 +261,7 @@ namespace } // Need at least enough data to fill the header and magic number to be a valid DDS - if (fileInfo.EndOfFile.LowPart < (sizeof(uint32_t) + sizeof(DDS_HEADER))) + if (fileInfo.EndOfFile.LowPart < DDS_MIN_HEADER_SIZE) { return E_FAIL; } @@ -286,7 +293,7 @@ namespace } // DDS files always start with the same magic number ("DDS ") - auto const dwMagicNumber = *reinterpret_cast(ddsData.get()); + const auto dwMagicNumber = *reinterpret_cast(ddsData.get()); if (dwMagicNumber != DDS_MAGIC) { ddsData.reset(); @@ -309,7 +316,7 @@ namespace (MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC)) { // Must be long enough for both headers and magic value - if (fileInfo.EndOfFile.LowPart < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10))) + if (fileInfo.EndOfFile.LowPart < DDS_DX10_HEADER_SIZE) { ddsData.reset(); return E_FAIL; @@ -320,7 +327,7 @@ namespace // setup the pointers in the process request *header = hdr; - auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER) + auto offset = DDS_MIN_HEADER_SIZE + (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0u); *bitData = ddsData.get() + offset; *bitSize = fileInfo.EndOfFile.LowPart - offset; @@ -484,7 +491,7 @@ namespace _In_ size_t width, _In_ size_t height, _In_ DXGI_FORMAT fmt, - size_t* outNumBytes, + _Out_opt_ size_t* outNumBytes, _Out_opt_ size_t* outRowBytes, _Out_opt_ size_t* outNumRows) noexcept { @@ -498,6 +505,9 @@ namespace size_t bpe = 0; switch (fmt) { + case DXGI_FORMAT_UNKNOWN: + return E_INVALIDARG; + case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: @@ -551,6 +561,15 @@ namespace bpe = 2; break; + #if (_WIN32_WINNT >= _WIN32_WINNT_WIN10) + + case DXGI_FORMAT_P208: + planar = true; + bpe = 2; + break; + + #endif + case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: if ((height % 2) != 0) @@ -1731,7 +1750,7 @@ namespace if (MAKEFOURCC('D', 'X', '1', '0') == header->ddspf.fourCC) { auto d3d10ext = reinterpret_cast(reinterpret_cast(header) + sizeof(DDS_HEADER)); - auto const mode = static_cast(d3d10ext->miscFlags2 & DDS_MISC_FLAGS2_ALPHA_MODE_MASK); + const auto mode = static_cast(d3d10ext->miscFlags2 & DDS_MISC_FLAGS2_ALPHA_MODE_MASK); switch (mode) { case DDS_ALPHA_MODE_STRAIGHT: diff --git a/Core/ScreenGrab.cpp b/Core/ScreenGrab.cpp index 522e8f1..be3c1c8 100644 --- a/Core/ScreenGrab.cpp +++ b/Core/ScreenGrab.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +63,7 @@ namespace { #pragma pack(push,1) -#define DDS_MAGIC 0x20534444 // "DDS " + constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS " struct DDS_PIXELFORMAT { @@ -120,6 +121,14 @@ namespace #pragma pack(pop) + static_assert(sizeof(DDS_PIXELFORMAT) == 32, "DDS pixel format size mismatch"); + static_assert(sizeof(DDS_HEADER) == 124, "DDS Header size mismatch"); + static_assert(sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch"); + + constexpr size_t DDS_MIN_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER); + constexpr size_t DDS_DX10_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); + static_assert(DDS_DX10_HEADER_SIZE > DDS_MIN_HEADER_SIZE, "DDS DX10 Header should be larger than standard header"); + const DDS_PIXELFORMAT DDSPF_DXT1 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }; @@ -807,13 +816,13 @@ HRESULT DirectX::SaveDDSTextureToFile( auto_delete_file delonfail(hFile.get()); // Setup header - constexpr size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); - uint8_t fileHeader[MAX_HEADER_SIZE] = {}; + uint8_t fileHeader[DDS_DX10_HEADER_SIZE] = {}; + *reinterpret_cast(&fileHeader[0]) = DDS_MAGIC; auto header = reinterpret_cast(&fileHeader[0] + sizeof(uint32_t)); - size_t headerSize = sizeof(uint32_t) + sizeof(DDS_HEADER); + size_t headerSize = DDS_MIN_HEADER_SIZE; header->size = sizeof(DDS_HEADER); header->flags = DDS_HEADER_FLAGS_TEXTURE | DDS_HEADER_FLAGS_MIPMAP; header->height = desc.Height; @@ -870,7 +879,7 @@ HRESULT DirectX::SaveDDSTextureToFile( memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT)); headerSize += sizeof(DDS_HEADER_DXT10); - extHeader = reinterpret_cast(fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER)); + extHeader = reinterpret_cast(fileHeader + DDS_MIN_HEADER_SIZE); extHeader->dxgiFormat = desc.Format; extHeader->resourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D; extHeader->arraySize = 1; diff --git a/Core/ScreenGrab.h b/Core/ScreenGrab.h index f8d055d..f8aa771 100644 --- a/Core/ScreenGrab.h +++ b/Core/ScreenGrab.h @@ -41,6 +41,6 @@ namespace DirectX _In_ REFGUID guidContainerFormat, _In_z_ const wchar_t* fileName, _In_opt_ const GUID* targetFormat = nullptr, - std::function setCustomProps = nullptr, + _In_ std::function setCustomProps = nullptr, _In_ bool forceSRGB = false); } diff --git a/Core/WICTextureLoader.cpp b/Core/WICTextureLoader.cpp index a09fb85..8e14e68 100644 --- a/Core/WICTextureLoader.cpp +++ b/Core/WICTextureLoader.cpp @@ -64,8 +64,7 @@ namespace #else template inline void SetDebugObjectName(_In_ ID3D11DeviceChild*, _In_ const char(&)[TNameLength]) noexcept - { - } + {} #endif //------------------------------------------------------------------------------------- @@ -78,7 +77,8 @@ namespace constexpr WICTranslate(const GUID& wg, DXGI_FORMAT fmt) noexcept : wic(wg), - format(fmt) {} + format(fmt) + {} }; constexpr WICTranslate g_WICFormats[] = @@ -116,7 +116,8 @@ namespace constexpr WICConvert(const GUID& src, const GUID& tgt) noexcept : source(src), - target(tgt) {} + target(tgt) + {} }; constexpr WICConvert g_WICConvert[] = @@ -594,8 +595,8 @@ namespace if (rowBytes > UINT32_MAX || numBytes > UINT32_MAX) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); - auto const rowPitch = static_cast(rowBytes); - auto const imageSize = static_cast(numBytes); + const auto rowPitch = static_cast(rowBytes); + const auto imageSize = static_cast(numBytes); std::unique_ptr temp(new (std::nothrow) uint8_t[imageSize]); if (!temp)