1
0
mirror of https://github.com/microsoft/DirectXTex synced 2024-11-12 15:50:08 +00:00

Support for Windows Subsystem for Linux (#208)

This commit is contained in:
Chuck Walbourn 2021-01-08 02:20:55 -08:00 committed by GitHub
parent 705a8e3766
commit 234eee8a01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1101 additions and 379 deletions

7
.gitignore vendored
View File

@ -18,7 +18,7 @@
*.VC.db *.VC.db
*.nupkg *.nupkg
.vs .vs
Bin [Bb]in
packages packages
/DirectXTex/Shaders/Compiled/*.inc /DirectXTex/Shaders/Compiled/*.inc
/DirectXTex/Shaders/Compiled/*.pdb /DirectXTex/Shaders/Compiled/*.pdb
@ -34,3 +34,8 @@ x64
/Tests /Tests
/wiki /wiki
/out /out
/CMakeCache.txt
/CMakeFiles
/Makefile
/cmake
/cmake_install.cmake

View File

@ -53,7 +53,6 @@ set(LIBRARY_SOURCES
DirectXTex/DirectXTexCompress.cpp DirectXTex/DirectXTexCompress.cpp
DirectXTex/DirectXTexConvert.cpp DirectXTex/DirectXTexConvert.cpp
DirectXTex/DirectXTexDDS.cpp DirectXTex/DirectXTexDDS.cpp
DirectXTex/DirectXTexFlipRotate.cpp
DirectXTex/DirectXTexHDR.cpp DirectXTex/DirectXTexHDR.cpp
DirectXTex/DirectXTexImage.cpp DirectXTex/DirectXTexImage.cpp
DirectXTex/DirectXTexMipmaps.cpp DirectXTex/DirectXTexMipmaps.cpp
@ -62,20 +61,26 @@ set(LIBRARY_SOURCES
DirectXTex/DirectXTexPMAlpha.cpp DirectXTex/DirectXTexPMAlpha.cpp
DirectXTex/DirectXTexResize.cpp DirectXTex/DirectXTexResize.cpp
DirectXTex/DirectXTexTGA.cpp DirectXTex/DirectXTexTGA.cpp
DirectXTex/DirectXTexUtil.cpp DirectXTex/DirectXTexUtil.cpp)
DirectXTex/DirectXTexWIC.cpp)
if(WIN32)
set(LIBRARY_SOURCES ${LIBRARY_SOURCES}
DirectXTex/DirectXTexFlipRotate.cpp
DirectXTex/DirectXTexWIC.cpp)
endif()
set(SHADER_SOURCES set(SHADER_SOURCES
DirectXTex/Shaders/BC6HEncode.hlsl DirectXTex/Shaders/BC6HEncode.hlsl
DirectXTex/Shaders/BC7Encode.hlsl) DirectXTex/Shaders/BC7Encode.hlsl)
if(BUILD_DX11) if(BUILD_DX11 AND WIN32)
set(LIBRARY_SOURCES ${LIBRARY_SOURCES} set(LIBRARY_SOURCES ${LIBRARY_SOURCES}
DirectXTex/BCDirectCompute.h DirectXTex/BCDirectCompute.h
DirectXTex/BCDirectCompute.cpp DirectXTex/BCDirectCompute.cpp
DirectXTex/DirectXTexCompressGPU.cpp DirectXTex/DirectXTexCompressGPU.cpp
DirectXTex/DirectXTexD3D11.cpp) DirectXTex/DirectXTexD3D11.cpp)
endif() endif()
if(BUILD_DX12) if(BUILD_DX12)
set(LIBRARY_SOURCES ${LIBRARY_SOURCES} set(LIBRARY_SOURCES ${LIBRARY_SOURCES}
DirectXTex/d3dx12.h DirectXTex/d3dx12.h
@ -91,7 +96,7 @@ if(ENABLE_OPENEXR_SUPPORT)
DirectXTex/DirectXTexEXR.cpp) DirectXTex/DirectXTexEXR.cpp)
endif() endif()
if(BUILD_DX11) if(BUILD_DX11 AND WIN32)
set(LIBRARY_SOURCES ${LIBRARY_SOURCES} set(LIBRARY_SOURCES ${LIBRARY_SOURCES}
DirectXTex/Shaders/Compiled/BC6HEncode_EncodeBlockCS.inc) DirectXTex/Shaders/Compiled/BC6HEncode_EncodeBlockCS.inc)
@ -134,6 +139,12 @@ if(MSVC)
string(REPLACE "/GR " "/GR- " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) string(REPLACE "/GR " "/GR- " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
endif() endif()
if (NOT WIN32)
find_package(directx-headers CONFIG REQUIRED)
find_package(directxmath CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE Microsoft::DirectX-Headers Microsoft::DirectXMath)
endif()
#--- Package #--- Package
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
@ -168,7 +179,7 @@ install(FILES
DESTINATION cmake/) DESTINATION cmake/)
#--- Command-line tools #--- Command-line tools
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
add_executable(texassemble add_executable(texassemble
Texassemble/texassemble.cpp Texassemble/texassemble.cpp
Texassemble/AnimatedGif.cpp) Texassemble/AnimatedGif.cpp)
@ -199,7 +210,7 @@ endif()
if(MSVC) if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /fp:fast) target_compile_options(${PROJECT_NAME} PRIVATE /fp:fast)
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
target_compile_options(texassemble PRIVATE /fp:fast) target_compile_options(texassemble PRIVATE /fp:fast)
target_compile_options(texconv PRIVATE /fp:fast) target_compile_options(texconv PRIVATE /fp:fast)
target_compile_options(texdiag PRIVATE /fp:fast) target_compile_options(texdiag PRIVATE /fp:fast)
@ -207,7 +218,7 @@ if(MSVC)
if (${CMAKE_SIZEOF_VOID_P} EQUAL "4") if (${CMAKE_SIZEOF_VOID_P} EQUAL "4")
target_compile_options(${PROJECT_NAME} PRIVATE /arch:SSE2) target_compile_options(${PROJECT_NAME} PRIVATE /arch:SSE2)
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
target_compile_options(texassemble PRIVATE /arch:SSE2) target_compile_options(texassemble PRIVATE /arch:SSE2)
target_compile_options(texconv PRIVATE /arch:SSE2) target_compile_options(texconv PRIVATE /arch:SSE2)
target_compile_options(texdiag PRIVATE /arch:SSE2) target_compile_options(texdiag PRIVATE /arch:SSE2)
@ -215,22 +226,22 @@ if(MSVC)
endif() endif()
endif() endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(WarningsLib "-Wpedantic" "-Wextra") set(WarningsLib "-Wpedantic" "-Wextra")
target_compile_options(${PROJECT_NAME} PRIVATE ${WarningsLib}) target_compile_options(${PROJECT_NAME} PRIVATE ${WarningsLib})
# OpenMP is not supported for clang for Windows by default # OpenMP is not supported for clang for Windows by default
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
set(WarningsEXE ${WarningsLib} "-Wno-c++98-compat" "-Wno-c++98-compat-pedantic" "-Wno-switch" "-Wno-switch-enum" "-Wno-language-extension-token" "-Wno-missing-prototypes") set(WarningsEXE ${WarningsLib} "-Wno-c++98-compat" "-Wno-c++98-compat-pedantic" "-Wno-switch" "-Wno-switch-enum" "-Wno-language-extension-token" "-Wno-missing-prototypes")
target_compile_options(texassemble PRIVATE ${WarningsEXE}) target_compile_options(texassemble PRIVATE ${WarningsEXE})
target_compile_options(texconv PRIVATE ${WarningsEXE} "-Wno-global-constructors") target_compile_options(texconv PRIVATE ${WarningsEXE} "-Wno-global-constructors")
target_compile_options(texdiag PRIVATE ${WarningsEXE} "-Wno-double-promotion") target_compile_options(texdiag PRIVATE ${WarningsEXE} "-Wno-double-promotion")
endif() endif()
endif() endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" ) if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(${PROJECT_NAME} PRIVATE /permissive- /JMC- /Zc:__cplusplus) target_compile_options(${PROJECT_NAME} PRIVATE /permissive- /JMC- /Zc:__cplusplus)
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
target_compile_options(texassemble PRIVATE /permissive- /Zc:__cplusplus) target_compile_options(texassemble PRIVATE /permissive- /Zc:__cplusplus)
target_compile_options(texconv PRIVATE /permissive- /Zc:__cplusplus) target_compile_options(texconv PRIVATE /permissive- /Zc:__cplusplus)
target_compile_options(texdiag PRIVATE /permissive- /Zc:__cplusplus) target_compile_options(texdiag PRIVATE /permissive- /Zc:__cplusplus)
@ -238,7 +249,7 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
if(ENABLE_CODE_ANALYSIS) if(ENABLE_CODE_ANALYSIS)
target_compile_options(${PROJECT_NAME} PRIVATE /analyze) target_compile_options(${PROJECT_NAME} PRIVATE /analyze)
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
target_compile_options(texassemble PRIVATE /analyze) target_compile_options(texassemble PRIVATE /analyze)
target_compile_options(texconv PRIVATE /analyze) target_compile_options(texconv PRIVATE /analyze)
target_compile_options(texdiag PRIVATE /analyze) target_compile_options(texdiag PRIVATE /analyze)
@ -247,7 +258,7 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.26) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.26)
target_compile_options(${PROJECT_NAME} PRIVATE /Zc:preprocessor /wd5105) target_compile_options(${PROJECT_NAME} PRIVATE /Zc:preprocessor /wd5105)
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
target_compile_options(texassemble PRIVATE /Zc:preprocessor /wd5105) target_compile_options(texassemble PRIVATE /Zc:preprocessor /wd5105)
target_compile_options(texconv PRIVATE /Zc:preprocessor /wd5105) target_compile_options(texconv PRIVATE /Zc:preprocessor /wd5105)
target_compile_options(texdiag PRIVATE /Zc:preprocessor /wd5105) target_compile_options(texdiag PRIVATE /Zc:preprocessor /wd5105)
@ -256,12 +267,12 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
if(BC_USE_OPENMP) if(BC_USE_OPENMP)
target_compile_options(${PROJECT_NAME} PRIVATE /openmp /Zc:twoPhase-) target_compile_options(${PROJECT_NAME} PRIVATE /openmp /Zc:twoPhase-)
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
target_compile_options(texconv PRIVATE /openmp /Zc:twoPhase-) target_compile_options(texconv PRIVATE /openmp /Zc:twoPhase-)
endif() endif()
endif() endif()
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
set(WarningsEXE "/wd4061" "/wd4062" "/wd4365" "/wd4668" "/wd4710" "/wd4820" "/wd5039" "/wd5045" "/wd5219") set(WarningsEXE "/wd4061" "/wd4062" "/wd4365" "/wd4668" "/wd4710" "/wd4820" "/wd5039" "/wd5045" "/wd5219")
target_compile_options(texassemble PRIVATE ${WarningsEXE}) target_compile_options(texassemble PRIVATE ${WarningsEXE})
target_compile_options(texconv PRIVATE ${WarningsEXE}) target_compile_options(texconv PRIVATE ${WarningsEXE})
@ -284,6 +295,6 @@ if(WIN32)
endif() endif()
endif() endif()
if(BUILD_TOOLS) if(BUILD_TOOLS AND WIN32)
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT texconv) set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT texconv)
endif() endif()

View File

@ -20,6 +20,11 @@
#include <cassert> #include <cassert>
#include <memory> #include <memory>
#ifndef WIN32
#include <fstream>
#include <filesystem>
#endif
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic ignored "-Wtautological-type-limit-compare" #pragma clang diagnostic ignored "-Wtautological-type-limit-compare"
#pragma clang diagnostic ignored "-Wcovered-switch-default" #pragma clang diagnostic ignored "-Wcovered-switch-default"
@ -30,7 +35,12 @@
#pragma warning(disable : 4062) #pragma warning(disable : 4062)
#define D3DX12_NO_STATE_OBJECT_HELPERS #define D3DX12_NO_STATE_OBJECT_HELPERS
#ifdef WIN32
#include "d3dx12.h" #include "d3dx12.h"
#else
#include "directx/d3dx12.h"
#endif
using namespace DirectX; using namespace DirectX;
@ -43,6 +53,18 @@ using namespace DirectX;
((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
#endif /* defined(MAKEFOURCC) */ #endif /* defined(MAKEFOURCC) */
// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)
#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast<HRESULT>(0x80070216L)
// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
#define HRESULT_E_NOT_SUPPORTED static_cast<HRESULT>(0x80070032L)
// HRESULT_FROM_WIN32(ERROR_HANDLE_EOF)
#define HRESULT_E_HANDLE_EOF static_cast<HRESULT>(0x80070026L)
// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
#define HRESULT_E_INVALID_DATA static_cast<HRESULT>(0x8007000DL)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// DDS file structure definitions // DDS file structure definitions
// //
@ -124,11 +146,13 @@ struct DDS_HEADER_DXT10
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
namespace namespace
{ {
#ifdef WIN32
struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } }; struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<void, handle_closer>; using ScopedHandle = std::unique_ptr<void, handle_closer>;
inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; } inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
#endif
template<UINT TNameLength> template<UINT TNameLength>
inline void SetDebugObjectName(_In_ ID3D12DeviceChild* resource, _In_z_ const wchar_t(&name)[TNameLength]) noexcept inline void SetDebugObjectName(_In_ ID3D12DeviceChild* resource, _In_z_ const wchar_t(&name)[TNameLength]) noexcept
@ -239,6 +263,7 @@ namespace
*bitSize = 0; *bitSize = 0;
#ifdef WIN32
// open the file // open the file
ScopedHandle hFile(safe_handle(CreateFile2(fileName, ScopedHandle hFile(safe_handle(CreateFile2(fileName,
GENERIC_READ, GENERIC_READ,
@ -296,6 +321,44 @@ namespace
return E_FAIL; return E_FAIL;
} }
size_t len = fileInfo.EndOfFile.LowPart;
#else // !WIN32
std::ifstream inFile(std::filesystem::path(fileName), std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
return E_FAIL;
std::streampos fileLen = inFile.tellg();
if (!inFile)
return E_FAIL;
// Need at least enough data to fill the header and magic number to be a valid DDS
if (fileLen < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
return E_FAIL;
ddsData.reset(new (std::nothrow) uint8_t[size_t(fileLen)]);
if (!ddsData)
return E_OUTOFMEMORY;
inFile.seekg(0, std::ios::beg);
if (!inFile)
{
ddsData.reset();
return E_FAIL;
}
inFile.read(reinterpret_cast<char*>(ddsData.get()), fileLen);
if (!inFile)
{
ddsData.reset();
return E_FAIL;
}
inFile.close();
size_t len = fileLen;
#endif
// DDS files always start with the same magic number ("DDS ") // DDS files always start with the same magic number ("DDS ")
auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData.get()); auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData.get());
if (dwMagicNumber != DDS_MAGIC) if (dwMagicNumber != DDS_MAGIC)
@ -320,7 +383,7 @@ namespace
(MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC)) (MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC))
{ {
// Must be long enough for both headers and magic value // 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 (len < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10)))
{ {
ddsData.reset(); ddsData.reset();
return E_FAIL; return E_FAIL;
@ -334,7 +397,7 @@ namespace
auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER) auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER)
+ (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0); + (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0);
*bitData = ddsData.get() + offset; *bitData = ddsData.get() + offset;
*bitSize = fileInfo.EndOfFile.LowPart - offset; *bitSize = len - offset;
return S_OK; return S_OK;
} }
@ -619,7 +682,7 @@ namespace
#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64) #if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!"); static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!");
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX) if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
#else #else
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!"); static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
#endif #endif
@ -1037,7 +1100,7 @@ namespace
return hr; return hr;
if (NumBytes > UINT32_MAX || RowBytes > UINT32_MAX) if (NumBytes > UINT32_MAX || RowBytes > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize)) if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize))
{ {
@ -1067,7 +1130,7 @@ namespace
if (pSrcBits + (NumBytes*d) > pEndBits) if (pSrcBits + (NumBytes*d) > pEndBits)
{ {
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); return HRESULT_E_HANDLE_EOF;
} }
pSrcBits += NumBytes * d; pSrcBits += NumBytes * d;
@ -1187,7 +1250,7 @@ namespace
arraySize = d3d10ext->arraySize; arraySize = d3d10ext->arraySize;
if (arraySize == 0) if (arraySize == 0)
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
switch (d3d10ext->dxgiFormat) switch (d3d10ext->dxgiFormat)
@ -1196,12 +1259,12 @@ namespace
case DXGI_FORMAT_IA44: case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8: case DXGI_FORMAT_P8:
case DXGI_FORMAT_A8P8: case DXGI_FORMAT_A8P8:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
default: default:
if (BitsPerPixel(d3d10ext->dxgiFormat) == 0) if (BitsPerPixel(d3d10ext->dxgiFormat) == 0)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
@ -1213,7 +1276,7 @@ namespace
// D3DX writes 1D textures with a fixed Height of 1 // D3DX writes 1D textures with a fixed Height of 1
if ((header->flags & DDS_HEIGHT) && height != 1) if ((header->flags & DDS_HEIGHT) && height != 1)
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
height = depth = 1; height = depth = 1;
break; break;
@ -1230,17 +1293,17 @@ namespace
case D3D12_RESOURCE_DIMENSION_TEXTURE3D: case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
if (!(header->flags & DDS_HEADER_FLAGS_VOLUME)) if (!(header->flags & DDS_HEADER_FLAGS_VOLUME))
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
if (arraySize > 1) if (arraySize > 1)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
resDim = static_cast<D3D12_RESOURCE_DIMENSION>(d3d10ext->resourceDimension); resDim = static_cast<D3D12_RESOURCE_DIMENSION>(d3d10ext->resourceDimension);
@ -1251,7 +1314,7 @@ namespace
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
if (header->flags & DDS_HEADER_FLAGS_VOLUME) if (header->flags & DDS_HEADER_FLAGS_VOLUME)
@ -1265,7 +1328,7 @@ namespace
// We require all six faces to be defined // We require all six faces to be defined
if ((header->caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES) if ((header->caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
arraySize = 6; arraySize = 6;
@ -1284,7 +1347,7 @@ namespace
// Bound sizes (for security purposes we don't trust DDS file metadata larger than the Direct3D hardware requirements) // Bound sizes (for security purposes we don't trust DDS file metadata larger than the Direct3D hardware requirements)
if (mipCount > D3D12_REQ_MIP_LEVELS) if (mipCount > D3D12_REQ_MIP_LEVELS)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
switch (resDim) switch (resDim)
@ -1293,7 +1356,7 @@ namespace
if ((arraySize > D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) || if ((arraySize > D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) ||
(width > D3D12_REQ_TEXTURE1D_U_DIMENSION)) (width > D3D12_REQ_TEXTURE1D_U_DIMENSION))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
break; break;
@ -1305,14 +1368,14 @@ namespace
(width > D3D12_REQ_TEXTURECUBE_DIMENSION) || (width > D3D12_REQ_TEXTURECUBE_DIMENSION) ||
(height > D3D12_REQ_TEXTURECUBE_DIMENSION)) (height > D3D12_REQ_TEXTURECUBE_DIMENSION))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
else if ((arraySize > D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || else if ((arraySize > D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) ||
(width > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION) || (width > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION) ||
(height > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION)) (height > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
break; break;
@ -1322,12 +1385,12 @@ namespace
(height > D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (height > D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ||
(depth > D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)) (depth > D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
UINT numberOfPlanes = D3D12GetFormatPlaneCount(d3dDevice, format); UINT numberOfPlanes = D3D12GetFormatPlaneCount(d3dDevice, format);
@ -1337,7 +1400,7 @@ namespace
if ((numberOfPlanes > 1) && IsDepthStencil(format)) if ((numberOfPlanes > 1) && IsDepthStencil(format))
{ {
// DirectX 12 uses planes for stencil, DirectX 11 does not // DirectX 12 uses planes for stencil, DirectX 11 does not
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
if (outIsCubeMap != nullptr) if (outIsCubeMap != nullptr)

View File

@ -16,7 +16,13 @@
#pragma once #pragma once
#if defined(WIN32) || defined(WINAPI_FAMILY)
#include <d3d12.h> #include <d3d12.h>
#else
#include <wsl/winadapter.h>
#include <wsl/wrladapter.h>
#include <directx/d3d12.h>
#endif
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// BCDirectCompute.cpp // BCDirectCompute.cpp
// //
// Direct3D 11 Compute Shader BC Compressor // Direct3D 11 Compute Shader BC Compressor
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -104,7 +104,7 @@ HRESULT GPUCompressBC::Initialize(ID3D11Device* pDevice)
if (fl < D3D_FEATURE_LEVEL_10_0) if (fl < D3D_FEATURE_LEVEL_10_0)
{ {
// DirectCompute not supported on Feature Level 9.x hardware // DirectCompute not supported on Feature Level 9.x hardware
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
if (fl < D3D_FEATURE_LEVEL_11_0) if (fl < D3D_FEATURE_LEVEL_11_0)
@ -119,7 +119,7 @@ HRESULT GPUCompressBC::Initialize(ID3D11Device* pDevice)
if (!hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x) if (!hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
@ -222,7 +222,7 @@ HRESULT GPUCompressBC::Prepare(size_t width, size_t height, uint32_t flags, DXGI
default: default:
m_bcformat = m_srcformat = DXGI_FORMAT_UNKNOWN; m_bcformat = m_srcformat = DXGI_FORMAT_UNKNOWN;
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
m_bcformat = format; m_bcformat = format;
@ -234,7 +234,7 @@ HRESULT GPUCompressBC::Prepare(size_t width, size_t height, uint32_t flags, DXGI
// Create structured buffers // Create structured buffers
uint64_t sizeInBytes = uint64_t(num_blocks) * sizeof(BufferBC6HBC7); uint64_t sizeInBytes = uint64_t(num_blocks) * sizeof(BufferBC6HBC7);
if (sizeInBytes >= UINT32_MAX) if (sizeInBytes >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
auto bufferSize = static_cast<size_t>(sizeInBytes); auto bufferSize = static_cast<size_t>(sizeInBytes);

View File

@ -17,6 +17,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#if defined(WIN32) || defined(WINAPI_FAMILY)
#if !defined(__d3d11_h__) && !defined(__d3d11_x_h__) && !defined(__d3d12_h__) && !defined(__d3d12_x_h__) && !defined(__XBOX_D3D12_X__) #if !defined(__d3d11_h__) && !defined(__d3d11_x_h__) && !defined(__d3d12_h__) && !defined(__d3d12_x_h__) && !defined(__XBOX_D3D12_X__)
#ifdef _GAMING_XBOX_SCARLETT #ifdef _GAMING_XBOX_SCARLETT
#include <d3d12_xs.h> #include <d3d12_xs.h>
@ -28,13 +29,19 @@
#include <d3d11_1.h> #include <d3d11_1.h>
#endif #endif
#endif #endif
#else
#include <directx/dxgiformat.h>
#include <wsl/winadapter.h>
#endif
#include <DirectXMath.h> #include <DirectXMath.h>
#ifdef WIN32
#include <OCIdl.h> #include <OCIdl.h>
struct IWICImagingFactory; struct IWICImagingFactory;
struct IWICMetadataQueryReader; struct IWICMetadataQueryReader;
#endif
#define DIRECTX_TEX_VERSION 191 #define DIRECTX_TEX_VERSION 191
@ -285,6 +292,7 @@ namespace DirectX
_In_ TGA_FLAGS flags, _In_ TGA_FLAGS flags,
_Out_ TexMetadata& metadata) noexcept; _Out_ TexMetadata& metadata) noexcept;
#ifdef WIN32
HRESULT __cdecl GetMetadataFromWICMemory( HRESULT __cdecl GetMetadataFromWICMemory(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_In_ WIC_FLAGS flags, _In_ WIC_FLAGS flags,
@ -296,6 +304,7 @@ namespace DirectX
_In_ WIC_FLAGS flags, _In_ WIC_FLAGS flags,
_Out_ TexMetadata& metadata, _Out_ TexMetadata& metadata,
_In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr); _In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr);
#endif
// Compatability helpers // Compatability helpers
HRESULT __cdecl GetMetadataFromTGAMemory( HRESULT __cdecl GetMetadataFromTGAMemory(
@ -450,6 +459,7 @@ namespace DirectX
_In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr) noexcept; _In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
// WIC operations // WIC operations
#ifdef WIN32
HRESULT __cdecl LoadFromWICMemory( HRESULT __cdecl LoadFromWICMemory(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_In_ WIC_FLAGS flags, _In_ WIC_FLAGS flags,
@ -479,6 +489,7 @@ namespace DirectX
_In_ WIC_FLAGS flags, _In_ REFGUID guidContainerFormat, _In_ WIC_FLAGS flags, _In_ REFGUID guidContainerFormat,
_In_z_ const wchar_t* szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_z_ const wchar_t* szFile, _In_opt_ const GUID* targetFormat = nullptr,
_In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr); _In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr);
#endif // WIN32
// Compatability helpers // Compatability helpers
HRESULT __cdecl LoadFromTGAMemory( HRESULT __cdecl LoadFromTGAMemory(
@ -504,11 +515,13 @@ namespace DirectX
TEX_FR_FLIP_VERTICAL = 0x10, TEX_FR_FLIP_VERTICAL = 0x10,
}; };
#ifdef WIN32
HRESULT __cdecl FlipRotate(_In_ const Image& srcImage, _In_ TEX_FR_FLAGS flags, _Out_ ScratchImage& image) noexcept; HRESULT __cdecl FlipRotate(_In_ const Image& srcImage, _In_ TEX_FR_FLAGS flags, _Out_ ScratchImage& image) noexcept;
HRESULT __cdecl FlipRotate( HRESULT __cdecl FlipRotate(
_In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
_In_ TEX_FR_FLAGS flags, _Out_ ScratchImage& result) noexcept; _In_ TEX_FR_FLAGS flags, _Out_ ScratchImage& result) noexcept;
// Flip and/or rotate image // Flip and/or rotate image
#endif
enum TEX_FILTER_FLAGS : unsigned long enum TEX_FILTER_FLAGS : unsigned long
{ {
@ -788,7 +801,7 @@ namespace DirectX
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// WIC utility code // WIC utility code
#ifdef WIN32
enum WICCodecs enum WICCodecs
{ {
WIC_CODEC_BMP = 1, // Windows Bitmap (.bmp) WIC_CODEC_BMP = 1, // Windows Bitmap (.bmp)
@ -804,6 +817,7 @@ namespace DirectX
IWICImagingFactory* __cdecl GetWICFactory(bool& iswic2) noexcept; IWICImagingFactory* __cdecl GetWICFactory(bool& iswic2) noexcept;
void __cdecl SetWICFactory(_In_opt_ IWICImagingFactory* pWIC) noexcept; void __cdecl SetWICFactory(_In_opt_ IWICImagingFactory* pWIC) noexcept;
#endif
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Direct3D 11 functions // Direct3D 11 functions

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexCompress.cpp // DirectXTexCompress.cpp
// //
// DirectX Texture Library - Texture compression // DirectX Texture Library - Texture compression
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -89,7 +89,7 @@ namespace
if (sbpp < 8) if (sbpp < 8)
{ {
// We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM) // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
// Round to bytes // Round to bytes
@ -102,7 +102,7 @@ namespace
size_t blocksize; size_t blocksize;
TEX_FILTER_FLAGS cflags; TEX_FILTER_FLAGS cflags;
if (!DetermineEncoderSettings(result.format, pfEncode, blocksize, cflags)) if (!DetermineEncoderSettings(result.format, pfEncode, blocksize, cflags))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
XM_ALIGNED_DATA(16) XMVECTOR temp[16]; XM_ALIGNED_DATA(16) XMVECTOR temp[16];
const uint8_t *pSrc = image.pixels; const uint8_t *pSrc = image.pixels;
@ -218,7 +218,7 @@ namespace
if (sbpp < 8) if (sbpp < 8)
{ {
// We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM) // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
// Round to bytes // Round to bytes
@ -231,7 +231,7 @@ namespace
size_t blocksize; size_t blocksize;
TEX_FILTER_FLAGS cflags; TEX_FILTER_FLAGS cflags;
if (!DetermineEncoderSettings(result.format, pfEncode, blocksize, cflags)) if (!DetermineEncoderSettings(result.format, pfEncode, blocksize, cflags))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
// Refactored version of loop to support parallel independance // Refactored version of loop to support parallel independance
const size_t nBlocks = std::max<size_t>(1, (image.width + 3) / 4) * std::max<size_t>(1, (image.height + 3) / 4); const size_t nBlocks = std::max<size_t>(1, (image.width + 3) / 4) * std::max<size_t>(1, (image.height + 3) / 4);
@ -394,7 +394,7 @@ namespace
if (dbpp < 8) if (dbpp < 8)
{ {
// We don't support decompressing to monochrome (DXGI_FORMAT_R1_UNORM) // We don't support decompressing to monochrome (DXGI_FORMAT_R1_UNORM)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
// Round to bytes // Round to bytes
@ -438,7 +438,7 @@ namespace
case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break; case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
XM_ALIGNED_DATA(16) XMVECTOR temp[16]; XM_ALIGNED_DATA(16) XMVECTOR temp[16];
@ -603,7 +603,7 @@ HRESULT DirectX::Compress(
if (IsTypeless(format) if (IsTypeless(format)
|| IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format)) || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
// Create compressed image // Create compressed image
HRESULT hr = image.Initialize2D(format, srcImage.width, srcImage.height, 1, 1); HRESULT hr = image.Initialize2D(format, srcImage.width, srcImage.height, 1, 1);
@ -655,7 +655,7 @@ HRESULT DirectX::Compress(
if (IsTypeless(format) if (IsTypeless(format)
|| IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format)) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
cImages.Release(); cImages.Release();
@ -749,7 +749,7 @@ HRESULT DirectX::Decompress(
return E_INVALIDARG; return E_INVALIDARG;
if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format)) if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
// Create decompressed image // Create decompressed image
@ -802,7 +802,7 @@ HRESULT DirectX::Decompress(
return E_INVALIDARG; return E_INVALIDARG;
if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format)) if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
images.Release(); images.Release();

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexCompressGPU.cpp // DirectXTexCompressGPU.cpp
// //
// DirectX Texture Library - DirectCompute-based texture compression // DirectX Texture Library - DirectCompute-based texture compression
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -219,7 +219,7 @@ HRESULT DirectX::Compress(
if (IsTypeless(format) if (IsTypeless(format)
|| IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format)) || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
// Setup GPU compressor // Setup GPU compressor
std::unique_ptr<GPUCompressBC> gpubc(new (std::nothrow) GPUCompressBC); std::unique_ptr<GPUCompressBC> gpubc(new (std::nothrow) GPUCompressBC);
@ -272,7 +272,7 @@ HRESULT DirectX::Compress(
if (IsTypeless(format) if (IsTypeless(format)
|| IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format)) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
cImages.Release(); cImages.Release();
@ -414,7 +414,7 @@ HRESULT DirectX::Compress(
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
return S_OK; return S_OK;

View File

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexConvert.cpp // DirectXTexConvert.cpp
// //
// DirectX Texture Library - Image pixel format conversion // DirectX Texture Library - Image pixel format conversion
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
@ -435,7 +435,7 @@ void DirectX::_CopyScanline(
return; return;
size_t size = std::min<size_t>(outSize, inSize); size_t size = std::min<size_t>(outSize, inSize);
memcpy_s(pDestination, outSize, pSource, size); memcpy(pDestination, pSource, size);
} }
@ -605,7 +605,7 @@ void DirectX::_SwizzleScanline(
return; return;
size_t size = std::min<size_t>(outSize, inSize); size_t size = std::min<size_t>(outSize, inSize);
memcpy_s(pDestination, outSize, pSource, size); memcpy(pDestination, pSource, size);
} }
@ -777,7 +777,7 @@ _Use_decl_annotations_ bool DirectX::_LoadScanline(
case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_FLOAT:
{ {
size_t msize = (size > (sizeof(XMVECTOR)*count)) ? (sizeof(XMVECTOR)*count) : size; size_t msize = (size > (sizeof(XMVECTOR)*count)) ? (sizeof(XMVECTOR)*count) : size;
memcpy_s(dPtr, sizeof(XMVECTOR)*count, pSource, msize); memcpy(dPtr, pSource, msize);
} }
return true; return true;
@ -2972,10 +2972,9 @@ namespace
{ XBOX_DXGI_FORMAT_R4G4_UNORM, 4, CONVF_UNORM | CONVF_R | CONVF_G }, { XBOX_DXGI_FORMAT_R4G4_UNORM, 4, CONVF_UNORM | CONVF_R | CONVF_G },
}; };
#pragma prefast( suppress : 25004, "Signature must match bsearch_s" ); #pragma prefast( suppress : 25004, "Signature must match bsearch" );
int __cdecl ConvertCompare(void *context, const void* ptr1, const void *ptr2) noexcept int __cdecl ConvertCompare(const void* ptr1, const void *ptr2) noexcept
{ {
UNREFERENCED_PARAMETER(context);
auto p1 = static_cast<const ConvertData*>(ptr1); auto p1 = static_cast<const ConvertData*>(ptr1);
auto p2 = static_cast<const ConvertData*>(ptr2); auto p2 = static_cast<const ConvertData*>(ptr2);
if (p1->format == p2->format) return 0; if (p1->format == p2->format) return 0;
@ -2998,8 +2997,8 @@ uint32_t DirectX::_GetConvertFlags(DXGI_FORMAT format) noexcept
#endif #endif
ConvertData key = { format, 0, 0 }; ConvertData key = { format, 0, 0 };
auto in = reinterpret_cast<const ConvertData*>(bsearch_s(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), auto in = reinterpret_cast<const ConvertData*>(bsearch(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData),
ConvertCompare, nullptr)); ConvertCompare));
return (in) ? in->flags : 0; return (in) ? in->flags : 0;
} }
@ -3032,10 +3031,10 @@ void DirectX::_ConvertScanline(
// Determine conversion details about source and dest formats // Determine conversion details about source and dest formats
ConvertData key = { inFormat, 0, 0 }; ConvertData key = { inFormat, 0, 0 };
auto in = reinterpret_cast<const ConvertData*>( auto in = reinterpret_cast<const ConvertData*>(
bsearch_s(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare, nullptr)); bsearch(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare));
key.format = outFormat; key.format = outFormat;
auto out = reinterpret_cast<const ConvertData*>( auto out = reinterpret_cast<const ConvertData*>(
bsearch_s(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare, nullptr)); bsearch(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare));
if (!in || !out) if (!in || !out)
{ {
assert(false); assert(false);
@ -4373,6 +4372,14 @@ namespace
_Out_ WICPixelFormatGUID& pfGUID, _Out_ WICPixelFormatGUID& pfGUID,
_Out_ WICPixelFormatGUID& targetGUID) noexcept _Out_ WICPixelFormatGUID& targetGUID) noexcept
{ {
#ifndef WIN32
UNREFERENCED_PARAMETER(filter);
UNREFERENCED_PARAMETER(sformat);
UNREFERENCED_PARAMETER(tformat);
UNREFERENCED_PARAMETER(pfGUID);
UNREFERENCED_PARAMETER(targetGUID);
return false;
#else
memset(&pfGUID, 0, sizeof(GUID)); memset(&pfGUID, 0, sizeof(GUID));
memset(&targetGUID, 0, sizeof(GUID)); memset(&targetGUID, 0, sizeof(GUID));
@ -4514,6 +4521,7 @@ namespace
} }
return true; return true;
#endif // WIN32
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -4527,6 +4535,15 @@ namespace
_In_ float threshold, _In_ float threshold,
_In_ const Image& destImage) _In_ const Image& destImage)
{ {
#ifndef WIN32
UNREFERENCED_PARAMETER(srcImage);
UNREFERENCED_PARAMETER(pfGUID);
UNREFERENCED_PARAMETER(targetGUID);
UNREFERENCED_PARAMETER(filter);
UNREFERENCED_PARAMETER(threshold);
UNREFERENCED_PARAMETER(destImage);
return E_NOTIMPL;
#else
assert(srcImage.width == destImage.width); assert(srcImage.width == destImage.width);
assert(srcImage.height == destImage.height); assert(srcImage.height == destImage.height);
@ -4553,7 +4570,7 @@ namespace
if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX
|| destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<IWICBitmap> source; ComPtr<IWICBitmap> source;
hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(srcImage.height), pfGUID, hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(srcImage.height), pfGUID,
@ -4571,9 +4588,9 @@ namespace
return hr; return hr;
return S_OK; return S_OK;
#endif // WIN32
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert the source image (not using WIC) // Convert the source image (not using WIC)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -4840,7 +4857,7 @@ HRESULT DirectX::Convert(
|| IsPlanar(srcImage.format) || IsPlanar(format) || IsPlanar(srcImage.format) || IsPlanar(format)
|| IsPalettized(srcImage.format) || IsPalettized(format) || IsPalettized(srcImage.format) || IsPalettized(format)
|| IsTypeless(srcImage.format) || IsTypeless(format)) || IsTypeless(srcImage.format) || IsTypeless(format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if ((srcImage.width > UINT32_MAX) || (srcImage.height > UINT32_MAX)) if ((srcImage.width > UINT32_MAX) || (srcImage.height > UINT32_MAX))
return E_INVALIDARG; return E_INVALIDARG;
@ -4896,7 +4913,7 @@ HRESULT DirectX::Convert(
|| IsPlanar(metadata.format) || IsPlanar(format) || IsPlanar(metadata.format) || IsPlanar(format)
|| IsPalettized(metadata.format) || IsPalettized(format) || IsPalettized(metadata.format) || IsPalettized(format)
|| IsTypeless(metadata.format) || IsTypeless(format)) || IsTypeless(metadata.format) || IsTypeless(format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX)) if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX))
return E_INVALIDARG; return E_INVALIDARG;
@ -5049,7 +5066,7 @@ HRESULT DirectX::ConvertToSinglePlane(const Image& srcImage, ScratchImage& image
DXGI_FORMAT format = _PlanarToSingle(srcImage.format); DXGI_FORMAT format = _PlanarToSingle(srcImage.format);
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if ((srcImage.width > UINT32_MAX) || (srcImage.height > UINT32_MAX)) if ((srcImage.width > UINT32_MAX) || (srcImage.height > UINT32_MAX))
return E_INVALIDARG; return E_INVALIDARG;
@ -5092,12 +5109,12 @@ HRESULT DirectX::ConvertToSinglePlane(
if (metadata.IsVolumemap()) if (metadata.IsVolumemap())
{ {
// Direct3D does not support any planar formats for Texture3D // Direct3D does not support any planar formats for Texture3D
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
DXGI_FORMAT format = _PlanarToSingle(metadata.format); DXGI_FORMAT format = _PlanarToSingle(metadata.format);
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX)) if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX))
return E_INVALIDARG; return E_INVALIDARG;

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexD3D11.cpp // DirectXTexD3D11.cpp
// //
// DirectX Texture Library - Direct3D 11 helpers // DirectX Texture Library - Direct3D 11 helpers
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -117,7 +117,7 @@ namespace
for (size_t h = 0; h < lines; ++h) for (size_t h = 0; h < lines; ++h)
{ {
size_t msize = std::min<size_t>(img->rowPitch, mapped.RowPitch); size_t msize = std::min<size_t>(img->rowPitch, mapped.RowPitch);
memcpy_s(dptr, img->rowPitch, sptr, msize); memcpy(dptr, sptr, msize);
sptr += mapped.RowPitch; sptr += mapped.RowPitch;
dptr += img->rowPitch; dptr += img->rowPitch;
} }
@ -176,7 +176,7 @@ namespace
for (size_t h = 0; h < lines; ++h) for (size_t h = 0; h < lines; ++h)
{ {
size_t msize = std::min<size_t>(img->rowPitch, mapped.RowPitch); size_t msize = std::min<size_t>(img->rowPitch, mapped.RowPitch);
memcpy_s(dptr, img->rowPitch, sptr, msize); memcpy(dptr, sptr, msize);
sptr += mapped.RowPitch; sptr += mapped.RowPitch;
dptr += img->rowPitch; dptr += img->rowPitch;
} }
@ -454,7 +454,7 @@ HRESULT DirectX::CreateTextureEx(
if (metadata.arraySize > 1) if (metadata.arraySize > 1)
// Direct3D 11 doesn't support arrays of 3D textures // Direct3D 11 doesn't support arrays of 3D textures
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
size_t depth = metadata.depth; size_t depth = metadata.depth;

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexD3D12.cpp // DirectXTexD3D12.cpp
// //
// DirectX Texture Library - Direct3D 12 helpers // DirectX Texture Library - Direct3D 12 helpers
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -16,6 +16,7 @@
#pragma clang diagnostic ignored "-Wsign-conversion" #pragma clang diagnostic ignored "-Wsign-conversion"
#endif #endif
#ifdef WIN32
#ifdef _GAMING_XBOX_SCARLETT #ifdef _GAMING_XBOX_SCARLETT
#include <d3dx12_xs.h> #include <d3dx12_xs.h>
#elif (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX) #elif (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
@ -24,6 +25,10 @@
#define D3DX12_NO_STATE_OBJECT_HELPERS #define D3DX12_NO_STATE_OBJECT_HELPERS
#include "d3dx12.h" #include "d3dx12.h"
#endif #endif
#else
#include "directx/d3dx12.h"
#include "dxguids/dxguids.h"
#endif
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
@ -133,7 +138,7 @@ namespace
if ((numberOfPlanes > 1) && IsDepthStencil(desc.Format)) if ((numberOfPlanes > 1) && IsDepthStencil(desc.Format))
{ {
// DirectX 12 uses planes for stencil, DirectX 11 does not // DirectX 12 uses planes for stencil, DirectX 11 does not
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
D3D12_HEAP_PROPERTIES sourceHeapProperties; D3D12_HEAP_PROPERTIES sourceHeapProperties;
@ -299,7 +304,13 @@ namespace
// Block until the copy is complete // Block until the copy is complete
while (fence->GetCompletedValue() < 1) while (fence->GetCompletedValue() < 1)
{
#ifdef WIN32
SwitchToThread(); SwitchToThread();
#else
std::this_thread::yield();
#endif
}
return S_OK; return S_OK;
} }
@ -489,7 +500,7 @@ HRESULT DirectX::CreateTextureEx(
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Prepares a texture resource for upload // Prepares a texture resource for upload
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
@ -510,7 +521,7 @@ HRESULT DirectX::PrepareUpload(
if ((numberOfPlanes > 1) && IsDepthStencil(metadata.format)) if ((numberOfPlanes > 1) && IsDepthStencil(metadata.format))
{ {
// DirectX 12 uses planes for stencil, DirectX 11 does not // DirectX 12 uses planes for stencil, DirectX 11 does not
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
size_t numberOfResources = (metadata.dimension == TEX_DIMENSION_TEXTURE3D) size_t numberOfResources = (metadata.dimension == TEX_DIMENSION_TEXTURE3D)
@ -536,7 +547,7 @@ HRESULT DirectX::PrepareUpload(
if (metadata.arraySize > 1) if (metadata.arraySize > 1)
// Direct3D 12 doesn't support arrays of 3D textures // Direct3D 12 doesn't support arrays of 3D textures
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
for (size_t plane = 0; plane < numberOfPlanes; ++plane) for (size_t plane = 0; plane < numberOfPlanes; ++plane)
{ {

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexDDS.cpp // DirectXTexDDS.cpp
// //
// DirectX Texture Library - Microsoft DirectDraw Surface (DDS) file format reader/writer // DirectX Texture Library - Microsoft DirectDraw Surface (DDS) file format reader/writer
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -41,9 +41,9 @@ namespace
CONV_FLAGS_A8P8 = 0x800, // Has an 8-bit palette with an alpha channel CONV_FLAGS_A8P8 = 0x800, // Has an 8-bit palette with an alpha channel
CONV_FLAGS_DX10 = 0x10000, // Has the 'DX10' extension header CONV_FLAGS_DX10 = 0x10000, // Has the 'DX10' extension header
CONV_FLAGS_PMALPHA = 0x20000, // Contains premultiplied alpha data CONV_FLAGS_PMALPHA = 0x20000, // Contains premultiplied alpha data
CONV_FLAGS_L8 = 0x40000, // Source is a 8 luminance format CONV_FLAGS_L8 = 0x40000, // Source is a 8 luminance format
CONV_FLAGS_L16 = 0x80000, // Source is a 16 luminance format CONV_FLAGS_L16 = 0x80000, // Source is a 16 luminance format
CONV_FLAGS_A8L8 = 0x100000, // Source is a 8:8 luminance format CONV_FLAGS_A8L8 = 0x100000, // Source is a 8:8 luminance format
}; };
struct LegacyDDS struct LegacyDDS
@ -284,7 +284,7 @@ namespace
if (size < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (size < (sizeof(DDS_HEADER) + sizeof(uint32_t)))
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
// DDS files always start with the same magic number ("DDS ") // DDS files always start with the same magic number ("DDS ")
@ -323,13 +323,13 @@ namespace
metadata.arraySize = d3d10ext->arraySize; metadata.arraySize = d3d10ext->arraySize;
if (metadata.arraySize == 0) if (metadata.arraySize == 0)
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
metadata.format = d3d10ext->dxgiFormat; metadata.format = d3d10ext->dxgiFormat;
if (!IsValid(metadata.format) || IsPalettized(metadata.format)) if (!IsValid(metadata.format) || IsPalettized(metadata.format))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
static_assert(static_cast<int>(TEX_MISC_TEXTURECUBE) == static_cast<int>(DDS_RESOURCE_MISC_TEXTURECUBE), "DDS header mismatch"); static_assert(static_cast<int>(TEX_MISC_TEXTURECUBE) == static_cast<int>(DDS_RESOURCE_MISC_TEXTURECUBE), "DDS header mismatch");
@ -343,7 +343,7 @@ namespace
// D3DX writes 1D textures with a fixed Height of 1 // D3DX writes 1D textures with a fixed Height of 1
if ((pHeader->flags & DDS_HEIGHT) && pHeader->height != 1) if ((pHeader->flags & DDS_HEIGHT) && pHeader->height != 1)
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
metadata.width = pHeader->width; metadata.width = pHeader->width;
@ -368,11 +368,11 @@ namespace
case DDS_DIMENSION_TEXTURE3D: case DDS_DIMENSION_TEXTURE3D:
if (!(pHeader->flags & DDS_HEADER_FLAGS_VOLUME)) if (!(pHeader->flags & DDS_HEADER_FLAGS_VOLUME))
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
if (metadata.arraySize > 1) if (metadata.arraySize > 1)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
metadata.width = pHeader->width; metadata.width = pHeader->width;
metadata.height = pHeader->height; metadata.height = pHeader->height;
@ -381,7 +381,7 @@ namespace
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
static_assert(static_cast<int>(TEX_MISC2_ALPHA_MODE_MASK) == static_cast<int>(DDS_MISC_FLAGS2_ALPHA_MODE_MASK), "DDS header mismatch"); static_assert(static_cast<int>(TEX_MISC2_ALPHA_MODE_MASK) == static_cast<int>(DDS_MISC_FLAGS2_ALPHA_MODE_MASK), "DDS header mismatch");
@ -411,7 +411,7 @@ namespace
{ {
// We require all six faces to be defined // We require all six faces to be defined
if ((pHeader->caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES) if ((pHeader->caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
metadata.arraySize = 6; metadata.arraySize = 6;
metadata.miscFlags |= TEX_MISC_TEXTURECUBE; metadata.miscFlags |= TEX_MISC_TEXTURECUBE;
@ -428,7 +428,7 @@ namespace
metadata.format = GetDXGIFormat(*pHeader, pHeader->ddspf, flags, convFlags); metadata.format = GetDXGIFormat(*pHeader, pHeader->ddspf, flags, convFlags);
if (metadata.format == DXGI_FORMAT_UNKNOWN) if (metadata.format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
// Special flag for handling LUMINANCE legacy formats // Special flag for handling LUMINANCE legacy formats
if (flags & DDS_FLAGS_EXPAND_LUMINANCE) if (flags & DDS_FLAGS_EXPAND_LUMINANCE)
@ -533,14 +533,14 @@ namespace
|| metadata.height > 16384u /* D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION */ || metadata.height > 16384u /* D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION */
|| metadata.mipLevels > 15u /* D3D12_REQ_MIP_LEVELS */) || metadata.mipLevels > 15u /* D3D12_REQ_MIP_LEVELS */)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
// 2048 is the maximum required depth/array size supported by Direct3D // 2048 is the maximum required depth/array size supported by Direct3D
if (metadata.arraySize > 2048u /* D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION, D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION */ if (metadata.arraySize > 2048u /* D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION, D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION */
|| metadata.depth > 2048u /* D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION */) || metadata.depth > 2048u /* D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION */)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
@ -564,7 +564,7 @@ HRESULT DirectX::_EncodeDDSHeader(
return E_INVALIDARG; return E_INVALIDARG;
if (IsPalettized(metadata.format)) if (IsPalettized(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (metadata.arraySize > 1) if (metadata.arraySize > 1)
{ {
@ -572,7 +572,7 @@ HRESULT DirectX::_EncodeDDSHeader(
{ {
// Texture1D arrays, Texture2D arrays, and Cubemap arrays must be stored using 'DX10' extended header // Texture1D arrays, Texture2D arrays, and Cubemap arrays must be stored using 'DX10' extended header
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
return HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE); return HRESULT_E_CANNOT_MAKE;
flags |= DDS_FLAGS_FORCE_DX10_EXT; flags |= DDS_FLAGS_FORCE_DX10_EXT;
} }
@ -588,28 +588,28 @@ HRESULT DirectX::_EncodeDDSHeader(
{ {
switch (metadata.format) switch (metadata.format)
{ {
case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy(&ddpf, &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R16G16_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R16G16_UNORM: memcpy(&ddpf, &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8_UNORM: memcpy(&ddpf, &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R16_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_L16, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R16_UNORM: memcpy(&ddpf, &DDSPF_L16, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_L8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8_UNORM: memcpy(&ddpf, &DDSPF_L8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_A8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_A8_UNORM: memcpy(&ddpf, &DDSPF_A8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8_B8G8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_R8G8_B8G8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8_B8G8_UNORM: memcpy(&ddpf, &DDSPF_R8G8_B8G8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy(&ddpf, &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC1_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC1_UNORM: memcpy(&ddpf, &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC2_UNORM: memcpy_s(&ddpf, sizeof(ddpf), metadata.IsPMAlpha() ? (&DDSPF_DXT2) : (&DDSPF_DXT3), sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC2_UNORM: memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT2) : (&DDSPF_DXT3), sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC3_UNORM: memcpy_s(&ddpf, sizeof(ddpf), metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC3_UNORM: memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC4_SNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC4_SNORM: memcpy(&ddpf, &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC5_SNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC5_SNORM: memcpy(&ddpf, &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B5G6R5_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_B5G6R5_UNORM: memcpy(&ddpf, &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy(&ddpf, &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8_SNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_V8U8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8_SNORM: memcpy(&ddpf, &DDSPF_V8U8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8B8A8_SNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_Q8W8V8U8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8B8A8_SNORM: memcpy(&ddpf, &DDSPF_Q8W8V8U8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R16G16_SNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_V16U16, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R16G16_SNORM: memcpy(&ddpf, &DDSPF_V16U16, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.1 case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy(&ddpf, &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.1
case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.1 case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy(&ddpf, &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.1
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2 case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy(&ddpf, &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2
case DXGI_FORMAT_YUY2: memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2 case DXGI_FORMAT_YUY2: memcpy(&ddpf, &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2
// Legacy D3DX formats using D3DFMT enum value as FourCC // Legacy D3DX formats using D3DFMT enum value as FourCC
case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_FLOAT:
@ -642,40 +642,40 @@ HRESULT DirectX::_EncodeDDSHeader(
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
// Write using the 'incorrect' mask version to match D3DX bug // Write using the 'incorrect' mask version to match D3DX bug
memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A2B10G10R10, sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, &DDSPF_A2B10G10R10, sizeof(DDS_PIXELFORMAT));
} }
break; break;
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT));
} }
break; break;
case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM_SRGB:
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT));
} }
break; break;
case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC2_UNORM_SRGB:
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
memcpy_s(&ddpf, sizeof(ddpf), metadata.IsPMAlpha() ? (&DDSPF_DXT2) : (&DDSPF_DXT3), sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT2) : (&DDSPF_DXT3), sizeof(DDS_PIXELFORMAT));
} }
break; break;
case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM_SRGB:
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
memcpy_s(&ddpf, sizeof(ddpf), metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT));
} }
break; break;
case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_UNORM:
memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_BC4_UNORM, sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, &DDSPF_BC4_UNORM, sizeof(DDS_PIXELFORMAT));
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
ddpf.fourCC = MAKEFOURCC('A', 'T', 'I', '1'); ddpf.fourCC = MAKEFOURCC('A', 'T', 'I', '1');
@ -683,7 +683,7 @@ HRESULT DirectX::_EncodeDDSHeader(
break; break;
case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_UNORM:
memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_BC5_UNORM, sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, &DDSPF_BC5_UNORM, sizeof(DDS_PIXELFORMAT));
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
ddpf.fourCC = MAKEFOURCC('A', 'T', 'I', '2'); ddpf.fourCC = MAKEFOURCC('A', 'T', 'I', '2');
@ -693,14 +693,14 @@ HRESULT DirectX::_EncodeDDSHeader(
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT));
} }
break; break;
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
{ {
memcpy_s(&ddpf, sizeof(ddpf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT)); memcpy(&ddpf, &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT));
} }
break; break;
@ -714,7 +714,7 @@ HRESULT DirectX::_EncodeDDSHeader(
if (ddpf.size == 0) if (ddpf.size == 0)
{ {
if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) if (flags & DDS_FLAGS_FORCE_DX9_LEGACY)
return HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE); return HRESULT_E_CANNOT_MAKE;
required += sizeof(DDS_HEADER_DXT10); required += sizeof(DDS_HEADER_DXT10);
} }
@ -813,7 +813,7 @@ HRESULT DirectX::_EncodeDDSHeader(
if (ddpf.size == 0) if (ddpf.size == 0)
{ {
memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT)); memcpy(&header->ddspf, &DDSPF_DX10, sizeof(DDS_PIXELFORMAT));
auto ext = reinterpret_cast<DDS_HEADER_DXT10*>(reinterpret_cast<uint8_t*>(header) + sizeof(DDS_HEADER)); auto ext = reinterpret_cast<DDS_HEADER_DXT10*>(reinterpret_cast<uint8_t*>(header) + sizeof(DDS_HEADER));
assert(ext); assert(ext);
@ -856,7 +856,7 @@ HRESULT DirectX::_EncodeDDSHeader(
} }
else else
{ {
memcpy_s(&header->ddspf, sizeof(header->ddspf), &ddpf, sizeof(ddpf)); memcpy(&header->ddspf, &ddpf, sizeof(ddpf));
} }
return S_OK; return S_OK;
@ -1074,7 +1074,7 @@ namespace
switch (outFormat) switch (outFormat)
{ {
case DXGI_FORMAT_B4G4R4A4_UNORM: case DXGI_FORMAT_B4G4R4A4_UNORM:
// D3DFMT_A4L4 -> DXGI_FORMAT_B4G4R4A4_UNORM // D3DFMT_A4L4 -> DXGI_FORMAT_B4G4R4A4_UNORM
if (inSize >= 1 && outSize >= 2) if (inSize >= 1 && outSize >= 2)
{ {
const uint8_t * __restrict sPtr = static_cast<const uint8_t*>(pSource); const uint8_t * __restrict sPtr = static_cast<const uint8_t*>(pSource);
@ -1249,7 +1249,7 @@ namespace
size_t pixelSize, nimages; size_t pixelSize, nimages;
if (!_DetermineImageArray(metadata, cpFlags, nimages, pixelSize)) if (!_DetermineImageArray(metadata, cpFlags, nimages, pixelSize))
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
if ((nimages == 0) || (nimages != image.GetImageCount())) if ((nimages == 0) || (nimages != image.GetImageCount()))
{ {
@ -1258,7 +1258,7 @@ namespace
if (pixelSize > size) if (pixelSize > size)
{ {
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); return HRESULT_E_HANDLE_EOF;
} }
std::unique_ptr<Image[]> timages(new (std::nothrow) Image[nimages]); std::unique_ptr<Image[]> timages(new (std::nothrow) Image[nimages]);
@ -1324,14 +1324,14 @@ namespace
if (IsCompressed(metadata.format)) if (IsCompressed(metadata.format))
{ {
size_t csize = std::min<size_t>(images[index].slicePitch, timages[index].slicePitch); size_t csize = std::min<size_t>(images[index].slicePitch, timages[index].slicePitch);
memcpy_s(pDest, images[index].slicePitch, pSrc, csize); memcpy(pDest, pSrc, csize);
if (cpFlags & CP_FLAGS_BAD_DXTN_TAILS) if (cpFlags & CP_FLAGS_BAD_DXTN_TAILS)
{ {
if (images[index].width < 4 || images[index].height < 4) if (images[index].width < 4 || images[index].height < 4)
{ {
csize = std::min<size_t>(images[index].slicePitch, timages[lastgood].slicePitch); csize = std::min<size_t>(images[index].slicePitch, timages[lastgood].slicePitch);
memcpy_s(pDest, images[index].slicePitch, timages[lastgood].pixels, csize); memcpy(pDest, timages[lastgood].pixels, csize);
} }
else else
{ {
@ -1348,7 +1348,7 @@ namespace
size_t csize = std::min<size_t>(dpitch, spitch); size_t csize = std::min<size_t>(dpitch, spitch);
for (size_t h = 0; h < count; ++h) for (size_t h = 0; h < count; ++h)
{ {
memcpy_s(pDest, dpitch, pSrc, csize); memcpy(pDest, pSrc, csize);
pSrc += spitch; pSrc += spitch;
pDest += dpitch; pDest += dpitch;
} }
@ -1426,14 +1426,14 @@ namespace
if (IsCompressed(metadata.format)) if (IsCompressed(metadata.format))
{ {
size_t csize = std::min<size_t>(images[index].slicePitch, timages[index].slicePitch); size_t csize = std::min<size_t>(images[index].slicePitch, timages[index].slicePitch);
memcpy_s(pDest, images[index].slicePitch, pSrc, csize); memcpy(pDest, pSrc, csize);
if (cpFlags & CP_FLAGS_BAD_DXTN_TAILS) if (cpFlags & CP_FLAGS_BAD_DXTN_TAILS)
{ {
if (images[index].width < 4 || images[index].height < 4) if (images[index].width < 4 || images[index].height < 4)
{ {
csize = std::min<size_t>(images[index].slicePitch, timages[lastgood + slice].slicePitch); csize = std::min<size_t>(images[index].slicePitch, timages[lastgood + slice].slicePitch);
memcpy_s(pDest, images[index].slicePitch, timages[lastgood + slice].pixels, csize); memcpy(pDest, timages[lastgood + slice].pixels, csize);
} }
else if (!slice) else if (!slice)
{ {
@ -1444,7 +1444,7 @@ namespace
else if (IsPlanar(metadata.format)) else if (IsPlanar(metadata.format))
{ {
// Direct3D does not support any planar formats for Texture3D // Direct3D does not support any planar formats for Texture3D
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
else else
{ {
@ -1509,7 +1509,7 @@ namespace
const TexMetadata& metadata = image.GetMetadata(); const TexMetadata& metadata = image.GetMetadata();
if (IsPlanar(metadata.format)) if (IsPlanar(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
uint32_t tflags = (convFlags & CONV_FLAGS_NOALPHA) ? TEXP_SCANLINE_SETALPHA : 0u; uint32_t tflags = (convFlags & CONV_FLAGS_NOALPHA) ? TEXP_SCANLINE_SETALPHA : 0u;
if (convFlags & CONV_FLAGS_SWIZZLE) if (convFlags & CONV_FLAGS_SWIZZLE)
@ -1575,6 +1575,7 @@ HRESULT DirectX::GetMetadataFromDDSFile(
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
@ -1596,11 +1597,31 @@ HRESULT DirectX::GetMetadataFromDDSFile(
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file)
if (fileInfo.EndOfFile.HighPart > 0) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
} }
size_t len = fileInfo.EndOfFile.LowPart;
#else // !WIN32
std::ifstream inFile(std::filesystem::path(szFile), std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
return E_FAIL;
std::streampos fileLen = inFile.tellg();
if (!inFile)
return E_FAIL;
if (fileLen > UINT32_MAX)
return HRESULT_E_FILE_TOO_LARGE;
inFile.seekg(0, std::ios::beg);
if (!inFile)
return E_FAIL;
size_t len = fileLen;
#endif
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (len < (sizeof(DDS_HEADER) + sizeof(uint32_t)))
{ {
return E_FAIL; return E_FAIL;
} }
@ -1609,14 +1630,24 @@ HRESULT DirectX::GetMetadataFromDDSFile(
const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10);
uint8_t header[MAX_HEADER_SIZE] = {}; uint8_t header[MAX_HEADER_SIZE] = {};
#ifdef WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
auto headerLen = static_cast<size_t>(bytesRead);
#else
auto headerLen = std::min<size_t>(len, MAX_HEADER_SIZE);
inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile)
return E_FAIL;
#endif
uint32_t convFlags = 0; uint32_t convFlags = 0;
return DecodeDDSHeader(header, bytesRead, flags, metadata, convFlags); return DecodeDDSHeader(header, headerLen, flags, metadata, convFlags);
} }
@ -1708,13 +1739,13 @@ HRESULT DirectX::LoadFromDDSFile(
image.Release(); image.Release();
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, nullptr))); FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
#endif #endif
if (!hFile) if (!hFile)
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1729,12 +1760,30 @@ HRESULT DirectX::LoadFromDDSFile(
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file)
if (fileInfo.EndOfFile.HighPart > 0) if (fileInfo.EndOfFile.HighPart > 0)
{ return HRESULT_E_FILE_TOO_LARGE;
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
} size_t len = fileInfo.EndOfFile.LowPart;
#else // !WIN32
std::ifstream inFile(std::filesystem::path(szFile), std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
return E_FAIL;
std::streampos fileLen = inFile.tellg();
if (!inFile)
return E_FAIL;
if (fileLen > UINT32_MAX)
return HRESULT_E_FILE_TOO_LARGE;
inFile.seekg(0, std::ios::beg);
if (!inFile)
return E_FAIL;
size_t len = fileLen;
#endif
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (len < (sizeof(DDS_HEADER) + sizeof(uint32_t)))
{ {
return E_FAIL; return E_FAIL;
} }
@ -1743,28 +1792,44 @@ HRESULT DirectX::LoadFromDDSFile(
const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10);
uint8_t header[MAX_HEADER_SIZE] = {}; uint8_t header[MAX_HEADER_SIZE] = {};
#ifdef WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
auto headerLen = static_cast<size_t>(bytesRead);
#else
auto headerLen = std::min<size_t>(len, MAX_HEADER_SIZE);
inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile)
return E_FAIL;
#endif
uint32_t convFlags = 0; uint32_t convFlags = 0;
TexMetadata mdata; TexMetadata mdata;
HRESULT hr = DecodeDDSHeader(header, bytesRead, flags, mdata, convFlags); HRESULT hr = DecodeDDSHeader(header, headerLen, flags, mdata, convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
DWORD offset = MAX_HEADER_SIZE; size_t offset = MAX_HEADER_SIZE;
if (!(convFlags & CONV_FLAGS_DX10)) if (!(convFlags & CONV_FLAGS_DX10))
{ {
#ifdef WIN32
// Must reset file position since we read more than the standard header above // Must reset file position since we read more than the standard header above
LARGE_INTEGER filePos = { { sizeof(uint32_t) + sizeof(DDS_HEADER), 0 } }; LARGE_INTEGER filePos = { { sizeof(uint32_t) + sizeof(DDS_HEADER), 0 } };
if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
#else
inFile.seekg(sizeof(uint32_t) + sizeof(DDS_HEADER), std::ios::beg);
if (!inFile)
return E_FAIL;
#endif
offset = sizeof(uint32_t) + sizeof(DDS_HEADER); offset = sizeof(uint32_t) + sizeof(DDS_HEADER);
} }
@ -1778,6 +1843,7 @@ HRESULT DirectX::LoadFromDDSFile(
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
#ifdef WIN32
if (!ReadFile(hFile.get(), pal8.get(), 256 * sizeof(uint32_t), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), pal8.get(), 256 * sizeof(uint32_t), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1787,11 +1853,16 @@ HRESULT DirectX::LoadFromDDSFile(
{ {
return E_FAIL; return E_FAIL;
} }
#else
inFile.read(reinterpret_cast<char*>(pal8.get()), 256 * sizeof(uint32_t));
if (!inFile)
return E_FAIL;
#endif
offset += (256 * sizeof(uint32_t)); offset += (256 * sizeof(uint32_t));
} }
DWORD remaining = fileInfo.EndOfFile.LowPart - offset; size_t remaining = len - offset;
if (remaining == 0) if (remaining == 0)
return E_FAIL; return E_FAIL;
@ -1808,7 +1879,8 @@ HRESULT DirectX::LoadFromDDSFile(
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (!ReadFile(hFile.get(), temp.get(), remaining, &bytesRead, nullptr)) #ifdef WIN32
if (!ReadFile(hFile.get(), temp.get(), static_cast<DWORD>(remaining), &bytesRead, nullptr))
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1819,6 +1891,14 @@ HRESULT DirectX::LoadFromDDSFile(
image.Release(); image.Release();
return E_FAIL; return E_FAIL;
} }
#else
inFile.read(reinterpret_cast<char*>(temp.get()), remaining);
if (!inFile)
{
image.Release();
return E_FAIL;
}
#endif
CP_FLAGS cflags = CP_FLAGS_NONE; CP_FLAGS cflags = CP_FLAGS_NONE;
if (flags & DDS_FLAGS_LEGACY_DWORD) if (flags & DDS_FLAGS_LEGACY_DWORD)
@ -1848,20 +1928,29 @@ HRESULT DirectX::LoadFromDDSFile(
if (remaining < image.GetPixelsSize()) if (remaining < image.GetPixelsSize())
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); return HRESULT_E_HANDLE_EOF;
} }
if (image.GetPixelsSize() > UINT32_MAX) if (image.GetPixelsSize() > UINT32_MAX)
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
} }
#ifdef WIN32
if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
#else
inFile.read(reinterpret_cast<char*>(image.GetPixels()), image.GetPixelsSize());
if (!inFile)
{
image.Release();
return E_FAIL;
}
#endif
if (convFlags & (CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA)) if (convFlags & (CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA))
{ {
@ -1974,11 +2063,7 @@ HRESULT DirectX::SaveToDDSMemory(
if (fastpath) if (fastpath)
{ {
size_t pixsize = images[index].slicePitch; size_t pixsize = images[index].slicePitch;
if (memcpy_s(pDestination, remaining, images[index].pixels, pixsize)) memcpy(pDestination, images[index].pixels, pixsize);
{
blob.Release();
return E_FAIL;
}
pDestination += pixsize; pDestination += pixsize;
remaining -= pixsize; remaining -= pixsize;
@ -2003,11 +2088,7 @@ HRESULT DirectX::SaveToDDSMemory(
size_t tremaining = remaining; size_t tremaining = remaining;
for (size_t j = 0; j < lines; ++j) for (size_t j = 0; j < lines; ++j)
{ {
if (memcpy_s(dPtr, tremaining, sPtr, csize)) memcpy(dPtr, sPtr, csize);
{
blob.Release();
return E_FAIL;
}
sPtr += rowPitch; sPtr += rowPitch;
dPtr += ddsRowPitch; dPtr += ddsRowPitch;
@ -2048,11 +2129,7 @@ HRESULT DirectX::SaveToDDSMemory(
if (fastpath) if (fastpath)
{ {
size_t pixsize = images[index].slicePitch; size_t pixsize = images[index].slicePitch;
if (memcpy_s(pDestination, remaining, images[index].pixels, pixsize)) memcpy(pDestination, images[index].pixels, pixsize);
{
blob.Release();
return E_FAIL;
}
pDestination += pixsize; pDestination += pixsize;
remaining -= pixsize; remaining -= pixsize;
@ -2077,11 +2154,7 @@ HRESULT DirectX::SaveToDDSMemory(
size_t tremaining = remaining; size_t tremaining = remaining;
for (size_t j = 0; j < lines; ++j) for (size_t j = 0; j < lines; ++j)
{ {
if (memcpy_s(dPtr, tremaining, sPtr, csize)) memcpy(dPtr, sPtr, csize);
{
blob.Release();
return E_FAIL;
}
sPtr += rowPitch; sPtr += rowPitch;
dPtr += ddsRowPitch; dPtr += ddsRowPitch;
@ -2133,6 +2206,7 @@ HRESULT DirectX::SaveToDDSFile(
return hr; return hr;
// Create file and write header // Create file and write header
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr)));
#else #else
@ -2155,6 +2229,15 @@ HRESULT DirectX::SaveToDDSFile(
{ {
return E_FAIL; return E_FAIL;
} }
#else // !WIN32
std::ofstream outFile(std::filesystem::path(szFile), std::ios::out | std::ios::binary | std::ios::trunc);
if (!outFile)
return E_FAIL;
outFile.write(reinterpret_cast<char*>(header), static_cast<std::streamsize>(required));
if (!outFile)
return E_FAIL;
#endif
// Write images // Write images
switch (static_cast<DDS_RESOURCE_DIMENSION>(metadata.dimension)) switch (static_cast<DDS_RESOURCE_DIMENSION>(metadata.dimension))
@ -2183,6 +2266,7 @@ HRESULT DirectX::SaveToDDSFile(
if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX)) if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX))
{ {
#ifdef WIN32
if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -2192,6 +2276,11 @@ HRESULT DirectX::SaveToDDSFile(
{ {
return E_FAIL; return E_FAIL;
} }
#else
outFile.write(reinterpret_cast<char*>(images[index].pixels), static_cast<std::streamsize>(ddsSlicePitch));
if (!outFile)
return E_FAIL;
#endif
} }
else else
{ {
@ -2203,13 +2292,14 @@ HRESULT DirectX::SaveToDDSFile(
} }
if (ddsRowPitch > UINT32_MAX) if (ddsRowPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
const uint8_t * __restrict sPtr = images[index].pixels; const uint8_t * __restrict sPtr = images[index].pixels;
size_t lines = ComputeScanlines(metadata.format, images[index].height); size_t lines = ComputeScanlines(metadata.format, images[index].height);
for (size_t j = 0; j < lines; ++j) for (size_t j = 0; j < lines; ++j)
{ {
#ifdef WIN32
if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -2219,6 +2309,11 @@ HRESULT DirectX::SaveToDDSFile(
{ {
return E_FAIL; return E_FAIL;
} }
#else
outFile.write(reinterpret_cast<const char*>(sPtr), static_cast<std::streamsize>(ddsRowPitch));
if (!outFile)
return E_FAIL;
#endif
sPtr += rowPitch; sPtr += rowPitch;
} }
@ -2256,6 +2351,7 @@ HRESULT DirectX::SaveToDDSFile(
if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX)) if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX))
{ {
#ifdef WIN32
if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -2265,6 +2361,11 @@ HRESULT DirectX::SaveToDDSFile(
{ {
return E_FAIL; return E_FAIL;
} }
#else
outFile.write(reinterpret_cast<char*>(images[index].pixels), static_cast<std::streamsize>(ddsSlicePitch));
if (!outFile)
return E_FAIL;
#endif
} }
else else
{ {
@ -2276,13 +2377,14 @@ HRESULT DirectX::SaveToDDSFile(
} }
if (ddsRowPitch > UINT32_MAX) if (ddsRowPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
const uint8_t * __restrict sPtr = images[index].pixels; const uint8_t * __restrict sPtr = images[index].pixels;
size_t lines = ComputeScanlines(metadata.format, images[index].height); size_t lines = ComputeScanlines(metadata.format, images[index].height);
for (size_t j = 0; j < lines; ++j) for (size_t j = 0; j < lines; ++j)
{ {
#ifdef WIN32
if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -2292,7 +2394,11 @@ HRESULT DirectX::SaveToDDSFile(
{ {
return E_FAIL; return E_FAIL;
} }
#else
outFile.write(reinterpret_cast<const char*>(sPtr), static_cast<std::streamsize>(ddsRowPitch));
if (!outFile)
return E_FAIL;
#endif
sPtr += rowPitch; sPtr += rowPitch;
} }
} }
@ -2308,7 +2414,9 @@ HRESULT DirectX::SaveToDDSFile(
return E_FAIL; return E_FAIL;
} }
#ifdef WIN32
delonfail.clear(); delonfail.clear();
#endif
return S_OK; return S_OK;
} }

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexFlipRotate.cpp // DirectXTexFlipRotate.cpp
// //
// DirectX Texture Library - Image flip/rotate operations // DirectX Texture Library - Image flip/rotate operations
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -37,7 +37,7 @@ namespace
if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX
|| destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<IWICBitmap> source; ComPtr<IWICBitmap> source;
HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(srcImage.height), pfGUID, HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(srcImage.height), pfGUID,
@ -63,7 +63,7 @@ namespace
if (memcmp(&pfFR, &pfGUID, sizeof(GUID)) != 0) if (memcmp(&pfFR, &pfGUID, sizeof(GUID)) != 0)
{ {
// Flip/rotate should return the same format as the source... // Flip/rotate should return the same format as the source...
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
UINT nwidth, nheight; UINT nwidth, nheight;
@ -199,7 +199,7 @@ HRESULT DirectX::FlipRotate(
if (IsCompressed(srcImage.format)) if (IsCompressed(srcImage.format))
{ {
// We don't support flip/rotate operations on compressed images // We don't support flip/rotate operations on compressed images
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
static_assert(static_cast<int>(TEX_FR_ROTATE0) == static_cast<int>(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC"); static_assert(static_cast<int>(TEX_FR_ROTATE0) == static_cast<int>(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC");
@ -292,7 +292,7 @@ HRESULT DirectX::FlipRotate(
if (IsCompressed(metadata.format)) if (IsCompressed(metadata.format))
{ {
// We don't support flip/rotate operations on compressed images // We don't support flip/rotate operations on compressed images
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
static_assert(static_cast<int>(TEX_FR_ROTATE0) == static_cast<int>(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC"); static_assert(static_cast<int>(TEX_FR_ROTATE0) == static_cast<int>(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC");

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexHDR.cpp // DirectXTexHDR.cpp
// //
// DirectX Texture Library - Radiance HDR (RGBE) file format reader/writer // DirectX Texture Library - Radiance HDR (RGBE) file format reader/writer
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -17,10 +17,10 @@
// +X width -Y height // +X width -Y height
// -X width +Y height // -X width +Y height
// -X width -Y height // -X width -Y height
// +Y height +X width // +Y height +X width
// -Y height +X width // -Y height +X width
// +Y height -X width // +Y height -X width
// -Y height -X width // -Y height -X width
// //
// All HDR files we've encountered are always written as "-Y height +X width", so // All HDR files we've encountered are always written as "-Y height +X width", so
// we support only that one as that's what other Radiance parsing code does as well. // we support only that one as that's what other Radiance parsing code does as well.
@ -34,6 +34,13 @@
using namespace DirectX; using namespace DirectX;
#ifndef WIN32
#include <cstdarg>
#define strncpy_s strncpy
#define sscanf_s sscanf
#endif
namespace namespace
{ {
const char g_Signature[] = "#?RADIANCE"; const char g_Signature[] = "#?RADIANCE";
@ -70,6 +77,19 @@ namespace
return 0; return 0;
} }
#ifndef WIN32
template<size_t sizeOfBuffer>
inline int sprintf_s(char (&buffer)[sizeOfBuffer], const char* format, ...)
{
// This is adapter code. It is not a full implementation of sprintf_s!
va_list ap;
va_start(ap, format);
int result = vsprintf(buffer, format, ap);
va_end(ap);
return result;
}
#endif
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decodes HDR header // Decodes HDR header
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -86,10 +106,10 @@ namespace
memset(&metadata, 0, sizeof(TexMetadata)); memset(&metadata, 0, sizeof(TexMetadata));
exposure = 1.f; exposure = 1.f;
if (size < sizeof(g_Signature)) if (size < sizeof(g_Signature))
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
// Verify magic signature // Verify magic signature
@ -137,7 +157,7 @@ namespace
if (memcmp(info, g_sRGBE, encodingLen) != 0 && memcmp(info, g_sXYZE, encodingLen) != 0) if (memcmp(info, g_sRGBE, encodingLen) != 0 && memcmp(info, g_sXYZE, encodingLen) != 0)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
formatFound = true; formatFound = true;
@ -217,10 +237,8 @@ namespace
if (orientation[0] != '-' && orientation[1] != 'Y') if (orientation[0] != '-' && orientation[1] != 'Y')
{ {
// We only support the -Y +X orientation (see top of file) // We only support the -Y +X orientation (see top of file)
return HRESULT_FROM_WIN32( return (static_cast<unsigned long>(((orientation[0] == '+' || orientation[0] == '-') && (orientation[1] == 'X' || orientation[1] == 'Y'))))
static_cast<unsigned long>(((orientation[0] == '+' || orientation[0] == '-') && (orientation[1] == 'X' || orientation[1] == 'Y')) ? HRESULT_E_NOT_SUPPORTED : HRESULT_E_INVALID_DATA;
? ERROR_NOT_SUPPORTED : ERROR_INVALID_DATA)
);
} }
uint32_t height = 0; uint32_t height = 0;
@ -240,7 +258,7 @@ namespace
else if (*ptr != '+') else if (*ptr != '+')
{ {
// We only support the -Y +X orientation (see top of file) // We only support the -Y +X orientation (see top of file)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
++ptr; ++ptr;
@ -251,7 +269,7 @@ namespace
else if (*ptr != 'X') else if (*ptr != 'X')
{ {
// We only support the -Y +X orientation (see top of file) // We only support the -Y +X orientation (see top of file)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
++ptr; ++ptr;
@ -266,7 +284,7 @@ namespace
if (!width || !height) if (!width || !height)
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
if (size == 0) if (size == 0)
@ -580,6 +598,7 @@ HRESULT DirectX::GetMetadataFromHDRFile(const wchar_t* szFile, TexMetadata& meta
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
@ -601,26 +620,57 @@ HRESULT DirectX::GetMetadataFromHDRFile(const wchar_t* szFile, TexMetadata& meta
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid HDR file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid HDR file)
if (fileInfo.EndOfFile.HighPart > 0) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
} }
size_t len = fileInfo.EndOfFile.LowPart;
#else // !WIN32
std::ifstream inFile(std::filesystem::path(szFile), std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
return E_FAIL;
std::streampos fileLen = inFile.tellg();
if (!inFile)
return E_FAIL;
if (fileLen > UINT32_MAX)
return HRESULT_E_FILE_TOO_LARGE;
inFile.seekg(0, std::ios::beg);
if (!inFile)
return E_FAIL;
size_t len = fileLen;
#endif
// Need at least enough data to fill the standard header to be a valid HDR // Need at least enough data to fill the standard header to be a valid HDR
if (fileInfo.EndOfFile.LowPart < sizeof(g_Signature)) if (len < sizeof(g_Signature))
{ {
return E_FAIL; return E_FAIL;
} }
// Read the first part of the file to find the header // Read the first part of the file to find the header
uint8_t header[8192] = {}; uint8_t header[8192] = {};
#ifdef WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, std::min<DWORD>(sizeof(header), fileInfo.EndOfFile.LowPart), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, std::min<DWORD>(sizeof(header), fileInfo.EndOfFile.LowPart), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
auto headerLen = static_cast<size_t>(bytesRead);
#else
auto headerLen = std::min<size_t>(sizeof(header), len);
inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile)
return E_FAIL;
#endif
size_t offset; size_t offset;
float exposure; float exposure;
return DecodeHDRHeader(header, bytesRead, metadata, offset, exposure); return DecodeHDRHeader(header, headerLen, metadata, offset, exposure);
} }
@ -685,7 +735,7 @@ HRESULT DirectX::LoadFromHDRMemory(const void* pSource, size_t size, TexMetadata
pixelLen -= 4; pixelLen -= 4;
auto scanLine = reinterpret_cast<float*>(destPtr); auto scanLine = reinterpret_cast<float*>(destPtr);
if (inColor[0] == 2 && inColor[1] == 2 && inColor[2] < 128) if (inColor[0] == 2 && inColor[1] == 2 && inColor[2] < 128)
{ {
// Adaptive Run Length Encoding (RLE) // Adaptive Run Length Encoding (RLE)
@ -852,6 +902,7 @@ HRESULT DirectX::LoadFromHDRFile(const wchar_t* szFile, TexMetadata* metadata, S
image.Release(); image.Release();
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
@ -873,22 +924,43 @@ HRESULT DirectX::LoadFromHDRFile(const wchar_t* szFile, TexMetadata* metadata, S
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid HDR file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid HDR file)
if (fileInfo.EndOfFile.HighPart > 0) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
} }
size_t len = fileInfo.EndOfFile.LowPart;
#else // !WIN32
std::ifstream inFile(std::filesystem::path(szFile), std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
return E_FAIL;
std::streampos fileLen = inFile.tellg();
if (!inFile)
return E_FAIL;
if (fileLen > UINT32_MAX)
return HRESULT_E_FILE_TOO_LARGE;
inFile.seekg(0, std::ios::beg);
if (!inFile)
return E_FAIL;
size_t len = fileLen;
#endif
// Need at least enough data to fill the header to be a valid HDR // Need at least enough data to fill the header to be a valid HDR
if (fileInfo.EndOfFile.LowPart < sizeof(g_Signature)) if (len < sizeof(g_Signature))
{ {
return E_FAIL; return E_FAIL;
} }
// Read file // Read file
std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[fileInfo.EndOfFile.LowPart]); std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[len]);
if (!temp) if (!temp)
{ {
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
#ifdef WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), temp.get(), fileInfo.EndOfFile.LowPart, &bytesRead, nullptr)) if (!ReadFile(hFile.get(), temp.get(), fileInfo.EndOfFile.LowPart, &bytesRead, nullptr))
{ {
@ -899,8 +971,13 @@ HRESULT DirectX::LoadFromHDRFile(const wchar_t* szFile, TexMetadata* metadata, S
{ {
return E_FAIL; return E_FAIL;
} }
#else
inFile.read(reinterpret_cast<char*>(temp.get()), len);
if (!inFile)
return E_FAIL;
#endif
return LoadFromHDRMemory(temp.get(), fileInfo.EndOfFile.LowPart, metadata, image); return LoadFromHDRMemory(temp.get(), len, metadata, image);
} }
@ -917,7 +994,7 @@ HRESULT DirectX::SaveToHDRMemory(const Image& image, Blob& blob) noexcept
{ {
// Images larger than this can't be RLE encoded. They are technically allowed as // Images larger than this can't be RLE encoded. They are technically allowed as
// uncompresssed, but we just don't support them. // uncompresssed, but we just don't support them.
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
int fpp; int fpp;
@ -932,7 +1009,7 @@ HRESULT DirectX::SaveToHDRMemory(const Image& image, Blob& blob) noexcept
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
blob.Release(); blob.Release();
@ -952,7 +1029,7 @@ HRESULT DirectX::SaveToHDRMemory(const Image& image, Blob& blob) noexcept
// Copy header // Copy header
auto dPtr = static_cast<uint8_t*>(blob.GetBufferPointer()); auto dPtr = static_cast<uint8_t*>(blob.GetBufferPointer());
assert(dPtr != nullptr); assert(dPtr != nullptr);
memcpy_s(dPtr, blob.GetBufferSize(), header, headerLen); memcpy(dPtr, header, headerLen);
dPtr += headerLen; dPtr += headerLen;
#ifdef DISABLE_COMPRESS #ifdef DISABLE_COMPRESS
@ -1029,7 +1106,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
{ {
// Images larger than this can't be RLE encoded. They are technically allowed as // Images larger than this can't be RLE encoded. They are technically allowed as
// uncompresssed, but we just don't support them. // uncompresssed, but we just don't support them.
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
int fpp; int fpp;
@ -1044,10 +1121,11 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
// Create file and write header // Create file and write header
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr)));
#else #else
@ -1059,12 +1137,17 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
} }
auto_delete_file delonfail(hFile.get()); auto_delete_file delonfail(hFile.get());
#else // !WIN32
std::ofstream outFile(std::filesystem::path(szFile), std::ios::out | std::ios::binary | std::ios::trunc);
if (!outFile)
return E_FAIL;
#endif
uint64_t pitch = uint64_t(image.width) * 4u; uint64_t pitch = uint64_t(image.width) * 4u;
uint64_t slicePitch = uint64_t(image.height) * pitch; uint64_t slicePitch = uint64_t(image.height) * pitch;
if (pitch > UINT32_MAX) if (pitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
size_t rowPitch = static_cast<size_t>(pitch); size_t rowPitch = static_cast<size_t>(pitch);
@ -1078,6 +1161,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
return hr; return hr;
// Write blob // Write blob
#ifdef WIN32
auto bytesToWrite = static_cast<const DWORD>(blob.GetBufferSize()); auto bytesToWrite = static_cast<const DWORD>(blob.GetBufferSize());
DWORD bytesWritten; DWORD bytesWritten;
if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr))
@ -1089,6 +1173,13 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
{ {
return E_FAIL; return E_FAIL;
} }
#else
outFile.write(reinterpret_cast<char*>(blob.GetBufferPointer()),
static_cast<std::streamsize>(blob.GetBufferSize()));
if (!outFile)
return E_FAIL;
#endif
} }
else else
{ {
@ -1103,6 +1194,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
char header[256] = {}; char header[256] = {};
sprintf_s(header, g_Header, image.height, image.width); sprintf_s(header, g_Header, image.height, image.width);
#ifdef WIN32
auto headerLen = static_cast<DWORD>(strlen(header)); auto headerLen = static_cast<DWORD>(strlen(header));
DWORD bytesWritten; DWORD bytesWritten;
@ -1113,6 +1205,11 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
if (bytesWritten != headerLen) if (bytesWritten != headerLen)
return E_FAIL; return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(header), static_cast<std::streamsize>(strlen(header)));
if (!outFile)
return E_FAIL;
#endif
#ifdef DISABLE_COMPRESS #ifdef DISABLE_COMPRESS
// Uncompressed write // Uncompressed write
@ -1122,6 +1219,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
FloatToRGBE(rgbe, reinterpret_cast<const float*>(sPtr), image.width, fpp); FloatToRGBE(rgbe, reinterpret_cast<const float*>(sPtr), image.width, fpp);
sPtr += image.rowPitch; sPtr += image.rowPitch;
#ifdef WIN32
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1129,6 +1227,12 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
if (bytesWritten != rowPitch) if (bytesWritten != rowPitch)
return E_FAIL; return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(rgbe), static_cast<std::streamsize>(rowPitch));
if (!outFile)
return E_FAIL;
#endif
} }
#else #else
auto enc = temp.get() + rowPitch; auto enc = temp.get() + rowPitch;
@ -1150,8 +1254,9 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
if (encSize > 0) if (encSize > 0)
{ {
if (encSize > UINT32_MAX) if (encSize > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
#ifdef WIN32
if (!WriteFile(hFile.get(), enc, static_cast<DWORD>(encSize), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), enc, static_cast<DWORD>(encSize), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1159,9 +1264,15 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
if (bytesWritten != encSize) if (bytesWritten != encSize)
return E_FAIL; return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(enc), static_cast<std::streamsize>(encSize));
if (!outFile)
return E_FAIL;
#endif
} }
else else
{ {
#ifdef WIN32
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1169,12 +1280,19 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
if (bytesWritten != rowPitch) if (bytesWritten != rowPitch)
return E_FAIL; return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(rgbe), static_cast<std::streamsize>(rowPitch));
if (!outFile)
return E_FAIL;
#endif
} }
} }
#endif #endif
} }
#ifdef WIN32
delonfail.clear(); delonfail.clear();
#endif
return S_OK; return S_OK;
} }

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexImage.cpp // DirectXTexImage.cpp
// //
// DirectX Texture Library - Image container // DirectX Texture Library - Image container
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -20,6 +20,19 @@ namespace DirectX
using namespace DirectX; using namespace DirectX;
#ifndef WIN32
namespace
{
inline void * _aligned_malloc(size_t size, size_t alignment)
{
size = (size + alignment - 1) & ~(alignment - 1);
return std::aligned_alloc(alignment, size);
}
#define _aligned_free free
}
#endif
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Determines number of image array entries and pixel size // Determines number of image array entries and pixel size
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -288,7 +301,7 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc
return E_INVALIDARG; return E_INVALIDARG;
if (IsPalettized(mdata.format)) if (IsPalettized(mdata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
size_t mipLevels = mdata.mipLevels; size_t mipLevels = mdata.mipLevels;
@ -325,7 +338,7 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
Release(); Release();
@ -342,7 +355,7 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc
size_t pixelSize, nimages; size_t pixelSize, nimages;
if (!_DetermineImageArray(m_metadata, flags, nimages, pixelSize)) if (!_DetermineImageArray(m_metadata, flags, nimages, pixelSize))
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
m_image = new (std::nothrow) Image[nimages]; m_image = new (std::nothrow) Image[nimages];
if (!m_image) if (!m_image)
@ -390,7 +403,7 @@ HRESULT ScratchImage::Initialize2D(DXGI_FORMAT fmt, size_t width, size_t height,
return E_INVALIDARG; return E_INVALIDARG;
if (IsPalettized(fmt)) if (IsPalettized(fmt))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (!_CalculateMipLevels(width, height, mipLevels)) if (!_CalculateMipLevels(width, height, mipLevels))
return E_INVALIDARG; return E_INVALIDARG;
@ -409,7 +422,7 @@ HRESULT ScratchImage::Initialize2D(DXGI_FORMAT fmt, size_t width, size_t height,
size_t pixelSize, nimages; size_t pixelSize, nimages;
if (!_DetermineImageArray(m_metadata, flags, nimages, pixelSize)) if (!_DetermineImageArray(m_metadata, flags, nimages, pixelSize))
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
m_image = new (std::nothrow) Image[nimages]; m_image = new (std::nothrow) Image[nimages];
if (!m_image) if (!m_image)
@ -441,7 +454,7 @@ HRESULT ScratchImage::Initialize3D(DXGI_FORMAT fmt, size_t width, size_t height,
return E_INVALIDARG; return E_INVALIDARG;
if (IsPalettized(fmt)) if (IsPalettized(fmt))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (!_CalculateMipLevels3D(width, height, depth, mipLevels)) if (!_CalculateMipLevels3D(width, height, depth, mipLevels))
return E_INVALIDARG; return E_INVALIDARG;
@ -460,7 +473,7 @@ HRESULT ScratchImage::Initialize3D(DXGI_FORMAT fmt, size_t width, size_t height,
size_t pixelSize, nimages; size_t pixelSize, nimages;
if (!_DetermineImageArray(m_metadata, flags, nimages, pixelSize)) if (!_DetermineImageArray(m_metadata, flags, nimages, pixelSize))
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
m_image = new (std::nothrow) Image[nimages]; m_image = new (std::nothrow) Image[nimages];
if (!m_image) if (!m_image)
@ -533,7 +546,7 @@ HRESULT ScratchImage::InitializeFromImage(const Image& srcImage, bool allow1D, C
for (size_t y = 0; y < rowCount; ++y) for (size_t y = 0; y < rowCount; ++y)
{ {
memcpy_s(dptr, dpitch, sptr, size); memcpy(dptr, sptr, size);
sptr += spitch; sptr += spitch;
dptr += dpitch; dptr += dpitch;
} }
@ -592,7 +605,7 @@ HRESULT ScratchImage::InitializeArrayFromImages(const Image* images, size_t nIma
for (size_t y = 0; y < rowCount; ++y) for (size_t y = 0; y < rowCount; ++y)
{ {
memcpy_s(dptr, dpitch, sptr, size); memcpy(dptr, sptr, size);
sptr += spitch; sptr += spitch;
dptr += dpitch; dptr += dpitch;
} }
@ -668,7 +681,7 @@ HRESULT ScratchImage::Initialize3DFromImages(const Image* images, size_t depth,
for (size_t y = 0; y < rowCount; ++y) for (size_t y = 0; y < rowCount; ++y)
{ {
memcpy_s(dptr, dpitch, sptr, size); memcpy(dptr, sptr, size);
sptr += spitch; sptr += spitch;
dptr += dpitch; dptr += dpitch;
} }

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexMipMaps.cpp // DirectXTexMipMaps.cpp
// //
// DirectX Texture Library - Mip-map generation // DirectX Texture Library - Mip-map generation
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -64,7 +64,7 @@ namespace
return mipLevels; return mipLevels;
} }
#ifdef WIN32
HRESULT EnsureWicBitmapPixelFormat( HRESULT EnsureWicBitmapPixelFormat(
_In_ IWICImagingFactory* pWIC, _In_ IWICImagingFactory* pWIC,
_In_ IWICBitmap* src, _In_ IWICBitmap* src,
@ -116,6 +116,7 @@ namespace
return hr; return hr;
} }
#endif // WIN32
#if DIRECTX_MATH_VERSION >= 310 #if DIRECTX_MATH_VERSION >= 310
@ -349,9 +350,11 @@ namespace DirectX
bool _CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels) noexcept; bool _CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels) noexcept;
// Also used by Compress // Also used by Compress
#ifdef WIN32
HRESULT _ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original, HRESULT _ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original,
_In_ size_t newWidth, _In_ size_t newHeight, _In_ TEX_FILTER_FLAGS filter, _Inout_ const Image* img) noexcept; _In_ size_t newWidth, _In_ size_t newHeight, _In_ TEX_FILTER_FLAGS filter, _Inout_ const Image* img) noexcept;
// Also used by Resize // Also used by Resize
#endif
bool _CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels) noexcept bool _CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels) noexcept
{ {
@ -391,6 +394,7 @@ namespace DirectX
return true; return true;
} }
#ifdef WIN32
//--- Resizing color and alpha channels separately using WIC --- //--- Resizing color and alpha channels separately using WIC ---
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT _ResizeSeparateColorAndAlpha( HRESULT _ResizeSeparateColorAndAlpha(
@ -595,7 +599,7 @@ namespace DirectX
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<IWICBitmap> wicBitmap; ComPtr<IWICBitmap> wicBitmap;
hr = EnsureWicBitmapPixelFormat(pWIC, resizedColorWithAlpha.Get(), filter, desiredPixelFormat, wicBitmap.GetAddressOf()); hr = EnsureWicBitmapPixelFormat(pWIC, resizedColorWithAlpha.Get(), filter, desiredPixelFormat, wicBitmap.GetAddressOf());
@ -607,10 +611,12 @@ namespace DirectX
return hr; return hr;
} }
#endif // WIN32
} }
namespace namespace
{ {
#ifdef WIN32
//--- determine when to use WIC vs. non-WIC paths --- //--- determine when to use WIC vs. non-WIC paths ---
bool UseWICFiltering(_In_ DXGI_FORMAT format, _In_ TEX_FILTER_FLAGS filter) noexcept bool UseWICFiltering(_In_ DXGI_FORMAT format, _In_ TEX_FILTER_FLAGS filter) noexcept
{ {
@ -705,7 +711,7 @@ namespace
size_t height = baseImage.height; size_t height = baseImage.height;
if (baseImage.rowPitch > UINT32_MAX || baseImage.slicePitch > UINT32_MAX) if (baseImage.rowPitch > UINT32_MAX || baseImage.slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<IWICBitmap> source; ComPtr<IWICBitmap> source;
HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(width), static_cast<UINT>(height), pfGUID, HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(width), static_cast<UINT>(height), pfGUID,
@ -776,7 +782,7 @@ namespace
return hr; return hr;
if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
hr = scaler->Initialize(source.Get(), static_cast<UINT>(width), static_cast<UINT>(height), _GetWICInterp(filter)); hr = scaler->Initialize(source.Get(), static_cast<UINT>(width), static_cast<UINT>(height), _GetWICInterp(filter));
if (FAILED(hr)) if (FAILED(hr))
@ -822,6 +828,7 @@ namespace
return S_OK; return S_OK;
} }
#endif // WIN32
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -873,7 +880,7 @@ namespace
for (size_t h = 0; h < mdata.height; ++h) for (size_t h = 0; h < mdata.height; ++h)
{ {
size_t msize = std::min<size_t>(dest->rowPitch, rowPitch); size_t msize = std::min<size_t>(dest->rowPitch, rowPitch);
memcpy_s(pDest, dest->rowPitch, pSrc, msize); memcpy(pDest, pSrc, msize);
pSrc += rowPitch; pSrc += rowPitch;
pDest += dest->rowPitch; pDest += dest->rowPitch;
} }
@ -1618,7 +1625,7 @@ namespace
for (size_t h = 0; h < height; ++h) for (size_t h = 0; h < height; ++h)
{ {
size_t msize = std::min<size_t>(dest->rowPitch, rowPitch); size_t msize = std::min<size_t>(dest->rowPitch, rowPitch);
memcpy_s(pDest, dest->rowPitch, pSrc, msize); memcpy(pDest, pSrc, msize);
pSrc += rowPitch; pSrc += rowPitch;
pDest += dest->rowPitch; pDest += dest->rowPitch;
} }
@ -2791,13 +2798,14 @@ HRESULT DirectX::GenerateMipMaps(
if (IsCompressed(baseImage.format) || IsTypeless(baseImage.format) || IsPlanar(baseImage.format) || IsPalettized(baseImage.format)) if (IsCompressed(baseImage.format) || IsTypeless(baseImage.format) || IsPlanar(baseImage.format) || IsPalettized(baseImage.format))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
HRESULT hr = E_UNEXPECTED; HRESULT hr = E_UNEXPECTED;
static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK"); static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK");
#ifdef WIN32
bool usewic = UseWICFiltering(baseImage.format, filter); bool usewic = UseWICFiltering(baseImage.format, filter);
WICPixelFormatGUID pfGUID = {}; WICPixelFormatGUID pfGUID = {};
@ -2811,7 +2819,7 @@ HRESULT DirectX::GenerateMipMaps(
if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX)
{ {
if (filter & TEX_FILTER_FORCE_WIC) if (filter & TEX_FILTER_FORCE_WIC)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
usewic = false; usewic = false;
} }
@ -2872,10 +2880,11 @@ HRESULT DirectX::GenerateMipMaps(
} }
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
else else
#endif // WIN32
{ {
//--- Use custom filters to generate mipmaps ---------------------------------- //--- Use custom filters to generate mipmaps ----------------------------------
TexMetadata mdata = {}; TexMetadata mdata = {};
@ -2954,7 +2963,7 @@ HRESULT DirectX::GenerateMipMaps(
return hr; return hr;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
} }
@ -2973,7 +2982,7 @@ HRESULT DirectX::GenerateMipMaps(
if (metadata.IsVolumemap() if (metadata.IsVolumemap()
|| IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format)) || IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (!_CalculateMipLevels(metadata.width, metadata.height, levels)) if (!_CalculateMipLevels(metadata.width, metadata.height, levels))
return E_INVALIDARG; return E_INVALIDARG;
@ -3011,6 +3020,7 @@ HRESULT DirectX::GenerateMipMaps(
static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK"); static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK");
#ifdef WIN32
bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter); bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter);
WICPixelFormatGUID pfGUID = {}; WICPixelFormatGUID pfGUID = {};
@ -3024,7 +3034,7 @@ HRESULT DirectX::GenerateMipMaps(
if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX)
{ {
if (filter & TEX_FILTER_FORCE_WIC) if (filter & TEX_FILTER_FORCE_WIC)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
usewic = false; usewic = false;
} }
@ -3098,10 +3108,11 @@ HRESULT DirectX::GenerateMipMaps(
} }
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
else else
#endif // WIN32
{ {
//--- Use custom filters to generate mipmaps ---------------------------------- //--- Use custom filters to generate mipmaps ----------------------------------
TexMetadata mdata2 = metadata; TexMetadata mdata2 = metadata;
@ -3182,7 +3193,7 @@ HRESULT DirectX::GenerateMipMaps(
return hr; return hr;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
} }
@ -3203,7 +3214,7 @@ HRESULT DirectX::GenerateMipMaps3D(
return E_INVALIDARG; return E_INVALIDARG;
if (filter & TEX_FILTER_FORCE_WIC) if (filter & TEX_FILTER_FORCE_WIC)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
DXGI_FORMAT format = baseImages[0].format; DXGI_FORMAT format = baseImages[0].format;
size_t width = baseImages[0].width; size_t width = baseImages[0].width;
@ -3228,7 +3239,7 @@ HRESULT DirectX::GenerateMipMaps3D(
} }
if (IsCompressed(format) || IsTypeless(format) || IsPlanar(format) || IsPalettized(format)) if (IsCompressed(format) || IsTypeless(format) || IsPlanar(format) || IsPalettized(format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK"); static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK");
@ -3294,7 +3305,7 @@ HRESULT DirectX::GenerateMipMaps3D(
return hr; return hr;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
@ -3311,11 +3322,11 @@ HRESULT DirectX::GenerateMipMaps3D(
return E_INVALIDARG; return E_INVALIDARG;
if (filter & TEX_FILTER_FORCE_WIC) if (filter & TEX_FILTER_FORCE_WIC)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (!metadata.IsVolumemap() if (!metadata.IsVolumemap()
|| IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format)) || IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (!_CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, levels)) if (!_CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, levels))
return E_INVALIDARG; return E_INVALIDARG;
@ -3410,7 +3421,7 @@ HRESULT DirectX::GenerateMipMaps3D(
return hr; return hr;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
@ -3428,7 +3439,7 @@ HRESULT DirectX::ScaleMipMapsAlphaForCoverage(
if (metadata.IsVolumemap() if (metadata.IsVolumemap()
|| IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format)) || IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (srcImages[0].format != metadata.format || srcImages[0].width != metadata.width || srcImages[0].height != metadata.height) if (srcImages[0].format != metadata.format || srcImages[0].width != metadata.width || srcImages[0].height != metadata.height)
{ {
@ -3458,7 +3469,7 @@ HRESULT DirectX::ScaleMipMapsAlphaForCoverage(
for (size_t h = 0; h < metadata.height; ++h) for (size_t h = 0; h < metadata.height; ++h)
{ {
size_t msize = std::min<size_t>(dest->rowPitch, rowPitch); size_t msize = std::min<size_t>(dest->rowPitch, rowPitch);
memcpy_s(pDest, dest->rowPitch, pSrc, msize); memcpy(pDest, pSrc, msize);
pSrc += rowPitch; pSrc += rowPitch;
pDest += dest->rowPitch; pDest += dest->rowPitch;
} }
@ -3482,6 +3493,6 @@ HRESULT DirectX::ScaleMipMapsAlphaForCoverage(
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
return S_OK; return S_OK;
} }

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexMisc.cpp // DirectXTexMisc.cpp
// //
// DirectX Texture Library - Misc image operations // DirectX Texture Library - Misc image operations
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -13,6 +13,11 @@
using namespace DirectX; using namespace DirectX;
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-attributes"
#endif
namespace namespace
{ {
const XMVECTORF32 g_Gamma22 = { { { 2.2f, 2.2f, 2.2f, 1.f } } }; const XMVECTORF32 g_Gamma22 = { { { 2.2f, 2.2f, 2.2f, 1.f } } };
@ -261,7 +266,7 @@ namespace
//===================================================================================== //=====================================================================================
// Entry points // Entry points
//===================================================================================== //=====================================================================================
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Copies a rectangle from one image into another // Copies a rectangle from one image into another
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -280,7 +285,7 @@ HRESULT DirectX::CopyRectangle(
if (IsCompressed(srcImage.format) || IsCompressed(dstImage.format) if (IsCompressed(srcImage.format) || IsCompressed(dstImage.format)
|| IsPlanar(srcImage.format) || IsPlanar(dstImage.format) || IsPlanar(srcImage.format) || IsPlanar(dstImage.format)
|| IsPalettized(srcImage.format) || IsPalettized(dstImage.format)) || IsPalettized(srcImage.format) || IsPalettized(dstImage.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
// Validate rectangle/offset // Validate rectangle/offset
if (!srcRect.w || !srcRect.h || ((srcRect.x + srcRect.w) > srcImage.width) || ((srcRect.y + srcRect.h) > srcImage.height)) if (!srcRect.w || !srcRect.h || ((srcRect.x + srcRect.w) > srcImage.width) || ((srcRect.y + srcRect.h) > srcImage.height))
@ -301,7 +306,7 @@ HRESULT DirectX::CopyRectangle(
if (sbpp < 8) if (sbpp < 8)
{ {
// We don't support monochrome (DXGI_FORMAT_R1_UNORM) // We don't support monochrome (DXGI_FORMAT_R1_UNORM)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
const uint8_t* pEndSrc = srcImage.pixels + srcImage.rowPitch*srcImage.height; const uint8_t* pEndSrc = srcImage.pixels + srcImage.rowPitch*srcImage.height;
@ -322,7 +327,7 @@ HRESULT DirectX::CopyRectangle(
if (((pSrc + copyW) > pEndSrc) || (pDest > pEndDest)) if (((pSrc + copyW) > pEndSrc) || (pDest > pEndDest))
return E_FAIL; return E_FAIL;
memcpy_s(pDest, size_t(pEndDest - pDest), pSrc, copyW); memcpy(pDest, pSrc, copyW);
pSrc += srcImage.rowPitch; pSrc += srcImage.rowPitch;
pDest += dstImage.rowPitch; pDest += dstImage.rowPitch;
@ -339,7 +344,7 @@ HRESULT DirectX::CopyRectangle(
if (dbpp < 8) if (dbpp < 8)
{ {
// We don't support monochrome (DXGI_FORMAT_R1_UNORM) // We don't support monochrome (DXGI_FORMAT_R1_UNORM)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
// Round to bytes // Round to bytes
@ -374,7 +379,7 @@ HRESULT DirectX::CopyRectangle(
return S_OK; return S_OK;
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Computes the Mean-Squared-Error (MSE) between two images // Computes the Mean-Squared-Error (MSE) between two images
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -398,7 +403,7 @@ HRESULT DirectX::ComputeMSE(
if (IsPlanar(image1.format) || IsPlanar(image2.format) if (IsPlanar(image1.format) || IsPlanar(image2.format)
|| IsPalettized(image1.format) || IsPalettized(image2.format) || IsPalettized(image1.format) || IsPalettized(image2.format)
|| IsTypeless(image1.format) || IsTypeless(image2.format)) || IsTypeless(image1.format) || IsTypeless(image2.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (IsCompressed(image1.format)) if (IsCompressed(image1.format))
{ {
@ -478,7 +483,7 @@ HRESULT DirectX::EvaluateImage(
return E_INVALIDARG; return E_INVALIDARG;
if (IsPlanar(image.format) || IsPalettized(image.format) || IsTypeless(image.format)) if (IsPlanar(image.format) || IsPalettized(image.format) || IsTypeless(image.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (IsCompressed(image.format)) if (IsCompressed(image.format))
{ {
@ -513,7 +518,7 @@ HRESULT DirectX::EvaluateImage(
return E_INVALIDARG; return E_INVALIDARG;
if (IsPlanar(metadata.format) || IsPalettized(metadata.format) || IsTypeless(metadata.format)) if (IsPlanar(metadata.format) || IsPalettized(metadata.format) || IsTypeless(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (metadata.width > UINT32_MAX if (metadata.width > UINT32_MAX
|| metadata.height > UINT32_MAX) || metadata.height > UINT32_MAX)
@ -607,7 +612,7 @@ HRESULT DirectX::TransformImage(
return E_INVALIDARG; return E_INVALIDARG;
if (IsPlanar(image.format) || IsPalettized(image.format) || IsCompressed(image.format) || IsTypeless(image.format)) if (IsPlanar(image.format) || IsPalettized(image.format) || IsCompressed(image.format) || IsTypeless(image.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
HRESULT hr = result.Initialize2D(image.format, image.width, image.height, 1, 1); HRESULT hr = result.Initialize2D(image.format, image.width, image.height, 1, 1);
if (FAILED(hr)) if (FAILED(hr))
@ -626,7 +631,7 @@ HRESULT DirectX::TransformImage(
result.Release(); result.Release();
return hr; return hr;
} }
return S_OK; return S_OK;
} }
@ -641,7 +646,7 @@ HRESULT DirectX::TransformImage(
return E_INVALIDARG; return E_INVALIDARG;
if (IsPlanar(metadata.format) || IsPalettized(metadata.format) || IsCompressed(metadata.format) || IsTypeless(metadata.format)) if (IsPlanar(metadata.format) || IsPalettized(metadata.format) || IsCompressed(metadata.format) || IsTypeless(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (metadata.width > UINT32_MAX if (metadata.width > UINT32_MAX
|| metadata.height > UINT32_MAX) || metadata.height > UINT32_MAX)

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexNormalMaps.cpp // DirectXTexNormalMaps.cpp
// //
// DirectX Texture Library - Normal map operations // DirectX Texture Library - Normal map operations
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -84,7 +84,7 @@ namespace
return E_FAIL; return E_FAIL;
if (!(convFlags & (CONVF_UNORM | CONVF_SNORM | CONVF_FLOAT))) if (!(convFlags & (CONVF_UNORM | CONVF_SNORM | CONVF_FLOAT)))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
const size_t width = srcImage.width; const size_t width = srcImage.width;
const size_t height = srcImage.height; const size_t height = srcImage.height;
@ -124,7 +124,7 @@ namespace
if (flags & CNMAP_MIRROR_V) if (flags & CNMAP_MIRROR_V)
{ {
// Mirror first row // Mirror first row
memcpy_s(row0, rowPitch, row1, rowPitch); memcpy(row0, row1, rowPitch);
} }
else else
{ {
@ -248,7 +248,7 @@ namespace
//===================================================================================== //=====================================================================================
// Entry points // Entry points
//===================================================================================== //=====================================================================================
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Generates a normal map from a height-map // Generates a normal map from a height-map
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -282,7 +282,7 @@ HRESULT DirectX::ComputeNormalMap(
|| IsTypeless(format) || IsTypeless(srcImage.format) || IsTypeless(format) || IsTypeless(srcImage.format)
|| IsPlanar(format) || IsPlanar(srcImage.format) || IsPlanar(format) || IsPlanar(srcImage.format)
|| IsPalettized(format) || IsPalettized(srcImage.format)) || IsPalettized(format) || IsPalettized(srcImage.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
// Setup target image // Setup target image
normalMap.Release(); normalMap.Release();
@ -325,7 +325,7 @@ HRESULT DirectX::ComputeNormalMap(
|| IsTypeless(format) || IsTypeless(metadata.format) || IsTypeless(format) || IsTypeless(metadata.format)
|| IsPlanar(format) || IsPlanar(metadata.format) || IsPlanar(format) || IsPlanar(metadata.format)
|| IsPalettized(format) || IsPalettized(metadata.format)) || IsPalettized(format) || IsPalettized(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
static_assert(CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask"); static_assert(CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask");
switch (flags & 0xf) switch (flags & 0xf)
@ -371,7 +371,7 @@ HRESULT DirectX::ComputeNormalMap(
if (IsCompressed(src.format) || IsTypeless(src.format)) if (IsCompressed(src.format) || IsTypeless(src.format))
{ {
normalMaps.Release(); normalMaps.Release();
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
if (src.width != dest[index].width || src.height != dest[index].height) if (src.width != dest[index].width || src.height != dest[index].height)

View File

@ -70,6 +70,7 @@
#pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic ignored "-Wunknown-pragmas"
#endif #endif
#if defined(WIN32) || defined(WINAPI_FAMILY)
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
@ -104,10 +105,11 @@
#else #else
#include <d3d11_1.h> #include <d3d11_1.h>
#endif #endif
#else // !WIN32
#define _XM_NO_XMVECTOR_OVERLOADS_ #include <wsl/winadapter.h>
#include <wsl/wrladapter.h>
#include "DirectXTex.h" #include <directx/d3d12.h>
#endif
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
@ -117,17 +119,31 @@
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#ifndef WIN32
#include <fstream>
#include <filesystem>
#include <thread>
#endif
#define _XM_NO_XMVECTOR_OVERLOADS_
#include <DirectXPackedVector.h> #include <DirectXPackedVector.h>
#if (DIRECTX_MATH_VERSION < 315) #if (DIRECTX_MATH_VERSION < 315)
#define XM_ALIGNED_DATA(x) __declspec(align(x)) #define XM_ALIGNED_DATA(x) __declspec(align(x))
#endif #endif
#include "DirectXTex.h"
#include <malloc.h> #include <malloc.h>
#ifdef WIN32
#include <Ole2.h> #include <Ole2.h>
#include <wincodec.h> #include <wincodec.h>
#include <wrl\client.h> #include <wrl\client.h>
#else
using WICPixelFormatGUID = GUID;
#endif
#include "scoped.h" #include "scoped.h"
@ -147,10 +163,34 @@
#define XBOX_DXGI_FORMAT_R4G4_UNORM DXGI_FORMAT(190) #define XBOX_DXGI_FORMAT_R4G4_UNORM DXGI_FORMAT(190)
// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)
#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast<HRESULT>(0x80070216L)
// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
#define HRESULT_E_NOT_SUPPORTED static_cast<HRESULT>(0x80070032L)
// HRESULT_FROM_WIN32(ERROR_HANDLE_EOF)
#define HRESULT_E_HANDLE_EOF static_cast<HRESULT>(0x80070026L)
// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
#define HRESULT_E_INVALID_DATA static_cast<HRESULT>(0x8007000DL)
// HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE)
#define HRESULT_E_FILE_TOO_LARGE static_cast<HRESULT>(0x800700DFL)
// HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE)
#define HRESULT_E_CANNOT_MAKE static_cast<HRESULT>(0x80070052L)
// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)
#ifndef E_NOT_SUFFICIENT_BUFFER
#define E_NOT_SUFFICIENT_BUFFER static_cast<HRESULT>(0x8007007AL)
#endif
namespace DirectX namespace DirectX
{ {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// WIC helper functions // WIC helper functions
#ifdef WIN32
DXGI_FORMAT __cdecl _WICToDXGI(_In_ const GUID& guid) noexcept; DXGI_FORMAT __cdecl _WICToDXGI(_In_ const GUID& guid) noexcept;
bool __cdecl _DXGIToWIC(_In_ DXGI_FORMAT format, _Out_ GUID& guid, _In_ bool ignoreRGBvsBGR = false) noexcept; bool __cdecl _DXGIToWIC(_In_ DXGI_FORMAT format, _Out_ GUID& guid, _In_ bool ignoreRGBvsBGR = false) noexcept;
@ -235,7 +275,7 @@ namespace DirectX
return WICBitmapInterpolationModeFant; return WICBitmapInterpolationModeFant;
} }
} }
#endif // WIN32
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Image helper functions // Image helper functions

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexPMAlpha.cpp // DirectXTexPMAlpha.cpp
// //
// DirectX Texture Library - Premultiplied alpha operations // DirectX Texture Library - Premultiplied alpha operations
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -223,7 +223,7 @@ HRESULT DirectX::PremultiplyAlpha(
|| IsPalettized(srcImage.format) || IsPalettized(srcImage.format)
|| IsTypeless(srcImage.format) || IsTypeless(srcImage.format)
|| !HasAlpha(srcImage.format)) || !HasAlpha(srcImage.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if ((srcImage.width > UINT32_MAX) || (srcImage.height > UINT32_MAX)) if ((srcImage.width > UINT32_MAX) || (srcImage.height > UINT32_MAX))
return E_INVALIDARG; return E_INVALIDARG;
@ -276,7 +276,7 @@ HRESULT DirectX::PremultiplyAlpha(
|| IsPalettized(metadata.format) || IsPalettized(metadata.format)
|| IsTypeless(metadata.format) || IsTypeless(metadata.format)
|| !HasAlpha(metadata.format)) || !HasAlpha(metadata.format))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX)) if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX))
return E_INVALIDARG; return E_INVALIDARG;

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexResize.cpp // DirectXTexResize.cpp
// //
// DirectX Texture Library - Image resizing operations // DirectX Texture Library - Image resizing operations
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -16,14 +16,17 @@
using namespace DirectX; using namespace DirectX;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
#ifdef WIN32
namespace DirectX namespace DirectX
{ {
extern HRESULT _ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original, extern HRESULT _ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original,
_In_ size_t newWidth, _In_ size_t newHeight, _In_ TEX_FILTER_FLAGS filter, _Inout_ const Image* img) noexcept; _In_ size_t newWidth, _In_ size_t newHeight, _In_ TEX_FILTER_FLAGS filter, _Inout_ const Image* img) noexcept;
} }
#endif
namespace namespace
{ {
#ifdef WIN32
//--- Do image resize using WIC --- //--- Do image resize using WIC ---
HRESULT PerformResizeUsingWIC( HRESULT PerformResizeUsingWIC(
const Image& srcImage, const Image& srcImage,
@ -58,7 +61,7 @@ namespace
if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX
|| destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<IWICBitmap> source; ComPtr<IWICBitmap> source;
hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(srcImage.height), pfGUID, hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(srcImage.height), pfGUID,
@ -238,7 +241,7 @@ namespace
return true; return true;
} }
#endif // WIN32
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Resize custom filters // Resize custom filters
@ -820,7 +823,7 @@ namespace
return ResizeTriangleFilter(srcImage, filter, destImage); return ResizeTriangleFilter(srcImage, filter, destImage);
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
} }
} }
@ -856,9 +859,10 @@ HRESULT DirectX::Resize(
if (IsCompressed(srcImage.format)) if (IsCompressed(srcImage.format))
{ {
// We don't support resizing compressed images // We don't support resizing compressed images
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
#ifdef WIN32
bool usewic = UseWICFiltering(srcImage.format, filter); bool usewic = UseWICFiltering(srcImage.format, filter);
WICPixelFormatGUID pfGUID = {}; WICPixelFormatGUID pfGUID = {};
@ -872,11 +876,12 @@ HRESULT DirectX::Resize(
if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX)
{ {
if (filter & TEX_FILTER_FORCE_WIC) if (filter & TEX_FILTER_FORCE_WIC)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
usewic = false; usewic = false;
} }
} }
#endif // WIN32
HRESULT hr = image.Initialize2D(srcImage.format, width, height, 1, 1); HRESULT hr = image.Initialize2D(srcImage.format, width, height, 1, 1);
if (FAILED(hr)) if (FAILED(hr))
@ -886,6 +891,7 @@ HRESULT DirectX::Resize(
if (!rimage) if (!rimage)
return E_POINTER; return E_POINTER;
#ifdef WIN32
if (usewic) if (usewic)
{ {
if (wicpf) if (wicpf)
@ -900,6 +906,7 @@ HRESULT DirectX::Resize(
} }
} }
else else
#endif
{ {
// Case 3: not using WIC resizing // Case 3: not using WIC resizing
hr = PerformResizeUsingCustomFilters(srcImage, filter, *rimage); hr = PerformResizeUsingCustomFilters(srcImage, filter, *rimage);
@ -942,6 +949,7 @@ HRESULT DirectX::Resize(
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
#ifdef WIN32
bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter); bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter);
WICPixelFormatGUID pfGUID = {}; WICPixelFormatGUID pfGUID = {};
@ -955,11 +963,12 @@ HRESULT DirectX::Resize(
if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX)
{ {
if (filter & TEX_FILTER_FORCE_WIC) if (filter & TEX_FILTER_FORCE_WIC)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
usewic = false; usewic = false;
} }
} }
#endif
switch (metadata.dimension) switch (metadata.dimension)
{ {
@ -996,6 +1005,7 @@ HRESULT DirectX::Resize(
return E_FAIL; return E_FAIL;
} }
#ifdef WIN32
if (usewic) if (usewic)
{ {
if (wicpf) if (wicpf)
@ -1010,6 +1020,7 @@ HRESULT DirectX::Resize(
} }
} }
else else
#endif
{ {
// Case 3: not using WIC resizing // Case 3: not using WIC resizing
hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg); hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg);
@ -1055,6 +1066,7 @@ HRESULT DirectX::Resize(
return E_FAIL; return E_FAIL;
} }
#ifdef WIN32
if (usewic) if (usewic)
{ {
if (wicpf) if (wicpf)
@ -1069,6 +1081,7 @@ HRESULT DirectX::Resize(
} }
} }
else else
#endif
{ {
// Case 3: not using WIC resizing // Case 3: not using WIC resizing
hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg); hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg);

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexTGA.cpp // DirectXTexTGA.cpp
// //
// DirectX Texture Library - Targa Truevision (TGA) file format reader/writer // DirectX Texture Library - Targa Truevision (TGA) file format reader/writer
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -148,7 +148,7 @@ namespace
if (size < sizeof(TGA_HEADER)) if (size < sizeof(TGA_HEADER))
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
auto pHeader = static_cast<const TGA_HEADER*>(pSource); auto pHeader = static_cast<const TGA_HEADER*>(pSource);
@ -156,17 +156,17 @@ namespace
if (pHeader->bColorMapType != 0 if (pHeader->bColorMapType != 0
|| pHeader->wColorMapLength != 0) || pHeader->wColorMapLength != 0)
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
if (pHeader->bDescriptor & (TGA_FLAGS_INTERLEAVED_2WAY | TGA_FLAGS_INTERLEAVED_4WAY)) if (pHeader->bDescriptor & (TGA_FLAGS_INTERLEAVED_2WAY | TGA_FLAGS_INTERLEAVED_4WAY))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
if (!pHeader->wWidth || !pHeader->wHeight) if (!pHeader->wWidth || !pHeader->wHeight)
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
switch (pHeader->bImageType) switch (pHeader->bImageType)
@ -214,7 +214,7 @@ namespace
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
if (convFlags && (pHeader->bImageType == TGA_BLACK_AND_WHITE_RLE)) if (convFlags && (pHeader->bImageType == TGA_BLACK_AND_WHITE_RLE))
@ -226,10 +226,10 @@ namespace
case TGA_NO_IMAGE: case TGA_NO_IMAGE:
case TGA_COLOR_MAPPED: case TGA_COLOR_MAPPED:
case TGA_COLOR_MAPPED_RLE: case TGA_COLOR_MAPPED_RLE:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
default: default:
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_E_INVALID_DATA;
} }
metadata.width = pHeader->wWidth; metadata.width = pHeader->wWidth;
@ -1082,7 +1082,7 @@ namespace
if ((image.width > UINT16_MAX) if ((image.width > UINT16_MAX)
|| (image.height > UINT16_MAX)) || (image.height > UINT16_MAX))
{ {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
header.wWidth = static_cast<uint16_t>(image.width); header.wWidth = static_cast<uint16_t>(image.width);
@ -1127,7 +1127,7 @@ namespace
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
return S_OK; return S_OK;
@ -1223,15 +1223,21 @@ namespace
time_t now = {}; time_t now = {};
time(&now); time(&now);
#ifdef WIN32
tm info; tm info;
if (!gmtime_s(&info, &now)) auto pinfo = &info;
if (!gmtime_s(pinfo, &now))
#else
const tm* pinfo = gmtime(&now);
if (pinfo)
#endif
{ {
ext->wStampMonth = static_cast<uint16_t>(info.tm_mon + 1); ext->wStampMonth = static_cast<uint16_t>(pinfo->tm_mon + 1);
ext->wStampDay = static_cast<uint16_t>(info.tm_mday); ext->wStampDay = static_cast<uint16_t>(pinfo->tm_mday);
ext->wStampYear = static_cast<uint16_t>(info.tm_year + 1900); ext->wStampYear = static_cast<uint16_t>(pinfo->tm_year + 1900);
ext->wStampHour = static_cast<uint16_t>(info.tm_hour); ext->wStampHour = static_cast<uint16_t>(pinfo->tm_hour);
ext->wStampMinute = static_cast<uint16_t>(info.tm_min); ext->wStampMinute = static_cast<uint16_t>(pinfo->tm_min);
ext->wStampSecond = static_cast<uint16_t>(info.tm_sec); ext->wStampSecond = static_cast<uint16_t>(pinfo->tm_sec);
} }
} }
} }
@ -1336,6 +1342,7 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
@ -1357,25 +1364,56 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file)
if (fileInfo.EndOfFile.HighPart > 0) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
} }
size_t len = fileInfo.EndOfFile.LowPart;
#else // !WIN32
std::ifstream inFile(std::filesystem::path(szFile), std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
return E_FAIL;
std::streampos fileLen = inFile.tellg();
if (!inFile)
return E_FAIL;
if (fileLen > UINT32_MAX)
return HRESULT_E_FILE_TOO_LARGE;
inFile.seekg(0, std::ios::beg);
if (!inFile)
return E_FAIL;
size_t len = fileLen;
#endif
// Need at least enough data to fill the standard header to be a valid TGA // Need at least enough data to fill the standard header to be a valid TGA
if (fileInfo.EndOfFile.LowPart < (sizeof(TGA_HEADER))) if (len < (sizeof(TGA_HEADER)))
{ {
return E_FAIL; return E_FAIL;
} }
// Read the standard header (we don't need the file footer to parse the file) // Read the standard header (we don't need the file footer to parse the file)
uint8_t header[sizeof(TGA_HEADER)] = {}; uint8_t header[sizeof(TGA_HEADER)] = {};
#ifdef WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
auto headerLen = static_cast<size_t>(bytesRead);
#else
inFile.read(reinterpret_cast<char*>(header), sizeof(TGA_HEADER));
if (!inFile)
return E_FAIL;
size_t headerLen = sizeof(TGA_HEADER);
#endif
size_t offset; size_t offset;
HRESULT hr = DecodeTGAHeader(header, bytesRead, flags, metadata, offset, nullptr); HRESULT hr = DecodeTGAHeader(header, headerLen, flags, metadata, offset, nullptr);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1383,12 +1421,14 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
const TGA_EXTENSION* ext = nullptr; const TGA_EXTENSION* ext = nullptr;
TGA_EXTENSION extData = {}; TGA_EXTENSION extData = {};
{ {
TGA_FOOTER footer = {};
#ifdef WIN32
if (SetFilePointer(hFile.get(), -static_cast<int>(sizeof(TGA_FOOTER)), nullptr, FILE_END) == INVALID_SET_FILE_POINTER) if (SetFilePointer(hFile.get(), -static_cast<int>(sizeof(TGA_FOOTER)), nullptr, FILE_END) == INVALID_SET_FILE_POINTER)
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
TGA_FOOTER footer = {};
if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1398,12 +1438,22 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
{ {
return E_FAIL; return E_FAIL;
} }
#else
inFile.seekg(-static_cast<int>(sizeof(TGA_FOOTER)), std::ios::end);
if (!inFile)
return E_FAIL;
inFile.read(reinterpret_cast<char*>(&footer), sizeof(TGA_FOOTER));
if (!inFile)
return E_FAIL;
#endif
if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 0) if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 0)
{ {
if (footer.dwExtensionOffset != 0 if (footer.dwExtensionOffset != 0
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= fileInfo.EndOfFile.LowPart)) && ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= len))
{ {
#ifdef WIN32
LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } }; LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } };
if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{ {
@ -1414,6 +1464,18 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
metadata.SetAlphaMode(GetAlphaModeFromExtension(ext)); metadata.SetAlphaMode(GetAlphaModeFromExtension(ext));
} }
} }
#else // !WIN32
inFile.seekg(static_cast<std::streampos>(footer.dwExtensionOffset), std::ios::beg);
if (inFile)
{
inFile.read(reinterpret_cast<char*>(&extData), sizeof(TGA_EXTENSION));
if (inFile)
{
ext = &extData;
metadata.SetAlphaMode(GetAlphaModeFromExtension(ext));
}
}
#endif
} }
} }
} }
@ -1531,6 +1593,7 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release(); image.Release();
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
@ -1552,43 +1615,80 @@ HRESULT DirectX::LoadFromTGAFile(
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file)
if (fileInfo.EndOfFile.HighPart > 0) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
} }
size_t len = fileInfo.EndOfFile.LowPart;
#else // !WIN32
std::ifstream inFile(std::filesystem::path(szFile), std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
return E_FAIL;
std::streampos fileLen = inFile.tellg();
if (!inFile)
return E_FAIL;
if (fileLen > UINT32_MAX)
return HRESULT_E_FILE_TOO_LARGE;
inFile.seekg(0, std::ios::beg);
if (!inFile)
return E_FAIL;
size_t len = fileLen;
#endif
// Need at least enough data to fill the header to be a valid TGA // Need at least enough data to fill the header to be a valid TGA
if (fileInfo.EndOfFile.LowPart < sizeof(TGA_HEADER)) if (len < sizeof(TGA_HEADER))
{ {
return E_FAIL; return E_FAIL;
} }
// Read the header // Read the header
uint8_t header[sizeof(TGA_HEADER)] = {}; uint8_t header[sizeof(TGA_HEADER)] = {};
#ifdef WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
auto headerLen = static_cast<size_t>(bytesRead);
#else
inFile.read(reinterpret_cast<char*>(header), sizeof(TGA_HEADER));
if (!inFile)
return E_FAIL;
size_t headerLen = sizeof(TGA_HEADER);
#endif
size_t offset; size_t offset;
uint32_t convFlags = 0; uint32_t convFlags = 0;
TexMetadata mdata; TexMetadata mdata;
HRESULT hr = DecodeTGAHeader(header, bytesRead, flags, mdata, offset, &convFlags); HRESULT hr = DecodeTGAHeader(header, headerLen, flags, mdata, offset, &convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
// Read the pixels // Read the pixels
auto remaining = static_cast<DWORD>(fileInfo.EndOfFile.LowPart - offset); auto remaining = len - offset;
if (remaining == 0) if (remaining == 0)
return E_FAIL; return E_FAIL;
if (offset > sizeof(TGA_HEADER)) if (offset > sizeof(TGA_HEADER))
{ {
#ifdef WIN32
// Skip past the id string // Skip past the id string
LARGE_INTEGER filePos = { { static_cast<DWORD>(offset), 0 } }; LARGE_INTEGER filePos = { { static_cast<DWORD>(offset), 0 } };
if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
#else
inFile.seekg(offset, std::ios::beg);
if (!inFile)
return E_FAIL;
#endif
} }
hr = image.Initialize2D(mdata.format, mdata.width, mdata.height, 1, 1); hr = image.Initialize2D(mdata.format, mdata.width, mdata.height, 1, 1);
@ -1605,15 +1705,16 @@ HRESULT DirectX::LoadFromTGAFile(
if (remaining < image.GetPixelsSize()) if (remaining < image.GetPixelsSize())
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); return HRESULT_E_HANDLE_EOF;
} }
if (image.GetPixelsSize() > UINT32_MAX) if (image.GetPixelsSize() > UINT32_MAX)
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
} }
#ifdef WIN32
if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
{ {
image.Release(); image.Release();
@ -1625,6 +1726,14 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release(); image.Release();
return E_FAIL; return E_FAIL;
} }
#else
inFile.read(reinterpret_cast<char*>(image.GetPixels()), image.GetPixelsSize());
if (!inFile)
{
image.Release();
return E_FAIL;
}
#endif
switch (mdata.format) switch (mdata.format)
{ {
@ -1824,7 +1933,8 @@ HRESULT DirectX::LoadFromTGAFile(
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (!ReadFile(hFile.get(), temp.get(), remaining, &bytesRead, nullptr)) #ifdef WIN32
if (!ReadFile(hFile.get(), temp.get(), static_cast<DWORD>(remaining), &bytesRead, nullptr))
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1835,6 +1945,14 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release(); image.Release();
return E_FAIL; return E_FAIL;
} }
#else
inFile.read(reinterpret_cast<char*>(temp.get()), remaining);
if (!inFile)
{
image.Release();
return E_FAIL;
}
#endif
if (convFlags & CONV_FLAGS_RLE) if (convFlags & CONV_FLAGS_RLE)
{ {
@ -1859,12 +1977,14 @@ HRESULT DirectX::LoadFromTGAFile(
const TGA_EXTENSION* ext = nullptr; const TGA_EXTENSION* ext = nullptr;
TGA_EXTENSION extData = {}; TGA_EXTENSION extData = {};
{ {
TGA_FOOTER footer = {};
#ifdef WIN32
if (SetFilePointer(hFile.get(), -static_cast<int>(sizeof(TGA_FOOTER)), nullptr, FILE_END) == INVALID_SET_FILE_POINTER) if (SetFilePointer(hFile.get(), -static_cast<int>(sizeof(TGA_FOOTER)), nullptr, FILE_END) == INVALID_SET_FILE_POINTER)
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
TGA_FOOTER footer = {};
if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr)) if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr))
{ {
image.Release(); image.Release();
@ -1876,12 +1996,28 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release(); image.Release();
return E_FAIL; return E_FAIL;
} }
#else // !WIN32
inFile.seekg(-static_cast<int>(sizeof(TGA_FOOTER)), std::ios::end);
if (!inFile)
{
image.Release();
return E_FAIL;
}
inFile.read(reinterpret_cast<char*>(&footer), sizeof(TGA_FOOTER));
if (!inFile)
{
image.Release();
return E_FAIL;
}
#endif
if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 0) if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 0)
{ {
if (footer.dwExtensionOffset != 0 if (footer.dwExtensionOffset != 0
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= fileInfo.EndOfFile.LowPart)) && ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= len))
{ {
#ifdef WIN32
LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } }; LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } };
if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{ {
@ -1891,6 +2027,17 @@ HRESULT DirectX::LoadFromTGAFile(
ext = &extData; ext = &extData;
} }
} }
#else // !WIN32
inFile.seekg(static_cast<std::streampos>(footer.dwExtensionOffset), std::ios::beg);
if (inFile)
{
inFile.read(reinterpret_cast<char*>(&extData), sizeof(TGA_EXTENSION));
if (inFile)
{
ext = &extData;
}
}
#endif
} }
} }
} }
@ -1960,7 +2107,7 @@ HRESULT DirectX::SaveToTGAMemory(
assert(destPtr != nullptr); assert(destPtr != nullptr);
uint8_t* dPtr = destPtr; uint8_t* dPtr = destPtr;
memcpy_s(dPtr, blob.GetBufferSize(), &tga_header, sizeof(TGA_HEADER)); memcpy(dPtr, &tga_header, sizeof(TGA_HEADER));
dPtr += sizeof(TGA_HEADER); dPtr += sizeof(TGA_HEADER);
const uint8_t* pPixels = image.pixels; const uint8_t* pPixels = image.pixels;
@ -2033,6 +2180,7 @@ HRESULT DirectX::SaveToTGAFile(
return hr; return hr;
// Create file and write header // Create file and write header
#ifdef WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr)));
#else #else
@ -2044,6 +2192,11 @@ HRESULT DirectX::SaveToTGAFile(
} }
auto_delete_file delonfail(hFile.get()); auto_delete_file delonfail(hFile.get());
#else
std::ofstream outFile(std::filesystem::path(szFile), std::ios::out | std::ios::binary | std::ios::trunc);
if (!outFile)
return E_FAIL;
#endif
// Determine size for TGA pixel data // Determine size for TGA pixel data
size_t rowPitch, slicePitch; size_t rowPitch, slicePitch;
@ -2062,6 +2215,7 @@ HRESULT DirectX::SaveToTGAFile(
return hr; return hr;
// Write blob // Write blob
#ifdef WIN32
const DWORD bytesToWrite = static_cast<DWORD>(blob.GetBufferSize()); const DWORD bytesToWrite = static_cast<DWORD>(blob.GetBufferSize());
DWORD bytesWritten; DWORD bytesWritten;
if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr))
@ -2073,6 +2227,13 @@ HRESULT DirectX::SaveToTGAFile(
{ {
return E_FAIL; return E_FAIL;
} }
#else
outFile.write(reinterpret_cast<char*>(blob.GetBufferPointer()),
static_cast<std::streamsize>(blob.GetBufferSize()));
if (!outFile)
return E_FAIL;
#endif
} }
else else
{ {
@ -2082,6 +2243,7 @@ HRESULT DirectX::SaveToTGAFile(
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
// Write header // Write header
#ifdef WIN32
DWORD bytesWritten; DWORD bytesWritten;
if (!WriteFile(hFile.get(), &tga_header, sizeof(TGA_HEADER), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), &tga_header, sizeof(TGA_HEADER), &bytesWritten, nullptr))
{ {
@ -2090,9 +2252,14 @@ HRESULT DirectX::SaveToTGAFile(
if (bytesWritten != sizeof(TGA_HEADER)) if (bytesWritten != sizeof(TGA_HEADER))
return E_FAIL; return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(&tga_header), sizeof(TGA_HEADER));
if (!outFile)
return E_FAIL;
#endif
if (rowPitch > UINT32_MAX) if (rowPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
// Write pixels // Write pixels
const uint8_t* pPixels = image.pixels; const uint8_t* pPixels = image.pixels;
@ -2115,6 +2282,7 @@ HRESULT DirectX::SaveToTGAFile(
pPixels += image.rowPitch; pPixels += image.rowPitch;
#ifdef WIN32
if (!WriteFile(hFile.get(), temp.get(), static_cast<DWORD>(rowPitch), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), temp.get(), static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -2122,6 +2290,11 @@ HRESULT DirectX::SaveToTGAFile(
if (bytesWritten != rowPitch) if (bytesWritten != rowPitch)
return E_FAIL; return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(temp.get()), rowPitch);
if (!outFile)
return E_FAIL;
#endif
} }
uint32_t extOffset = 0; uint32_t extOffset = 0;
@ -2131,6 +2304,7 @@ HRESULT DirectX::SaveToTGAFile(
TGA_EXTENSION ext = {}; TGA_EXTENSION ext = {};
SetExtension(&ext, flags, *metadata); SetExtension(&ext, flags, *metadata);
#ifdef WIN32
extOffset = SetFilePointer(hFile.get(), 0, nullptr, FILE_CURRENT); extOffset = SetFilePointer(hFile.get(), 0, nullptr, FILE_CURRENT);
if (extOffset == INVALID_SET_FILE_POINTER) if (extOffset == INVALID_SET_FILE_POINTER)
{ {
@ -2144,6 +2318,13 @@ HRESULT DirectX::SaveToTGAFile(
if (bytesWritten != sizeof(TGA_EXTENSION)) if (bytesWritten != sizeof(TGA_EXTENSION))
return E_FAIL; return E_FAIL;
#else
extOffset = static_cast<uint32_t>(outFile.tellp());
outFile.write(reinterpret_cast<char*>(&ext), sizeof(TGA_EXTENSION));
if (!outFile)
return E_FAIL;
#endif
} }
// Write TGA 2.0 footer // Write TGA 2.0 footer
@ -2151,16 +2332,24 @@ HRESULT DirectX::SaveToTGAFile(
footer.dwExtensionOffset = extOffset; footer.dwExtensionOffset = extOffset;
memcpy(footer.Signature, g_Signature, sizeof(g_Signature)); memcpy(footer.Signature, g_Signature, sizeof(g_Signature));
if (!WriteFile(hFile.get(), &footer, sizeof(footer), &bytesWritten, nullptr)) #ifdef WIN32
if (!WriteFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
if (bytesWritten != sizeof(footer)) if (bytesWritten != sizeof(footer))
return E_FAIL; return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(&footer), sizeof(TGA_FOOTER));
if (!outFile)
return E_FAIL;
#endif
} }
#ifdef WIN32
delonfail.clear(); delonfail.clear();
#endif
return S_OK; return S_OK;
} }

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexUtil.cpp // DirectXTexUtil.cpp
// //
// DirectX Texture Library - Utilities // DirectX Texture Library - Utilities
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -32,6 +32,7 @@ using Microsoft::WRL::ComPtr;
namespace namespace
{ {
#ifdef WIN32
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// WIC Pixel Format Translation Data // WIC Pixel Format Translation Data
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -113,9 +114,20 @@ namespace
ifactory)) ? TRUE : FALSE; ifactory)) ? TRUE : FALSE;
#endif #endif
} }
#else // !WIN32
inline void * _aligned_malloc(size_t size, size_t alignment)
{
size = (size + alignment - 1) & ~(alignment - 1);
return std::aligned_alloc(alignment, size);
}
#define _aligned_free free
#endif
} }
#ifdef WIN32
//===================================================================================== //=====================================================================================
// WIC Utilities // WIC Utilities
//===================================================================================== //=====================================================================================
@ -317,7 +329,7 @@ void DirectX::SetWICFactory(_In_opt_ IWICImagingFactory* pWIC) noexcept
if (pWIC) if (pWIC)
pWIC->Release(); pWIC->Release();
} }
#endif // WIN32
//===================================================================================== //=====================================================================================
@ -1056,7 +1068,7 @@ HRESULT DirectX::ComputePitch(DXGI_FORMAT fmt, size_t width, size_t height,
if (pitch > UINT32_MAX || slice > UINT32_MAX) if (pitch > UINT32_MAX || slice > UINT32_MAX)
{ {
rowPitch = slicePitch = 0; rowPitch = slicePitch = 0;
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
} }
#else #else
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!"); static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");

View File

@ -314,7 +314,7 @@ namespace
TEX_ALPHA_MODE alphaMode; TEX_ALPHA_MODE alphaMode;
metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert, &alphaMode); metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert, &alphaMode);
if (metadata.format == DXGI_FORMAT_UNKNOWN) if (metadata.format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
metadata.SetAlphaMode(alphaMode); metadata.SetAlphaMode(alphaMode);
@ -437,7 +437,7 @@ namespace
return E_NOINTERFACE; return E_NOINTERFACE;
if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
if (memcmp(&convertGUID, &GUID_NULL, sizeof(GUID)) == 0) if (memcmp(&convertGUID, &GUID_NULL, sizeof(GUID)) == 0)
{ {
@ -509,7 +509,7 @@ namespace
return E_POINTER; return E_POINTER;
if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<IWICBitmapFrameDecode> frame; ComPtr<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame(static_cast<UINT>(index), frame.GetAddressOf()); hr = decoder->GetFrame(static_cast<UINT>(index), frame.GetAddressOf());
@ -731,7 +731,7 @@ namespace
WICPixelFormatGUID pfGuid; WICPixelFormatGUID pfGuid;
if (!_DXGIToWIC(image.format, pfGuid)) if (!_DXGIToWIC(image.format, pfGuid))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
HRESULT hr = frame->Initialize(props); HRESULT hr = frame->Initialize(props);
if (FAILED(hr)) if (FAILED(hr))
@ -741,7 +741,7 @@ namespace
return E_INVALIDARG; return E_INVALIDARG;
if (image.rowPitch > UINT32_MAX || image.slicePitch > UINT32_MAX) if (image.rowPitch > UINT32_MAX || image.slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
hr = frame->SetSize(static_cast<UINT>(image.width), static_cast<UINT>(image.height)); hr = frame->SetSize(static_cast<UINT>(image.width), static_cast<UINT>(image.height));
if (FAILED(hr)) if (FAILED(hr))
@ -919,7 +919,7 @@ namespace
return hr; return hr;
if (!mframe) if (!mframe)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
hr = encoder->Initialize(stream, WICBitmapEncoderNoCache); hr = encoder->Initialize(stream, WICBitmapEncoderNoCache);
if (FAILED(hr)) if (FAILED(hr))
@ -971,7 +971,7 @@ HRESULT DirectX::GetMetadataFromWICMemory(
return E_INVALIDARG; return E_INVALIDARG;
if (size > UINT32_MAX) if (size > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
bool iswic2 = false; bool iswic2 = false;
auto pWIC = GetWICFactory(iswic2); auto pWIC = GetWICFactory(iswic2);
@ -1063,7 +1063,7 @@ HRESULT DirectX::LoadFromWICMemory(
return E_INVALIDARG; return E_INVALIDARG;
if (size > UINT32_MAX) if (size > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
bool iswic2 = false; bool iswic2 = false;
auto pWIC = GetWICFactory(iswic2); auto pWIC = GetWICFactory(iswic2);
@ -1216,7 +1216,7 @@ HRESULT DirectX::SaveToWICMemory(
return hr; return hr;
if (stat.cbSize.HighPart > 0) if (stat.cbSize.HighPart > 0)
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
hr = blob.Initialize(stat.cbSize.LowPart); hr = blob.Initialize(stat.cbSize.LowPart);
if (FAILED(hr)) if (FAILED(hr))
@ -1273,7 +1273,7 @@ HRESULT DirectX::SaveToWICMemory(
return hr; return hr;
if (stat.cbSize.HighPart > 0) if (stat.cbSize.HighPart > 0)
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_E_FILE_TOO_LARGE;
hr = blob.Initialize(stat.cbSize.LowPart); hr = blob.Initialize(stat.cbSize.LowPart);
if (FAILED(hr)) if (FAILED(hr))

View File

@ -1,6 +1,6 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// scoped.h // scoped.h
// //
// Utility header with helper classes for exception-safe handling of resources // Utility header with helper classes for exception-safe handling of resources
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
@ -14,9 +14,39 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#ifndef WIN32
#include <cstdlib>
struct aligned_deleter { void operator()(void* p) noexcept { free(p); } };
using ScopedAlignedArrayFloat = std::unique_ptr<float[], aligned_deleter>;
inline ScopedAlignedArrayFloat make_AlignedArrayFloat(uint64_t count)
{
uint64_t size = sizeof(float) * count;
size = (size + 15u) & ~0xF;
if (size > static_cast<uint64_t>(UINT32_MAX))
return nullptr;
auto ptr = aligned_alloc(16, static_cast<size_t>(size) );
return ScopedAlignedArrayFloat(static_cast<float*>(ptr));
}
using ScopedAlignedArrayXMVECTOR = std::unique_ptr<DirectX::XMVECTOR[], aligned_deleter>;
inline ScopedAlignedArrayXMVECTOR make_AlignedArrayXMVECTOR(uint64_t count)
{
uint64_t size = sizeof(DirectX::XMVECTOR) * count;
if (size > static_cast<uint64_t>(UINT32_MAX))
return nullptr;
auto ptr = aligned_alloc(16, static_cast<size_t>(size));
return ScopedAlignedArrayXMVECTOR(static_cast<DirectX::XMVECTOR*>(ptr));
}
#else // WIN32
//---------------------------------------------------------------------------------
#include <malloc.h> #include <malloc.h>
//---------------------------------------------------------------------------------
struct aligned_deleter { void operator()(void* p) noexcept { _aligned_free(p); } }; struct aligned_deleter { void operator()(void* p) noexcept { _aligned_free(p); } };
using ScopedAlignedArrayFloat = std::unique_ptr<float[], aligned_deleter>; using ScopedAlignedArrayFloat = std::unique_ptr<float[], aligned_deleter>;
@ -77,3 +107,5 @@ public:
private: private:
HANDLE m_handle; HANDLE m_handle;
}; };
#endif // WIN32

View File

@ -29,9 +29,14 @@
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#ifdef WIN32
#include <wincodec.h> #include <wincodec.h>
#include <wrl\client.h> #include <wrl\client.h>
#else
#include <fstream>
#include <filesystem>
#include <thread>
#endif
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic ignored "-Wtautological-type-limit-compare" #pragma clang diagnostic ignored "-Wtautological-type-limit-compare"
@ -41,7 +46,11 @@
#endif #endif
#define D3DX12_NO_STATE_OBJECT_HELPERS #define D3DX12_NO_STATE_OBJECT_HELPERS
#ifdef WIN32
#include "d3dx12.h" #include "d3dx12.h"
#else
#include "directx/d3dx12.h"
#endif
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
@ -54,6 +63,12 @@ using Microsoft::WRL::ComPtr;
((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
#endif /* defined(MAKEFOURCC) */ #endif /* defined(MAKEFOURCC) */
// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)
#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast<HRESULT>(0x80070216L)
// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
#define HRESULT_E_NOT_SUPPORTED static_cast<HRESULT>(0x80070032L)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// DDS file structure definitions // DDS file structure definitions
// //
@ -85,7 +100,7 @@ namespace
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA #define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV #define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT #define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT
#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT #define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT
#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH #define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH
#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE #define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE
@ -200,6 +215,7 @@ namespace
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 }; { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifdef WIN32
struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } }; struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<void, handle_closer>; using ScopedHandle = std::unique_ptr<void, handle_closer>;
@ -257,6 +273,7 @@ namespace
const wchar_t* m_filename; const wchar_t* m_filename;
ComPtr<IWICStream>& m_handle; ComPtr<IWICStream>& m_handle;
}; };
#endif
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Return the BPP for a particular format // Return the BPP for a particular format
@ -573,7 +590,7 @@ namespace
#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64) #if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!"); static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!");
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX) if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
#else #else
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!"); static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
#endif #endif
@ -663,14 +680,14 @@ namespace
return E_INVALIDARG; return E_INVALIDARG;
if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D) if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
if (srcPitch > UINT32_MAX) if (srcPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
UINT numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format); UINT numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format);
if (numberOfPlanes != 1) if (numberOfPlanes != 1)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
D3D12_HEAP_PROPERTIES sourceHeapProperties; D3D12_HEAP_PROPERTIES sourceHeapProperties;
D3D12_HEAP_FLAGS sourceHeapFlags; D3D12_HEAP_FLAGS sourceHeapFlags;
@ -812,11 +829,18 @@ namespace
// Block until the copy is complete // Block until the copy is complete
while (fence->GetCompletedValue() < 1) while (fence->GetCompletedValue() < 1)
{
#ifdef WIN32
SwitchToThread(); SwitchToThread();
#else
std::this_thread::yield();
#endif
}
return S_OK; return S_OK;
} }
#ifdef WIN32
BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID* ifactory) noexcept BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID* ifactory) noexcept
{ {
return SUCCEEDED(CoCreateInstance( return SUCCEEDED(CoCreateInstance(
@ -842,6 +866,7 @@ namespace
return factory; return factory;
} }
#endif
} // anonymous namespace } // anonymous namespace
@ -884,7 +909,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFFu; UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFFu;
if (dstRowPitch > UINT32_MAX) if (dstRowPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<ID3D12Resource> pStaging; ComPtr<ID3D12Resource> pStaging;
HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState); HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState);
@ -892,11 +917,17 @@ HRESULT DirectX::SaveDDSTextureToFile(
return hr; return hr;
// Create file // Create file
#ifdef WIN32
ScopedHandle hFile(safe_handle(CreateFile2(fileName, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr))); ScopedHandle hFile(safe_handle(CreateFile2(fileName, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr)));
if (!hFile) if (!hFile)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
auto_delete_file delonfail(hFile.get()); auto_delete_file delonfail(hFile.get());
#else
std::ofstream outFile(std::filesystem::path(fileName), std::ios::out | std::ios::binary | std::ios::trunc);
if (!outFile)
return E_FAIL;
#endif
// Setup header // Setup header
const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10);
@ -917,30 +948,30 @@ HRESULT DirectX::SaveDDSTextureToFile(
DDS_HEADER_DXT10* extHeader = nullptr; DDS_HEADER_DXT10* extHeader = nullptr;
switch (desc.Format) switch (desc.Format)
{ {
case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy(&header->ddspf, &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R16G16_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R16G16_UNORM: memcpy(&header->ddspf, &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8_UNORM: memcpy(&header->ddspf, &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R16_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_L16, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R16_UNORM: memcpy(&header->ddspf, &DDSPF_L16, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_L8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8_UNORM: memcpy(&header->ddspf, &DDSPF_L8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_A8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_A8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_A8_UNORM: memcpy(&header->ddspf, &DDSPF_A8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8_B8G8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_R8G8_B8G8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8_B8G8_UNORM: memcpy(&header->ddspf, &DDSPF_R8G8_B8G8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy(&header->ddspf, &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC1_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC1_UNORM: memcpy(&header->ddspf, &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC2_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_DXT3, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC2_UNORM: memcpy(&header->ddspf, &DDSPF_DXT3, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC3_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_DXT5, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC3_UNORM: memcpy(&header->ddspf, &DDSPF_DXT5, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC4_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_BC4_UNORM, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC4_UNORM: memcpy(&header->ddspf, &DDSPF_BC4_UNORM, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC4_SNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC4_SNORM: memcpy(&header->ddspf, &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC5_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_BC5_UNORM, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC5_UNORM: memcpy(&header->ddspf, &DDSPF_BC5_UNORM, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_BC5_SNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_BC5_SNORM: memcpy(&header->ddspf, &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B5G6R5_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_B5G6R5_UNORM: memcpy(&header->ddspf, &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy(&header->ddspf, &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8_SNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_V8U8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8_SNORM: memcpy(&header->ddspf, &DDSPF_V8U8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R8G8B8A8_SNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_Q8W8V8U8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R8G8B8A8_SNORM: memcpy(&header->ddspf, &DDSPF_Q8W8V8U8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_R16G16_SNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_V16U16, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_R16G16_SNORM: memcpy(&header->ddspf, &DDSPF_V16U16, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy(&header->ddspf, &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy(&header->ddspf, &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_YUY2: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_YUY2: memcpy(&header->ddspf, &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT)); break;
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT)); break; case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy(&header->ddspf, &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT)); break;
// Legacy D3DX formats using D3DFMT enum value as FourCC // Legacy D3DX formats using D3DFMT enum value as FourCC
case DXGI_FORMAT_R32G32B32A32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 116; break; // D3DFMT_A32B32G32R32F case DXGI_FORMAT_R32G32B32A32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 116; break; // D3DFMT_A32B32G32R32F
@ -956,10 +987,10 @@ HRESULT DirectX::SaveDDSTextureToFile(
case DXGI_FORMAT_IA44: case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8: case DXGI_FORMAT_P8:
case DXGI_FORMAT_A8P8: case DXGI_FORMAT_A8P8:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
default: default:
memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT)); memcpy(&header->ddspf, &DDSPF_DX10, sizeof(DDS_PIXELFORMAT));
headerSize += sizeof(DDS_HEADER_DXT10); headerSize += sizeof(DDS_HEADER_DXT10);
extHeader = reinterpret_cast<DDS_HEADER_DXT10*>(fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER)); extHeader = reinterpret_cast<DDS_HEADER_DXT10*>(fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER));
@ -975,7 +1006,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
return hr; return hr;
if (rowPitch > UINT32_MAX || slicePitch > UINT32_MAX) if (rowPitch > UINT32_MAX || slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
if (IsCompressed(desc.Format)) if (IsCompressed(desc.Format))
{ {
@ -998,7 +1029,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
UINT64 imageSize = dstRowPitch * UINT64(rowCount); UINT64 imageSize = dstRowPitch * UINT64(rowCount);
if (imageSize > UINT32_MAX) if (imageSize > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
void* pMappedMemory = nullptr; void* pMappedMemory = nullptr;
D3D12_RANGE readRange = { 0, static_cast<SIZE_T>(imageSize) }; D3D12_RANGE readRange = { 0, static_cast<SIZE_T>(imageSize) };
@ -1019,7 +1050,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
size_t msize = std::min<size_t>(rowPitch, size_t(dstRowPitch)); size_t msize = std::min<size_t>(rowPitch, size_t(dstRowPitch));
for (size_t h = 0; h < rowCount; ++h) for (size_t h = 0; h < rowCount; ++h)
{ {
memcpy_s(dptr, rowPitch, sptr, msize); memcpy(dptr, sptr, msize);
sptr += dstRowPitch; sptr += dstRowPitch;
dptr += rowPitch; dptr += rowPitch;
} }
@ -1027,6 +1058,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
pStaging->Unmap(0, &writeRange); pStaging->Unmap(0, &writeRange);
// Write header & pixels // Write header & pixels
#ifdef WIN32
DWORD bytesWritten; DWORD bytesWritten;
if (!WriteFile(hFile.get(), fileHeader, static_cast<DWORD>(headerSize), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), fileHeader, static_cast<DWORD>(headerSize), &bytesWritten, nullptr))
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1041,11 +1073,23 @@ HRESULT DirectX::SaveDDSTextureToFile(
return E_FAIL; return E_FAIL;
delonfail.clear(); delonfail.clear();
#else
outFile.write(reinterpret_cast<char*>(fileHeader), static_cast<std::streamsize>(headerSize));
if (!outFile)
return E_FAIL;
outFile.write(reinterpret_cast<char*>(pixels.get()), static_cast<std::streamsize>(slicePitch));
if (!outFile)
return E_FAIL;
outFile.close();
#endif
return S_OK; return S_OK;
} }
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
#ifdef WIN32
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::SaveWICTextureToFile( HRESULT DirectX::SaveWICTextureToFile(
ID3D12CommandQueue* pCommandQ, ID3D12CommandQueue* pCommandQ,
@ -1088,7 +1132,7 @@ HRESULT DirectX::SaveWICTextureToFile(
UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFFu; UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFFu;
if (dstRowPitch > UINT32_MAX) if (dstRowPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<ID3D12Resource> pStaging; ComPtr<ID3D12Resource> pStaging;
HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState); HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState);
@ -1141,7 +1185,7 @@ HRESULT DirectX::SaveWICTextureToFile(
break; break;
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_E_NOT_SUPPORTED;
} }
auto pWIC = _GetWIC(); auto pWIC = _GetWIC();
@ -1297,7 +1341,7 @@ HRESULT DirectX::SaveWICTextureToFile(
UINT64 imageSize = dstRowPitch * UINT64(desc.Height); UINT64 imageSize = dstRowPitch * UINT64(desc.Height);
if (imageSize > UINT32_MAX) if (imageSize > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); return HRESULT_E_ARITHMETIC_OVERFLOW;
void* pMappedMemory = nullptr; void* pMappedMemory = nullptr;
D3D12_RANGE readRange = { 0, static_cast<SIZE_T>(imageSize) }; D3D12_RANGE readRange = { 0, static_cast<SIZE_T>(imageSize) };
@ -1369,3 +1413,4 @@ HRESULT DirectX::SaveWICTextureToFile(
return S_OK; return S_OK;
} }
#endif // WIN32

View File

@ -17,10 +17,17 @@
#pragma once #pragma once
#ifdef WIN32
#include <d3d12.h> #include <d3d12.h>
#include <OCIdl.h> #include <OCIdl.h>
#include <functional> #include <functional>
#else
#include <wsl/winadapter.h>
#include <wsl/wrladapter.h>
#include <directx/d3d12.h>
#endif
namespace DirectX namespace DirectX
@ -32,6 +39,7 @@ namespace DirectX
D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_RENDER_TARGET) noexcept; D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_RENDER_TARGET) noexcept;
#ifdef WIN32
HRESULT __cdecl SaveWICTextureToFile( HRESULT __cdecl SaveWICTextureToFile(
_In_ ID3D12CommandQueue* pCommandQ, _In_ ID3D12CommandQueue* pCommandQ,
_In_ ID3D12Resource* pSource, _In_ ID3D12Resource* pSource,
@ -42,4 +50,5 @@ namespace DirectX
_In_opt_ const GUID* targetFormat = nullptr, _In_opt_ const GUID* targetFormat = nullptr,
_In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr, _In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr,
bool forceSRGB = false); bool forceSRGB = false);
#endif
} }