diff --git a/DirectXTex/DDS.h b/DirectXTex/DDS.h index a88f14a..cce220c 100644 --- a/DirectXTex/DDS.h +++ b/DirectXTex/DDS.h @@ -284,6 +284,7 @@ namespace DirectX #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"); diff --git a/DirectXTex/DirectXTex.h b/DirectXTex/DirectXTex.h index c8c9099..77d8c71 100644 --- a/DirectXTex/DirectXTex.h +++ b/DirectXTex/DirectXTex.h @@ -187,6 +187,20 @@ namespace DirectX // Helper for dimension }; + struct DDSMetaData + { + uint32_t size; // DDPIXELFORMAT.dwSize + uint32_t flags; // DDPIXELFORMAT.dwFlags + uint32_t fourCC; // DDPIXELFORMAT.dwFourCC + uint32_t RGBBitCount; // DDPIXELFORMAT.dwRGBBitCount/dwYUVBitCount/dwAlphaBitDepth/dwLuminanceBitCount/dwBumpBitCount + uint32_t RBitMask; // DDPIXELFORMAT.dwRBitMask/dwYBitMask/dwLuminanceBitMask/dwBumpDuBitMask + uint32_t GBitMask; // DDPIXELFORMAT.dwGBitMask/dwUBitMask/dwBumpDvBitMask + uint32_t BBitMask; // DDPIXELFORMAT.dwBBitMask/dwVBitMask/dwBumpLuminanceBitMask + uint32_t ABitMask; // DDPIXELFORMAT.dwRGBAlphaBitMask/dwYUVAlphaBitMask/dwLuminanceAlphaBitMask + + bool __cdecl IsDX10() const noexcept { return (fourCC == 0x30315844); } + }; + enum DDS_FLAGS : unsigned long { DDS_FLAGS_NONE = 0x0, @@ -304,6 +318,17 @@ namespace DirectX _In_ DDS_FLAGS flags, _Out_ TexMetadata& metadata) noexcept; + HRESULT __cdecl GetMetadataFromDDSMemoryEx( + _In_reads_bytes_(size) const void* pSource, _In_ size_t size, + _In_ DDS_FLAGS flags, + _Out_ TexMetadata& metadata, + _Out_opt_ DDSMetaData* ddPixelFormat) noexcept; + HRESULT __cdecl GetMetadataFromDDSFileEx( + _In_z_ const wchar_t* szFile, + _In_ DDS_FLAGS flags, + _Out_ TexMetadata& metadata, + _Out_opt_ DDSMetaData* ddPixelFormat) noexcept; + HRESULT __cdecl GetMetadataFromHDRMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _Out_ TexMetadata& metadata) noexcept; @@ -448,6 +473,19 @@ namespace DirectX _In_ DDS_FLAGS flags, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image) noexcept; + HRESULT __cdecl LoadFromDDSMemoryEx( + _In_reads_bytes_(size) const void* pSource, _In_ size_t size, + _In_ DDS_FLAGS flags, + _Out_opt_ TexMetadata* metadata, + _Out_opt_ DDSMetaData* ddPixelFormat, + _Out_ ScratchImage& image) noexcept; + HRESULT __cdecl LoadFromDDSFileEx( + _In_z_ const wchar_t* szFile, + _In_ DDS_FLAGS flags, + _Out_opt_ TexMetadata* metadata, + _Out_opt_ DDSMetaData* ddPixelFormat, + _Out_ ScratchImage& image) noexcept; + HRESULT __cdecl SaveToDDSMemory( _In_ const Image& image, _In_ DDS_FLAGS flags, diff --git a/DirectXTex/DirectXTexDDS.cpp b/DirectXTex/DirectXTexDDS.cpp index 36e3f87..81b3682 100644 --- a/DirectXTex/DirectXTexDDS.cpp +++ b/DirectXTex/DirectXTexDDS.cpp @@ -314,12 +314,17 @@ namespace size_t size, DDS_FLAGS flags, _Out_ TexMetadata& metadata, + _Out_opt_ DDSMetaData* ddPixelFormat, _Inout_ uint32_t& convFlags) noexcept { if (!pSource) return E_INVALIDARG; - memset(&metadata, 0, sizeof(TexMetadata)); + metadata = {}; + if (ddPixelFormat) + { + *ddPixelFormat = {}; + } if (size < (sizeof(DDS_HEADER) + sizeof(uint32_t))) { @@ -594,6 +599,19 @@ namespace } } + // Handle DDS-specific metadata + if (ddPixelFormat) + { + ddPixelFormat->size = pHeader->ddspf.size; + ddPixelFormat->flags = pHeader->ddspf.flags; + ddPixelFormat->fourCC = pHeader->ddspf.fourCC; + ddPixelFormat->RGBBitCount = pHeader->ddspf.RGBBitCount; + ddPixelFormat->RBitMask = pHeader->ddspf.RBitMask; + ddPixelFormat->GBitMask = pHeader->ddspf.GBitMask; + ddPixelFormat->BBitMask = pHeader->ddspf.BBitMask; + ddPixelFormat->ABitMask = pHeader->ddspf.ABitMask; + } + return S_OK; } } @@ -1632,12 +1650,23 @@ HRESULT DirectX::GetMetadataFromDDSMemory( size_t size, DDS_FLAGS flags, TexMetadata& metadata) noexcept +{ + return GetMetadataFromDDSMemoryEx(pSource, size, flags, metadata, nullptr); +} + +_Use_decl_annotations_ +HRESULT DirectX::GetMetadataFromDDSMemoryEx( + const void* pSource, + size_t size, + DDS_FLAGS flags, + TexMetadata& metadata, + DDSMetaData* ddPixelFormat) noexcept { if (!pSource || size == 0) return E_INVALIDARG; uint32_t convFlags = 0; - return DecodeDDSHeader(pSource, size, flags, metadata, convFlags); + return DecodeDDSHeader(pSource, size, flags, metadata, ddPixelFormat, convFlags); } _Use_decl_annotations_ @@ -1645,6 +1674,16 @@ HRESULT DirectX::GetMetadataFromDDSFile( const wchar_t* szFile, DDS_FLAGS flags, TexMetadata& metadata) noexcept +{ + return GetMetadataFromDDSFileEx(szFile, flags, metadata, nullptr); +} + +_Use_decl_annotations_ +HRESULT DirectX::GetMetadataFromDDSFileEx( + const wchar_t* szFile, + DDS_FLAGS flags, + TexMetadata& metadata, + DDSMetaData* ddPixelFormat) noexcept { if (!szFile) return E_INVALIDARG; @@ -1720,7 +1759,7 @@ HRESULT DirectX::GetMetadataFromDDSFile( #endif uint32_t convFlags = 0; - return DecodeDDSHeader(header, headerLen, flags, metadata, convFlags); + return DecodeDDSHeader(header, headerLen, flags, metadata, ddPixelFormat, convFlags); } @@ -1734,6 +1773,18 @@ HRESULT DirectX::LoadFromDDSMemory( DDS_FLAGS flags, TexMetadata* metadata, ScratchImage& image) noexcept +{ + return LoadFromDDSMemoryEx(pSource, size, flags, metadata, nullptr, image); +} + +_Use_decl_annotations_ +HRESULT DirectX::LoadFromDDSMemoryEx( + const void* pSource, + size_t size, + DDS_FLAGS flags, + TexMetadata* metadata, + DDSMetaData* ddPixelFormat, + ScratchImage& image) noexcept { if (!pSource || size == 0) return E_INVALIDARG; @@ -1742,7 +1793,7 @@ HRESULT DirectX::LoadFromDDSMemory( uint32_t convFlags = 0; TexMetadata mdata; - HRESULT hr = DecodeDDSHeader(pSource, size, flags, mdata, convFlags); + HRESULT hr = DecodeDDSHeader(pSource, size, flags, mdata, ddPixelFormat, convFlags); if (FAILED(hr)) return hr; @@ -1806,6 +1857,17 @@ HRESULT DirectX::LoadFromDDSFile( DDS_FLAGS flags, TexMetadata* metadata, ScratchImage& image) noexcept +{ + return LoadFromDDSFileEx(szFile, flags, metadata, nullptr, image); +} + +_Use_decl_annotations_ +HRESULT DirectX::LoadFromDDSFileEx( + const wchar_t* szFile, + DDS_FLAGS flags, + TexMetadata* metadata, + DDSMetaData* ddPixelFormat, + ScratchImage& image) noexcept { if (!szFile) return E_INVALIDARG; @@ -1882,7 +1944,7 @@ HRESULT DirectX::LoadFromDDSFile( uint32_t convFlags = 0; TexMetadata mdata; - HRESULT hr = DecodeDDSHeader(header, headerLen, flags, mdata, convFlags); + HRESULT hr = DecodeDDSHeader(header, headerLen, flags, mdata, ddPixelFormat, convFlags); if (FAILED(hr)) return hr;