From 234eee8a019f4a53adef5b86c90efe9a7f5f3111 Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Fri, 8 Jan 2021 02:20:55 -0800 Subject: [PATCH] Support for Windows Subsystem for Linux (#208) --- .gitignore | 7 +- CMakeLists.txt | 45 ++-- DDSTextureLoader/DDSTextureLoader12.cpp | 105 ++++++-- DDSTextureLoader/DDSTextureLoader12.h | 6 + DirectXTex/BCDirectCompute.cpp | 10 +- DirectXTex/DirectXTex.h | 16 +- DirectXTex/DirectXTexCompress.cpp | 22 +- DirectXTex/DirectXTexCompressGPU.cpp | 8 +- DirectXTex/DirectXTexConvert.cpp | 55 +++-- DirectXTex/DirectXTexD3D11.cpp | 8 +- DirectXTex/DirectXTexD3D12.cpp | 21 +- DirectXTex/DirectXTexDDS.cpp | 304 ++++++++++++++++-------- DirectXTex/DirectXTexFlipRotate.cpp | 10 +- DirectXTex/DirectXTexHDR.cpp | 178 +++++++++++--- DirectXTex/DirectXTexImage.cpp | 35 ++- DirectXTex/DirectXTexMipmaps.cpp | 59 +++-- DirectXTex/DirectXTexMisc.cpp | 31 ++- DirectXTex/DirectXTexNormalMaps.cpp | 14 +- DirectXTex/DirectXTexP.h | 50 +++- DirectXTex/DirectXTexPMAlpha.cpp | 6 +- DirectXTex/DirectXTexResize.cpp | 27 ++- DirectXTex/DirectXTexTGA.cpp | 257 +++++++++++++++++--- DirectXTex/DirectXTexUtil.cpp | 18 +- DirectXTex/DirectXTexWIC.cpp | 20 +- DirectXTex/scoped.h | 36 ++- ScreenGrab/ScreenGrab12.cpp | 123 +++++++--- ScreenGrab/ScreenGrab12.h | 9 + 27 files changed, 1101 insertions(+), 379 deletions(-) diff --git a/.gitignore b/.gitignore index bfc5e7c..62c90f3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ *.VC.db *.nupkg .vs -Bin +[Bb]in packages /DirectXTex/Shaders/Compiled/*.inc /DirectXTex/Shaders/Compiled/*.pdb @@ -34,3 +34,8 @@ x64 /Tests /wiki /out +/CMakeCache.txt +/CMakeFiles +/Makefile +/cmake +/cmake_install.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 17c7d13..49e9ac6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,6 @@ set(LIBRARY_SOURCES DirectXTex/DirectXTexCompress.cpp DirectXTex/DirectXTexConvert.cpp DirectXTex/DirectXTexDDS.cpp - DirectXTex/DirectXTexFlipRotate.cpp DirectXTex/DirectXTexHDR.cpp DirectXTex/DirectXTexImage.cpp DirectXTex/DirectXTexMipmaps.cpp @@ -62,20 +61,26 @@ set(LIBRARY_SOURCES DirectXTex/DirectXTexPMAlpha.cpp DirectXTex/DirectXTexResize.cpp DirectXTex/DirectXTexTGA.cpp - DirectXTex/DirectXTexUtil.cpp - DirectXTex/DirectXTexWIC.cpp) + DirectXTex/DirectXTexUtil.cpp) + +if(WIN32) + set(LIBRARY_SOURCES ${LIBRARY_SOURCES} + DirectXTex/DirectXTexFlipRotate.cpp + DirectXTex/DirectXTexWIC.cpp) +endif() set(SHADER_SOURCES DirectXTex/Shaders/BC6HEncode.hlsl DirectXTex/Shaders/BC7Encode.hlsl) -if(BUILD_DX11) +if(BUILD_DX11 AND WIN32) set(LIBRARY_SOURCES ${LIBRARY_SOURCES} DirectXTex/BCDirectCompute.h DirectXTex/BCDirectCompute.cpp DirectXTex/DirectXTexCompressGPU.cpp DirectXTex/DirectXTexD3D11.cpp) endif() + if(BUILD_DX12) set(LIBRARY_SOURCES ${LIBRARY_SOURCES} DirectXTex/d3dx12.h @@ -91,7 +96,7 @@ if(ENABLE_OPENEXR_SUPPORT) DirectXTex/DirectXTexEXR.cpp) endif() -if(BUILD_DX11) +if(BUILD_DX11 AND WIN32) set(LIBRARY_SOURCES ${LIBRARY_SOURCES} DirectXTex/Shaders/Compiled/BC6HEncode_EncodeBlockCS.inc) @@ -134,6 +139,12 @@ if(MSVC) string(REPLACE "/GR " "/GR- " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) 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 include(CMakePackageConfigHelpers) @@ -168,7 +179,7 @@ install(FILES DESTINATION cmake/) #--- Command-line tools -if(BUILD_TOOLS) +if(BUILD_TOOLS AND WIN32) add_executable(texassemble Texassemble/texassemble.cpp Texassemble/AnimatedGif.cpp) @@ -199,7 +210,7 @@ endif() if(MSVC) 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(texconv PRIVATE /fp:fast) target_compile_options(texdiag PRIVATE /fp:fast) @@ -207,7 +218,7 @@ if(MSVC) if (${CMAKE_SIZEOF_VOID_P} EQUAL "4") 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(texconv PRIVATE /arch:SSE2) target_compile_options(texdiag PRIVATE /arch:SSE2) @@ -215,22 +226,22 @@ if(MSVC) endif() endif() -if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(WarningsLib "-Wpedantic" "-Wextra") target_compile_options(${PROJECT_NAME} PRIVATE ${WarningsLib}) # 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") target_compile_options(texassemble PRIVATE ${WarningsEXE}) target_compile_options(texconv PRIVATE ${WarningsEXE} "-Wno-global-constructors") target_compile_options(texdiag PRIVATE ${WarningsEXE} "-Wno-double-promotion") 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) - if(BUILD_TOOLS) + if(BUILD_TOOLS AND WIN32) target_compile_options(texassemble PRIVATE /permissive- /Zc:__cplusplus) target_compile_options(texconv 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) target_compile_options(${PROJECT_NAME} PRIVATE /analyze) - if(BUILD_TOOLS) + if(BUILD_TOOLS AND WIN32) target_compile_options(texassemble PRIVATE /analyze) target_compile_options(texconv 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) 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(texconv 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) 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-) endif() endif() - if(BUILD_TOOLS) + if(BUILD_TOOLS AND WIN32) set(WarningsEXE "/wd4061" "/wd4062" "/wd4365" "/wd4668" "/wd4710" "/wd4820" "/wd5039" "/wd5045" "/wd5219") target_compile_options(texassemble PRIVATE ${WarningsEXE}) target_compile_options(texconv PRIVATE ${WarningsEXE}) @@ -284,6 +295,6 @@ if(WIN32) endif() endif() -if(BUILD_TOOLS) +if(BUILD_TOOLS AND WIN32) set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT texconv) endif() diff --git a/DDSTextureLoader/DDSTextureLoader12.cpp b/DDSTextureLoader/DDSTextureLoader12.cpp index 9f1452f..f89e93f 100644 --- a/DDSTextureLoader/DDSTextureLoader12.cpp +++ b/DDSTextureLoader/DDSTextureLoader12.cpp @@ -20,6 +20,11 @@ #include #include +#ifndef WIN32 +#include +#include +#endif + #ifdef __clang__ #pragma clang diagnostic ignored "-Wtautological-type-limit-compare" #pragma clang diagnostic ignored "-Wcovered-switch-default" @@ -30,7 +35,12 @@ #pragma warning(disable : 4062) #define D3DX12_NO_STATE_OBJECT_HELPERS + +#ifdef WIN32 #include "d3dx12.h" +#else +#include "directx/d3dx12.h" +#endif using namespace DirectX; @@ -43,6 +53,18 @@ using namespace DirectX; ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) #endif /* defined(MAKEFOURCC) */ +// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW) +#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast(0x80070216L) + +// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) +#define HRESULT_E_NOT_SUPPORTED static_cast(0x80070032L) + +// HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) +#define HRESULT_E_HANDLE_EOF static_cast(0x80070026L) + +// HRESULT_FROM_WIN32(ERROR_INVALID_DATA) +#define HRESULT_E_INVALID_DATA static_cast(0x8007000DL) + //-------------------------------------------------------------------------------------- // DDS file structure definitions // @@ -124,11 +146,13 @@ struct DDS_HEADER_DXT10 //-------------------------------------------------------------------------------------- namespace { +#ifdef WIN32 struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } }; using ScopedHandle = std::unique_ptr; inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; } +#endif template inline void SetDebugObjectName(_In_ ID3D12DeviceChild* resource, _In_z_ const wchar_t(&name)[TNameLength]) noexcept @@ -239,6 +263,7 @@ namespace *bitSize = 0; +#ifdef WIN32 // open the file ScopedHandle hFile(safe_handle(CreateFile2(fileName, GENERIC_READ, @@ -296,6 +321,44 @@ namespace 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(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 ") auto dwMagicNumber = *reinterpret_cast(ddsData.get()); if (dwMagicNumber != DDS_MAGIC) @@ -320,7 +383,7 @@ namespace (MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC)) { // Must be long enough for both headers and magic value - if (fileInfo.EndOfFile.LowPart < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10))) + if (len < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10))) { ddsData.reset(); return E_FAIL; @@ -334,7 +397,7 @@ namespace auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER) + (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0); *bitData = ddsData.get() + offset; - *bitSize = fileInfo.EndOfFile.LowPart - offset; + *bitSize = len - offset; return S_OK; } @@ -619,7 +682,7 @@ namespace #if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64) static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!"); if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; #else static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!"); #endif @@ -1037,7 +1100,7 @@ namespace return hr; 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)) { @@ -1067,7 +1130,7 @@ namespace if (pSrcBits + (NumBytes*d) > pEndBits) { - return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); + return HRESULT_E_HANDLE_EOF; } pSrcBits += NumBytes * d; @@ -1187,7 +1250,7 @@ namespace arraySize = d3d10ext->arraySize; if (arraySize == 0) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } switch (d3d10ext->dxgiFormat) @@ -1196,12 +1259,12 @@ namespace case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: case DXGI_FORMAT_A8P8: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; default: 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 if ((header->flags & DDS_HEIGHT) && height != 1) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } height = depth = 1; break; @@ -1230,17 +1293,17 @@ namespace case D3D12_RESOURCE_DIMENSION_TEXTURE3D: if (!(header->flags & DDS_HEADER_FLAGS_VOLUME)) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } if (arraySize > 1) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } resDim = static_cast(d3d10ext->resourceDimension); @@ -1251,7 +1314,7 @@ namespace if (format == DXGI_FORMAT_UNKNOWN) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } if (header->flags & DDS_HEADER_FLAGS_VOLUME) @@ -1265,7 +1328,7 @@ namespace // We require all six faces to be defined if ((header->caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } 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) if (mipCount > D3D12_REQ_MIP_LEVELS) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } switch (resDim) @@ -1293,7 +1356,7 @@ namespace if ((arraySize > D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) || (width > D3D12_REQ_TEXTURE1D_U_DIMENSION)) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } break; @@ -1305,14 +1368,14 @@ namespace (width > 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) || (width > 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; @@ -1322,12 +1385,12 @@ namespace (height > 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; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } UINT numberOfPlanes = D3D12GetFormatPlaneCount(d3dDevice, format); @@ -1337,7 +1400,7 @@ namespace if ((numberOfPlanes > 1) && IsDepthStencil(format)) { // 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) diff --git a/DDSTextureLoader/DDSTextureLoader12.h b/DDSTextureLoader/DDSTextureLoader12.h index 490564e..0e14a62 100644 --- a/DDSTextureLoader/DDSTextureLoader12.h +++ b/DDSTextureLoader/DDSTextureLoader12.h @@ -16,7 +16,13 @@ #pragma once +#if defined(WIN32) || defined(WINAPI_FAMILY) #include +#else +#include +#include +#include +#endif #include #include diff --git a/DirectXTex/BCDirectCompute.cpp b/DirectXTex/BCDirectCompute.cpp index 2493777..7b22e9e 100644 --- a/DirectXTex/BCDirectCompute.cpp +++ b/DirectXTex/BCDirectCompute.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // BCDirectCompute.cpp -// +// // Direct3D 11 Compute Shader BC Compressor // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -104,7 +104,7 @@ HRESULT GPUCompressBC::Initialize(ID3D11Device* pDevice) if (fl < D3D_FEATURE_LEVEL_10_0) { // 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) @@ -119,7 +119,7 @@ HRESULT GPUCompressBC::Initialize(ID3D11Device* pDevice) 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: m_bcformat = m_srcformat = DXGI_FORMAT_UNKNOWN; - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } m_bcformat = format; @@ -234,7 +234,7 @@ HRESULT GPUCompressBC::Prepare(size_t width, size_t height, uint32_t flags, DXGI // Create structured buffers uint64_t sizeInBytes = uint64_t(num_blocks) * sizeof(BufferBC6HBC7); if (sizeInBytes >= UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; auto bufferSize = static_cast(sizeInBytes); diff --git a/DirectXTex/DirectXTex.h b/DirectXTex/DirectXTex.h index cc82d78..96da493 100644 --- a/DirectXTex/DirectXTex.h +++ b/DirectXTex/DirectXTex.h @@ -17,6 +17,7 @@ #include #include +#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__) #ifdef _GAMING_XBOX_SCARLETT #include @@ -28,13 +29,19 @@ #include #endif #endif +#else +#include +#include +#endif #include +#ifdef WIN32 #include struct IWICImagingFactory; struct IWICMetadataQueryReader; +#endif #define DIRECTX_TEX_VERSION 191 @@ -285,6 +292,7 @@ namespace DirectX _In_ TGA_FLAGS flags, _Out_ TexMetadata& metadata) noexcept; +#ifdef WIN32 HRESULT __cdecl GetMetadataFromWICMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ WIC_FLAGS flags, @@ -296,6 +304,7 @@ namespace DirectX _In_ WIC_FLAGS flags, _Out_ TexMetadata& metadata, _In_opt_ std::function getMQR = nullptr); +#endif // Compatability helpers HRESULT __cdecl GetMetadataFromTGAMemory( @@ -450,6 +459,7 @@ namespace DirectX _In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr) noexcept; // WIC operations +#ifdef WIN32 HRESULT __cdecl LoadFromWICMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ WIC_FLAGS flags, @@ -479,6 +489,7 @@ namespace DirectX _In_ WIC_FLAGS flags, _In_ REFGUID guidContainerFormat, _In_z_ const wchar_t* szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function setCustomProps = nullptr); +#endif // WIN32 // Compatability helpers HRESULT __cdecl LoadFromTGAMemory( @@ -504,11 +515,13 @@ namespace DirectX 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_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ TEX_FR_FLAGS flags, _Out_ ScratchImage& result) noexcept; // Flip and/or rotate image +#endif enum TEX_FILTER_FLAGS : unsigned long { @@ -788,7 +801,7 @@ namespace DirectX //--------------------------------------------------------------------------------- // WIC utility code - +#ifdef WIN32 enum WICCodecs { WIC_CODEC_BMP = 1, // Windows Bitmap (.bmp) @@ -804,6 +817,7 @@ namespace DirectX IWICImagingFactory* __cdecl GetWICFactory(bool& iswic2) noexcept; void __cdecl SetWICFactory(_In_opt_ IWICImagingFactory* pWIC) noexcept; +#endif //--------------------------------------------------------------------------------- // Direct3D 11 functions diff --git a/DirectXTex/DirectXTexCompress.cpp b/DirectXTex/DirectXTexCompress.cpp index 07e0c01..85be9b5 100644 --- a/DirectXTex/DirectXTexCompress.cpp +++ b/DirectXTex/DirectXTexCompress.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexCompress.cpp -// +// // DirectX Texture Library - Texture compression // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -89,7 +89,7 @@ namespace if (sbpp < 8) { // 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 @@ -102,7 +102,7 @@ namespace size_t blocksize; TEX_FILTER_FLAGS 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]; const uint8_t *pSrc = image.pixels; @@ -218,7 +218,7 @@ namespace if (sbpp < 8) { // 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 @@ -231,7 +231,7 @@ namespace size_t blocksize; TEX_FILTER_FLAGS 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 const size_t nBlocks = std::max(1, (image.width + 3) / 4) * std::max(1, (image.height + 3) / 4); @@ -394,7 +394,7 @@ namespace if (dbpp < 8) { // 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 @@ -438,7 +438,7 @@ namespace case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } XM_ALIGNED_DATA(16) XMVECTOR temp[16]; @@ -603,7 +603,7 @@ HRESULT DirectX::Compress( if (IsTypeless(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 HRESULT hr = image.Initialize2D(format, srcImage.width, srcImage.height, 1, 1); @@ -655,7 +655,7 @@ HRESULT DirectX::Compress( if (IsTypeless(format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; cImages.Release(); @@ -749,7 +749,7 @@ HRESULT DirectX::Decompress( return E_INVALIDARG; if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } // Create decompressed image @@ -802,7 +802,7 @@ HRESULT DirectX::Decompress( return E_INVALIDARG; if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } images.Release(); diff --git a/DirectXTex/DirectXTexCompressGPU.cpp b/DirectXTex/DirectXTexCompressGPU.cpp index 7610025..5fb38b1 100644 --- a/DirectXTex/DirectXTexCompressGPU.cpp +++ b/DirectXTex/DirectXTexCompressGPU.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexCompressGPU.cpp -// +// // DirectX Texture Library - DirectCompute-based texture compression // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -219,7 +219,7 @@ HRESULT DirectX::Compress( if (IsTypeless(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 std::unique_ptr gpubc(new (std::nothrow) GPUCompressBC); @@ -272,7 +272,7 @@ HRESULT DirectX::Compress( if (IsTypeless(format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; cImages.Release(); @@ -414,7 +414,7 @@ HRESULT DirectX::Compress( break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } return S_OK; diff --git a/DirectXTex/DirectXTexConvert.cpp b/DirectXTex/DirectXTexConvert.cpp index fecb43d..85fcab0 100644 --- a/DirectXTex/DirectXTexConvert.cpp +++ b/DirectXTex/DirectXTexConvert.cpp @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------------- // DirectXTexConvert.cpp -// -// DirectX Texture Library - Image pixel format conversion +// +// DirectX Texture Library - Image pixel format conversion // // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. @@ -435,7 +435,7 @@ void DirectX::_CopyScanline( return; size_t size = std::min(outSize, inSize); - memcpy_s(pDestination, outSize, pSource, size); + memcpy(pDestination, pSource, size); } @@ -605,7 +605,7 @@ void DirectX::_SwizzleScanline( return; size_t size = std::min(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: { 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; @@ -2972,10 +2972,9 @@ namespace { XBOX_DXGI_FORMAT_R4G4_UNORM, 4, CONVF_UNORM | CONVF_R | CONVF_G }, }; -#pragma prefast( suppress : 25004, "Signature must match bsearch_s" ); - int __cdecl ConvertCompare(void *context, const void* ptr1, const void *ptr2) noexcept +#pragma prefast( suppress : 25004, "Signature must match bsearch" ); + int __cdecl ConvertCompare(const void* ptr1, const void *ptr2) noexcept { - UNREFERENCED_PARAMETER(context); auto p1 = static_cast(ptr1); auto p2 = static_cast(ptr2); if (p1->format == p2->format) return 0; @@ -2998,8 +2997,8 @@ uint32_t DirectX::_GetConvertFlags(DXGI_FORMAT format) noexcept #endif ConvertData key = { format, 0, 0 }; - auto in = reinterpret_cast(bsearch_s(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), - ConvertCompare, nullptr)); + auto in = reinterpret_cast(bsearch(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), + ConvertCompare)); return (in) ? in->flags : 0; } @@ -3032,10 +3031,10 @@ void DirectX::_ConvertScanline( // Determine conversion details about source and dest formats ConvertData key = { inFormat, 0, 0 }; auto in = reinterpret_cast( - 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; auto out = reinterpret_cast( - 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) { assert(false); @@ -4373,6 +4372,14 @@ namespace _Out_ WICPixelFormatGUID& pfGUID, _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(&targetGUID, 0, sizeof(GUID)); @@ -4514,6 +4521,7 @@ namespace } return true; +#endif // WIN32 } //------------------------------------------------------------------------------------- @@ -4527,6 +4535,15 @@ namespace _In_ float threshold, _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.height == destImage.height); @@ -4553,7 +4570,7 @@ namespace if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr source; hr = pWIC->CreateBitmapFromMemory(static_cast(srcImage.width), static_cast(srcImage.height), pfGUID, @@ -4571,9 +4588,9 @@ namespace return hr; return S_OK; +#endif // WIN32 } - //------------------------------------------------------------------------------------- // Convert the source image (not using WIC) //------------------------------------------------------------------------------------- @@ -4840,7 +4857,7 @@ HRESULT DirectX::Convert( || IsPlanar(srcImage.format) || IsPlanar(format) || IsPalettized(srcImage.format) || IsPalettized(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)) return E_INVALIDARG; @@ -4896,7 +4913,7 @@ HRESULT DirectX::Convert( || IsPlanar(metadata.format) || IsPlanar(format) || IsPalettized(metadata.format) || IsPalettized(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)) return E_INVALIDARG; @@ -5049,7 +5066,7 @@ HRESULT DirectX::ConvertToSinglePlane(const Image& srcImage, ScratchImage& image DXGI_FORMAT format = _PlanarToSingle(srcImage.format); 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)) return E_INVALIDARG; @@ -5092,12 +5109,12 @@ HRESULT DirectX::ConvertToSinglePlane( if (metadata.IsVolumemap()) { // 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); 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)) return E_INVALIDARG; diff --git a/DirectXTex/DirectXTexD3D11.cpp b/DirectXTex/DirectXTexD3D11.cpp index 00c7127..f684dad 100644 --- a/DirectXTex/DirectXTexD3D11.cpp +++ b/DirectXTex/DirectXTexD3D11.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexD3D11.cpp -// +// // DirectX Texture Library - Direct3D 11 helpers // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -117,7 +117,7 @@ namespace for (size_t h = 0; h < lines; ++h) { size_t msize = std::min(img->rowPitch, mapped.RowPitch); - memcpy_s(dptr, img->rowPitch, sptr, msize); + memcpy(dptr, sptr, msize); sptr += mapped.RowPitch; dptr += img->rowPitch; } @@ -176,7 +176,7 @@ namespace for (size_t h = 0; h < lines; ++h) { size_t msize = std::min(img->rowPitch, mapped.RowPitch); - memcpy_s(dptr, img->rowPitch, sptr, msize); + memcpy(dptr, sptr, msize); sptr += mapped.RowPitch; dptr += img->rowPitch; } @@ -454,7 +454,7 @@ HRESULT DirectX::CreateTextureEx( if (metadata.arraySize > 1) // 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; diff --git a/DirectXTex/DirectXTexD3D12.cpp b/DirectXTex/DirectXTexD3D12.cpp index 0f61879..c6101b8 100644 --- a/DirectXTex/DirectXTexD3D12.cpp +++ b/DirectXTex/DirectXTexD3D12.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexD3D12.cpp -// +// // DirectX Texture Library - Direct3D 12 helpers // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -16,6 +16,7 @@ #pragma clang diagnostic ignored "-Wsign-conversion" #endif +#ifdef WIN32 #ifdef _GAMING_XBOX_SCARLETT #include #elif (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX) @@ -24,6 +25,10 @@ #define D3DX12_NO_STATE_OBJECT_HELPERS #include "d3dx12.h" #endif +#else +#include "directx/d3dx12.h" +#include "dxguids/dxguids.h" +#endif #ifdef __clang__ #pragma clang diagnostic pop @@ -133,7 +138,7 @@ namespace if ((numberOfPlanes > 1) && IsDepthStencil(desc.Format)) { // 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; @@ -299,7 +304,13 @@ namespace // Block until the copy is complete while (fence->GetCompletedValue() < 1) + { +#ifdef WIN32 SwitchToThread(); +#else + std::this_thread::yield(); +#endif + } 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_ @@ -510,7 +521,7 @@ HRESULT DirectX::PrepareUpload( if ((numberOfPlanes > 1) && IsDepthStencil(metadata.format)) { // 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) @@ -536,7 +547,7 @@ HRESULT DirectX::PrepareUpload( if (metadata.arraySize > 1) // 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) { diff --git a/DirectXTex/DirectXTexDDS.cpp b/DirectXTex/DirectXTexDDS.cpp index 9a5d323..1bb1483 100644 --- a/DirectXTex/DirectXTexDDS.cpp +++ b/DirectXTex/DirectXTexDDS.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexDDS.cpp -// +// // DirectX Texture Library - Microsoft DirectDraw Surface (DDS) file format reader/writer // // 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_DX10 = 0x10000, // Has the 'DX10' extension header CONV_FLAGS_PMALPHA = 0x20000, // Contains premultiplied alpha data - CONV_FLAGS_L8 = 0x40000, // Source is a 8 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_L8 = 0x40000, // Source is a 8 luminance format + CONV_FLAGS_L16 = 0x80000, // Source is a 16 luminance format + CONV_FLAGS_A8L8 = 0x100000, // Source is a 8:8 luminance format }; struct LegacyDDS @@ -284,7 +284,7 @@ namespace 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 ") @@ -323,13 +323,13 @@ namespace metadata.arraySize = d3d10ext->arraySize; if (metadata.arraySize == 0) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } metadata.format = d3d10ext->dxgiFormat; if (!IsValid(metadata.format) || IsPalettized(metadata.format)) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } static_assert(static_cast(TEX_MISC_TEXTURECUBE) == static_cast(DDS_RESOURCE_MISC_TEXTURECUBE), "DDS header mismatch"); @@ -343,7 +343,7 @@ namespace // D3DX writes 1D textures with a fixed Height of 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; @@ -368,11 +368,11 @@ namespace case DDS_DIMENSION_TEXTURE3D: if (!(pHeader->flags & DDS_HEADER_FLAGS_VOLUME)) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } if (metadata.arraySize > 1) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; metadata.width = pHeader->width; metadata.height = pHeader->height; @@ -381,7 +381,7 @@ namespace break; default: - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } static_assert(static_cast(TEX_MISC2_ALPHA_MODE_MASK) == static_cast(DDS_MISC_FLAGS2_ALPHA_MODE_MASK), "DDS header mismatch"); @@ -411,7 +411,7 @@ namespace { // We require all six faces to be defined 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.miscFlags |= TEX_MISC_TEXTURECUBE; @@ -428,7 +428,7 @@ namespace metadata.format = GetDXGIFormat(*pHeader, pHeader->ddspf, flags, convFlags); 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 if (flags & DDS_FLAGS_EXPAND_LUMINANCE) @@ -533,14 +533,14 @@ namespace || metadata.height > 16384u /* D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION */ || 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 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 */) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } @@ -564,7 +564,7 @@ HRESULT DirectX::_EncodeDDSHeader( return E_INVALIDARG; if (IsPalettized(metadata.format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; 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 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; } @@ -588,28 +588,28 @@ HRESULT DirectX::_EncodeDDSHeader( { switch (metadata.format) { - case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy_s(&ddpf, sizeof(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_R8G8_UNORM: memcpy_s(&ddpf, sizeof(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_R8_UNORM: memcpy_s(&ddpf, sizeof(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_R8G8_B8G8_UNORM: memcpy_s(&ddpf, sizeof(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_BC1_UNORM: memcpy_s(&ddpf, sizeof(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_BC3_UNORM: memcpy_s(&ddpf, sizeof(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_BC5_SNORM: memcpy_s(&ddpf, sizeof(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_B5G5R5A1_UNORM: memcpy_s(&ddpf, sizeof(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_R8G8B8A8_SNORM: memcpy_s(&ddpf, sizeof(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_B8G8R8A8_UNORM: memcpy_s(&ddpf, sizeof(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_B4G4R4A4_UNORM: memcpy_s(&ddpf, sizeof(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_R8G8B8A8_UNORM: memcpy(&ddpf, &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R16G16_UNORM: memcpy(&ddpf, &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8G8_UNORM: memcpy(&ddpf, &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R16_UNORM: memcpy(&ddpf, &DDSPF_L16, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8_UNORM: memcpy(&ddpf, &DDSPF_L8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_A8_UNORM: memcpy(&ddpf, &DDSPF_A8, 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(&ddpf, &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_BC1_UNORM: memcpy(&ddpf, &DDSPF_DXT1, 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(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_BC4_SNORM: memcpy(&ddpf, &DDSPF_BC4_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(&ddpf, &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy(&ddpf, &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8G8_SNORM: memcpy(&ddpf, &DDSPF_V8U8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8G8B8A8_SNORM: memcpy(&ddpf, &DDSPF_Q8W8V8U8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R16G16_SNORM: memcpy(&ddpf, &DDSPF_V16U16, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy(&ddpf, &DDSPF_A8R8G8B8, 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(&ddpf, &DDSPF_A4R4G4B4, 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 case DXGI_FORMAT_R32G32B32A32_FLOAT: @@ -642,40 +642,40 @@ HRESULT DirectX::_EncodeDDSHeader( if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) { // 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; case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: 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; case DXGI_FORMAT_BC1_UNORM_SRGB: 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; case DXGI_FORMAT_BC2_UNORM_SRGB: 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; case DXGI_FORMAT_BC3_UNORM_SRGB: 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; 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) { ddpf.fourCC = MAKEFOURCC('A', 'T', 'I', '1'); @@ -683,7 +683,7 @@ HRESULT DirectX::_EncodeDDSHeader( break; 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) { ddpf.fourCC = MAKEFOURCC('A', 'T', 'I', '2'); @@ -693,14 +693,14 @@ HRESULT DirectX::_EncodeDDSHeader( case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: 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; case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: 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; @@ -714,7 +714,7 @@ HRESULT DirectX::_EncodeDDSHeader( if (ddpf.size == 0) { if (flags & DDS_FLAGS_FORCE_DX9_LEGACY) - return HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE); + return HRESULT_E_CANNOT_MAKE; required += sizeof(DDS_HEADER_DXT10); } @@ -813,7 +813,7 @@ HRESULT DirectX::_EncodeDDSHeader( 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(reinterpret_cast(header) + sizeof(DDS_HEADER)); assert(ext); @@ -856,7 +856,7 @@ HRESULT DirectX::_EncodeDDSHeader( } else { - memcpy_s(&header->ddspf, sizeof(header->ddspf), &ddpf, sizeof(ddpf)); + memcpy(&header->ddspf, &ddpf, sizeof(ddpf)); } return S_OK; @@ -1074,7 +1074,7 @@ namespace switch (outFormat) { case DXGI_FORMAT_B4G4R4A4_UNORM: - // D3DFMT_A4L4 -> DXGI_FORMAT_B4G4R4A4_UNORM + // D3DFMT_A4L4 -> DXGI_FORMAT_B4G4R4A4_UNORM if (inSize >= 1 && outSize >= 2) { const uint8_t * __restrict sPtr = static_cast(pSource); @@ -1249,7 +1249,7 @@ namespace size_t pixelSize, nimages; if (!_DetermineImageArray(metadata, cpFlags, nimages, pixelSize)) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; if ((nimages == 0) || (nimages != image.GetImageCount())) { @@ -1258,7 +1258,7 @@ namespace if (pixelSize > size) { - return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); + return HRESULT_E_HANDLE_EOF; } std::unique_ptr timages(new (std::nothrow) Image[nimages]); @@ -1324,14 +1324,14 @@ namespace if (IsCompressed(metadata.format)) { size_t csize = std::min(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 (images[index].width < 4 || images[index].height < 4) { csize = std::min(images[index].slicePitch, timages[lastgood].slicePitch); - memcpy_s(pDest, images[index].slicePitch, timages[lastgood].pixels, csize); + memcpy(pDest, timages[lastgood].pixels, csize); } else { @@ -1348,7 +1348,7 @@ namespace size_t csize = std::min(dpitch, spitch); for (size_t h = 0; h < count; ++h) { - memcpy_s(pDest, dpitch, pSrc, csize); + memcpy(pDest, pSrc, csize); pSrc += spitch; pDest += dpitch; } @@ -1426,14 +1426,14 @@ namespace if (IsCompressed(metadata.format)) { size_t csize = std::min(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 (images[index].width < 4 || images[index].height < 4) { csize = std::min(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) { @@ -1444,7 +1444,7 @@ namespace else if (IsPlanar(metadata.format)) { // Direct3D does not support any planar formats for Texture3D - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } else { @@ -1509,7 +1509,7 @@ namespace const TexMetadata& metadata = image.GetMetadata(); 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; if (convFlags & CONV_FLAGS_SWIZZLE) @@ -1575,6 +1575,7 @@ HRESULT DirectX::GetMetadataFromDDSFile( if (!szFile) return E_INVALIDARG; +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); #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) 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 - if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) + if (len < (sizeof(DDS_HEADER) + sizeof(uint32_t))) { 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); uint8_t header[MAX_HEADER_SIZE] = {}; +#ifdef WIN32 DWORD bytesRead = 0; if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); } + auto headerLen = static_cast(bytesRead); +#else + auto headerLen = std::min(len, MAX_HEADER_SIZE); + + inFile.read(reinterpret_cast(header), headerLen); + if (!inFile) + return E_FAIL; +#endif + 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(); +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); #else ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr))); #endif - if (!hFile) { 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) 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 - if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) + if (len < (sizeof(DDS_HEADER) + sizeof(uint32_t))) { 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); uint8_t header[MAX_HEADER_SIZE] = {}; +#ifdef WIN32 DWORD bytesRead = 0; if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); } + auto headerLen = static_cast(bytesRead); +#else + auto headerLen = std::min(len, MAX_HEADER_SIZE); + + inFile.read(reinterpret_cast(header), headerLen); + if (!inFile) + return E_FAIL; +#endif + uint32_t convFlags = 0; TexMetadata mdata; - HRESULT hr = DecodeDDSHeader(header, bytesRead, flags, mdata, convFlags); + HRESULT hr = DecodeDDSHeader(header, headerLen, flags, mdata, convFlags); if (FAILED(hr)) return hr; - DWORD offset = MAX_HEADER_SIZE; + size_t offset = MAX_HEADER_SIZE; if (!(convFlags & CONV_FLAGS_DX10)) { +#ifdef WIN32 // Must reset file position since we read more than the standard header above LARGE_INTEGER filePos = { { sizeof(uint32_t) + sizeof(DDS_HEADER), 0 } }; if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) { 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); } @@ -1778,6 +1843,7 @@ HRESULT DirectX::LoadFromDDSFile( return E_OUTOFMEMORY; } +#ifdef WIN32 if (!ReadFile(hFile.get(), pal8.get(), 256 * sizeof(uint32_t), &bytesRead, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -1787,11 +1853,16 @@ HRESULT DirectX::LoadFromDDSFile( { return E_FAIL; } +#else + inFile.read(reinterpret_cast(pal8.get()), 256 * sizeof(uint32_t)); + if (!inFile) + return E_FAIL; +#endif offset += (256 * sizeof(uint32_t)); } - DWORD remaining = fileInfo.EndOfFile.LowPart - offset; + size_t remaining = len - offset; if (remaining == 0) return E_FAIL; @@ -1808,7 +1879,8 @@ HRESULT DirectX::LoadFromDDSFile( return E_OUTOFMEMORY; } - if (!ReadFile(hFile.get(), temp.get(), remaining, &bytesRead, nullptr)) +#ifdef WIN32 + if (!ReadFile(hFile.get(), temp.get(), static_cast(remaining), &bytesRead, nullptr)) { image.Release(); return HRESULT_FROM_WIN32(GetLastError()); @@ -1819,6 +1891,14 @@ HRESULT DirectX::LoadFromDDSFile( image.Release(); return E_FAIL; } +#else + inFile.read(reinterpret_cast(temp.get()), remaining); + if (!inFile) + { + image.Release(); + return E_FAIL; + } +#endif CP_FLAGS cflags = CP_FLAGS_NONE; if (flags & DDS_FLAGS_LEGACY_DWORD) @@ -1848,20 +1928,29 @@ HRESULT DirectX::LoadFromDDSFile( if (remaining < image.GetPixelsSize()) { image.Release(); - return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); + return HRESULT_E_HANDLE_EOF; } if (image.GetPixelsSize() > UINT32_MAX) { image.Release(); - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; } +#ifdef WIN32 if (!ReadFile(hFile.get(), image.GetPixels(), static_cast(image.GetPixelsSize()), &bytesRead, nullptr)) { image.Release(); return HRESULT_FROM_WIN32(GetLastError()); } +#else + inFile.read(reinterpret_cast(image.GetPixels()), image.GetPixelsSize()); + if (!inFile) + { + image.Release(); + return E_FAIL; + } +#endif if (convFlags & (CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA)) { @@ -1974,11 +2063,7 @@ HRESULT DirectX::SaveToDDSMemory( if (fastpath) { size_t pixsize = images[index].slicePitch; - if (memcpy_s(pDestination, remaining, images[index].pixels, pixsize)) - { - blob.Release(); - return E_FAIL; - } + memcpy(pDestination, images[index].pixels, pixsize); pDestination += pixsize; remaining -= pixsize; @@ -2003,11 +2088,7 @@ HRESULT DirectX::SaveToDDSMemory( size_t tremaining = remaining; for (size_t j = 0; j < lines; ++j) { - if (memcpy_s(dPtr, tremaining, sPtr, csize)) - { - blob.Release(); - return E_FAIL; - } + memcpy(dPtr, sPtr, csize); sPtr += rowPitch; dPtr += ddsRowPitch; @@ -2048,11 +2129,7 @@ HRESULT DirectX::SaveToDDSMemory( if (fastpath) { size_t pixsize = images[index].slicePitch; - if (memcpy_s(pDestination, remaining, images[index].pixels, pixsize)) - { - blob.Release(); - return E_FAIL; - } + memcpy(pDestination, images[index].pixels, pixsize); pDestination += pixsize; remaining -= pixsize; @@ -2077,11 +2154,7 @@ HRESULT DirectX::SaveToDDSMemory( size_t tremaining = remaining; for (size_t j = 0; j < lines; ++j) { - if (memcpy_s(dPtr, tremaining, sPtr, csize)) - { - blob.Release(); - return E_FAIL; - } + memcpy(dPtr, sPtr, csize); sPtr += rowPitch; dPtr += ddsRowPitch; @@ -2133,6 +2206,7 @@ HRESULT DirectX::SaveToDDSFile( return hr; // Create file and write header +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr))); #else @@ -2155,6 +2229,15 @@ HRESULT DirectX::SaveToDDSFile( { 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(header), static_cast(required)); + if (!outFile) + return E_FAIL; +#endif // Write images switch (static_cast(metadata.dimension)) @@ -2183,6 +2266,7 @@ HRESULT DirectX::SaveToDDSFile( if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX)) { +#ifdef WIN32 if (!WriteFile(hFile.get(), images[index].pixels, static_cast(ddsSlicePitch), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -2192,6 +2276,11 @@ HRESULT DirectX::SaveToDDSFile( { return E_FAIL; } +#else + outFile.write(reinterpret_cast(images[index].pixels), static_cast(ddsSlicePitch)); + if (!outFile) + return E_FAIL; +#endif } else { @@ -2203,13 +2292,14 @@ HRESULT DirectX::SaveToDDSFile( } if (ddsRowPitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; const uint8_t * __restrict sPtr = images[index].pixels; size_t lines = ComputeScanlines(metadata.format, images[index].height); for (size_t j = 0; j < lines; ++j) { +#ifdef WIN32 if (!WriteFile(hFile.get(), sPtr, static_cast(ddsRowPitch), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -2219,6 +2309,11 @@ HRESULT DirectX::SaveToDDSFile( { return E_FAIL; } +#else + outFile.write(reinterpret_cast(sPtr), static_cast(ddsRowPitch)); + if (!outFile) + return E_FAIL; +#endif sPtr += rowPitch; } @@ -2256,6 +2351,7 @@ HRESULT DirectX::SaveToDDSFile( if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX)) { +#ifdef WIN32 if (!WriteFile(hFile.get(), images[index].pixels, static_cast(ddsSlicePitch), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -2265,6 +2361,11 @@ HRESULT DirectX::SaveToDDSFile( { return E_FAIL; } +#else + outFile.write(reinterpret_cast(images[index].pixels), static_cast(ddsSlicePitch)); + if (!outFile) + return E_FAIL; +#endif } else { @@ -2276,13 +2377,14 @@ HRESULT DirectX::SaveToDDSFile( } if (ddsRowPitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; const uint8_t * __restrict sPtr = images[index].pixels; size_t lines = ComputeScanlines(metadata.format, images[index].height); for (size_t j = 0; j < lines; ++j) { +#ifdef WIN32 if (!WriteFile(hFile.get(), sPtr, static_cast(ddsRowPitch), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -2292,7 +2394,11 @@ HRESULT DirectX::SaveToDDSFile( { return E_FAIL; } - +#else + outFile.write(reinterpret_cast(sPtr), static_cast(ddsRowPitch)); + if (!outFile) + return E_FAIL; +#endif sPtr += rowPitch; } } @@ -2308,7 +2414,9 @@ HRESULT DirectX::SaveToDDSFile( return E_FAIL; } +#ifdef WIN32 delonfail.clear(); +#endif return S_OK; } diff --git a/DirectXTex/DirectXTexFlipRotate.cpp b/DirectXTex/DirectXTexFlipRotate.cpp index 5f6c789..eeba532 100644 --- a/DirectXTex/DirectXTexFlipRotate.cpp +++ b/DirectXTex/DirectXTexFlipRotate.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexFlipRotate.cpp -// +// // DirectX Texture Library - Image flip/rotate operations // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -37,7 +37,7 @@ namespace if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr source; HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast(srcImage.width), static_cast(srcImage.height), pfGUID, @@ -63,7 +63,7 @@ namespace if (memcmp(&pfFR, &pfGUID, sizeof(GUID)) != 0) { // 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; @@ -199,7 +199,7 @@ HRESULT DirectX::FlipRotate( if (IsCompressed(srcImage.format)) { // 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(TEX_FR_ROTATE0) == static_cast(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC"); @@ -292,7 +292,7 @@ HRESULT DirectX::FlipRotate( if (IsCompressed(metadata.format)) { // 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(TEX_FR_ROTATE0) == static_cast(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC"); diff --git a/DirectXTex/DirectXTexHDR.cpp b/DirectXTex/DirectXTexHDR.cpp index f00d19a..907bde6 100644 --- a/DirectXTex/DirectXTexHDR.cpp +++ b/DirectXTex/DirectXTexHDR.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexHDR.cpp -// +// // DirectX Texture Library - Radiance HDR (RGBE) file format reader/writer // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -17,10 +17,10 @@ // +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 // we support only that one as that's what other Radiance parsing code does as well. @@ -34,6 +34,13 @@ using namespace DirectX; +#ifndef WIN32 +#include + +#define strncpy_s strncpy +#define sscanf_s sscanf +#endif + namespace { const char g_Signature[] = "#?RADIANCE"; @@ -70,6 +77,19 @@ namespace return 0; } +#ifndef WIN32 + template + 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 //------------------------------------------------------------------------------------- @@ -86,10 +106,10 @@ namespace memset(&metadata, 0, sizeof(TexMetadata)); exposure = 1.f; - + if (size < sizeof(g_Signature)) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } // Verify magic signature @@ -137,7 +157,7 @@ namespace 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; @@ -217,10 +237,8 @@ namespace if (orientation[0] != '-' && orientation[1] != 'Y') { // We only support the -Y +X orientation (see top of file) - return HRESULT_FROM_WIN32( - static_cast(((orientation[0] == '+' || orientation[0] == '-') && (orientation[1] == 'X' || orientation[1] == 'Y')) - ? ERROR_NOT_SUPPORTED : ERROR_INVALID_DATA) - ); + return (static_cast(((orientation[0] == '+' || orientation[0] == '-') && (orientation[1] == 'X' || orientation[1] == 'Y')))) + ? HRESULT_E_NOT_SUPPORTED : HRESULT_E_INVALID_DATA; } uint32_t height = 0; @@ -240,7 +258,7 @@ namespace else if (*ptr != '+') { // We only support the -Y +X orientation (see top of file) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } ++ptr; @@ -251,7 +269,7 @@ namespace else if (*ptr != 'X') { // We only support the -Y +X orientation (see top of file) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } ++ptr; @@ -266,7 +284,7 @@ namespace if (!width || !height) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } if (size == 0) @@ -580,6 +598,7 @@ HRESULT DirectX::GetMetadataFromHDRFile(const wchar_t* szFile, TexMetadata& meta if (!szFile) return E_INVALIDARG; +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); #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) 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 - if (fileInfo.EndOfFile.LowPart < sizeof(g_Signature)) + if (len < sizeof(g_Signature)) { return E_FAIL; } // Read the first part of the file to find the header uint8_t header[8192] = {}; + +#ifdef WIN32 DWORD bytesRead = 0; if (!ReadFile(hFile.get(), header, std::min(sizeof(header), fileInfo.EndOfFile.LowPart), &bytesRead, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); } + auto headerLen = static_cast(bytesRead); +#else + auto headerLen = std::min(sizeof(header), len); + + inFile.read(reinterpret_cast(header), headerLen); + if (!inFile) + return E_FAIL; +#endif + size_t offset; 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; auto scanLine = reinterpret_cast(destPtr); - + if (inColor[0] == 2 && inColor[1] == 2 && inColor[2] < 128) { // Adaptive Run Length Encoding (RLE) @@ -852,6 +902,7 @@ HRESULT DirectX::LoadFromHDRFile(const wchar_t* szFile, TexMetadata* metadata, S image.Release(); +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); #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) 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 - if (fileInfo.EndOfFile.LowPart < sizeof(g_Signature)) + if (len < sizeof(g_Signature)) { return E_FAIL; } // Read file - std::unique_ptr temp(new (std::nothrow) uint8_t[fileInfo.EndOfFile.LowPart]); + std::unique_ptr temp(new (std::nothrow) uint8_t[len]); if (!temp) { return E_OUTOFMEMORY; } +#ifdef WIN32 DWORD bytesRead = 0; 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; } +#else + inFile.read(reinterpret_cast(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 // uncompresssed, but we just don't support them. - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } int fpp; @@ -932,7 +1009,7 @@ HRESULT DirectX::SaveToHDRMemory(const Image& image, Blob& blob) noexcept break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } blob.Release(); @@ -952,7 +1029,7 @@ HRESULT DirectX::SaveToHDRMemory(const Image& image, Blob& blob) noexcept // Copy header auto dPtr = static_cast(blob.GetBufferPointer()); assert(dPtr != nullptr); - memcpy_s(dPtr, blob.GetBufferSize(), header, headerLen); + memcpy(dPtr, header, headerLen); dPtr += headerLen; #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 // uncompresssed, but we just don't support them. - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } int fpp; @@ -1044,10 +1121,11 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } // Create file and write header +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr))); #else @@ -1059,12 +1137,17 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce } 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 slicePitch = uint64_t(image.height) * pitch; if (pitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; size_t rowPitch = static_cast(pitch); @@ -1078,6 +1161,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce return hr; // Write blob +#ifdef WIN32 auto bytesToWrite = static_cast(blob.GetBufferSize()); DWORD bytesWritten; 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; } +#else + outFile.write(reinterpret_cast(blob.GetBufferPointer()), + static_cast(blob.GetBufferSize())); + + if (!outFile) + return E_FAIL; +#endif } else { @@ -1103,6 +1194,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce char header[256] = {}; sprintf_s(header, g_Header, image.height, image.width); +#ifdef WIN32 auto headerLen = static_cast(strlen(header)); DWORD bytesWritten; @@ -1113,6 +1205,11 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce if (bytesWritten != headerLen) return E_FAIL; +#else + outFile.write(reinterpret_cast(header), static_cast(strlen(header))); + if (!outFile) + return E_FAIL; +#endif #ifdef DISABLE_COMPRESS // Uncompressed write @@ -1122,6 +1219,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce FloatToRGBE(rgbe, reinterpret_cast(sPtr), image.width, fpp); sPtr += image.rowPitch; + #ifdef WIN32 if (!WriteFile(hFile.get(), rgbe, static_cast(rowPitch), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -1129,6 +1227,12 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce if (bytesWritten != rowPitch) return E_FAIL; + #else + outFile.write(reinterpret_cast(rgbe), static_cast(rowPitch)); + if (!outFile) + return E_FAIL; + #endif + } #else 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 > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; +#ifdef WIN32 if (!WriteFile(hFile.get(), enc, static_cast(encSize), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -1159,9 +1264,15 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce if (bytesWritten != encSize) return E_FAIL; +#else + outFile.write(reinterpret_cast(enc), static_cast(encSize)); + if (!outFile) + return E_FAIL; +#endif } else { +#ifdef WIN32 if (!WriteFile(hFile.get(), rgbe, static_cast(rowPitch), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -1169,12 +1280,19 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce if (bytesWritten != rowPitch) return E_FAIL; +#else + outFile.write(reinterpret_cast(rgbe), static_cast(rowPitch)); + if (!outFile) + return E_FAIL; +#endif } } #endif } +#ifdef WIN32 delonfail.clear(); +#endif return S_OK; } diff --git a/DirectXTex/DirectXTexImage.cpp b/DirectXTex/DirectXTexImage.cpp index 0e12940..5ca3b70 100644 --- a/DirectXTex/DirectXTexImage.cpp +++ b/DirectXTex/DirectXTexImage.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexImage.cpp -// +// // DirectX Texture Library - Image container // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -20,6 +20,19 @@ 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 //------------------------------------------------------------------------------------- @@ -288,7 +301,7 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc return E_INVALIDARG; if (IsPalettized(mdata.format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; size_t mipLevels = mdata.mipLevels; @@ -325,7 +338,7 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } Release(); @@ -342,7 +355,7 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc size_t pixelSize, nimages; 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]; if (!m_image) @@ -390,7 +403,7 @@ HRESULT ScratchImage::Initialize2D(DXGI_FORMAT fmt, size_t width, size_t height, return E_INVALIDARG; if (IsPalettized(fmt)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; if (!_CalculateMipLevels(width, height, mipLevels)) return E_INVALIDARG; @@ -409,7 +422,7 @@ HRESULT ScratchImage::Initialize2D(DXGI_FORMAT fmt, size_t width, size_t height, size_t pixelSize, nimages; 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]; if (!m_image) @@ -441,7 +454,7 @@ HRESULT ScratchImage::Initialize3D(DXGI_FORMAT fmt, size_t width, size_t height, return E_INVALIDARG; if (IsPalettized(fmt)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; if (!_CalculateMipLevels3D(width, height, depth, mipLevels)) return E_INVALIDARG; @@ -460,7 +473,7 @@ HRESULT ScratchImage::Initialize3D(DXGI_FORMAT fmt, size_t width, size_t height, size_t pixelSize, nimages; 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]; if (!m_image) @@ -533,7 +546,7 @@ HRESULT ScratchImage::InitializeFromImage(const Image& srcImage, bool allow1D, C for (size_t y = 0; y < rowCount; ++y) { - memcpy_s(dptr, dpitch, sptr, size); + memcpy(dptr, sptr, size); sptr += spitch; dptr += dpitch; } @@ -592,7 +605,7 @@ HRESULT ScratchImage::InitializeArrayFromImages(const Image* images, size_t nIma for (size_t y = 0; y < rowCount; ++y) { - memcpy_s(dptr, dpitch, sptr, size); + memcpy(dptr, sptr, size); sptr += spitch; dptr += dpitch; } @@ -668,7 +681,7 @@ HRESULT ScratchImage::Initialize3DFromImages(const Image* images, size_t depth, for (size_t y = 0; y < rowCount; ++y) { - memcpy_s(dptr, dpitch, sptr, size); + memcpy(dptr, sptr, size); sptr += spitch; dptr += dpitch; } diff --git a/DirectXTex/DirectXTexMipmaps.cpp b/DirectXTex/DirectXTexMipmaps.cpp index b6fa404..e233421 100644 --- a/DirectXTex/DirectXTexMipmaps.cpp +++ b/DirectXTex/DirectXTexMipmaps.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexMipMaps.cpp -// +// // DirectX Texture Library - Mip-map generation // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -64,7 +64,7 @@ namespace return mipLevels; } - +#ifdef WIN32 HRESULT EnsureWicBitmapPixelFormat( _In_ IWICImagingFactory* pWIC, _In_ IWICBitmap* src, @@ -116,6 +116,7 @@ namespace return hr; } +#endif // WIN32 #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; // Also used by Compress +#ifdef WIN32 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; // Also used by Resize +#endif bool _CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels) noexcept { @@ -391,6 +394,7 @@ namespace DirectX return true; } +#ifdef WIN32 //--- Resizing color and alpha channels separately using WIC --- _Use_decl_annotations_ HRESULT _ResizeSeparateColorAndAlpha( @@ -595,7 +599,7 @@ namespace DirectX if (SUCCEEDED(hr)) { if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr wicBitmap; hr = EnsureWicBitmapPixelFormat(pWIC, resizedColorWithAlpha.Get(), filter, desiredPixelFormat, wicBitmap.GetAddressOf()); @@ -607,10 +611,12 @@ namespace DirectX return hr; } +#endif // WIN32 } namespace { +#ifdef WIN32 //--- determine when to use WIC vs. non-WIC paths --- bool UseWICFiltering(_In_ DXGI_FORMAT format, _In_ TEX_FILTER_FLAGS filter) noexcept { @@ -705,7 +711,7 @@ namespace size_t height = baseImage.height; if (baseImage.rowPitch > UINT32_MAX || baseImage.slicePitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr source; HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast(width), static_cast(height), pfGUID, @@ -776,7 +782,7 @@ namespace return hr; 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(width), static_cast(height), _GetWICInterp(filter)); if (FAILED(hr)) @@ -822,6 +828,7 @@ namespace return S_OK; } +#endif // WIN32 //------------------------------------------------------------------------------------- @@ -873,7 +880,7 @@ namespace for (size_t h = 0; h < mdata.height; ++h) { size_t msize = std::min(dest->rowPitch, rowPitch); - memcpy_s(pDest, dest->rowPitch, pSrc, msize); + memcpy(pDest, pSrc, msize); pSrc += rowPitch; pDest += dest->rowPitch; } @@ -1618,7 +1625,7 @@ namespace for (size_t h = 0; h < height; ++h) { size_t msize = std::min(dest->rowPitch, rowPitch); - memcpy_s(pDest, dest->rowPitch, pSrc, msize); + memcpy(pDest, pSrc, msize); pSrc += rowPitch; pDest += dest->rowPitch; } @@ -2791,13 +2798,14 @@ HRESULT DirectX::GenerateMipMaps( 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; 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); WICPixelFormatGUID pfGUID = {}; @@ -2811,7 +2819,7 @@ HRESULT DirectX::GenerateMipMaps( if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) { if (filter & TEX_FILTER_FORCE_WIC) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; usewic = false; } @@ -2872,10 +2880,11 @@ HRESULT DirectX::GenerateMipMaps( } default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } else +#endif // WIN32 { //--- Use custom filters to generate mipmaps ---------------------------------- TexMetadata mdata = {}; @@ -2954,7 +2963,7 @@ HRESULT DirectX::GenerateMipMaps( return hr; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } } @@ -2973,7 +2982,7 @@ HRESULT DirectX::GenerateMipMaps( if (metadata.IsVolumemap() || 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)) 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"); +#ifdef WIN32 bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter); WICPixelFormatGUID pfGUID = {}; @@ -3024,7 +3034,7 @@ HRESULT DirectX::GenerateMipMaps( if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) { if (filter & TEX_FILTER_FORCE_WIC) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; usewic = false; } @@ -3098,10 +3108,11 @@ HRESULT DirectX::GenerateMipMaps( } default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } else +#endif // WIN32 { //--- Use custom filters to generate mipmaps ---------------------------------- TexMetadata mdata2 = metadata; @@ -3182,7 +3193,7 @@ HRESULT DirectX::GenerateMipMaps( return hr; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } } @@ -3203,7 +3214,7 @@ HRESULT DirectX::GenerateMipMaps3D( return E_INVALIDARG; if (filter & TEX_FILTER_FORCE_WIC) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; DXGI_FORMAT format = baseImages[0].format; size_t width = baseImages[0].width; @@ -3228,7 +3239,7 @@ HRESULT DirectX::GenerateMipMaps3D( } 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"); @@ -3294,7 +3305,7 @@ HRESULT DirectX::GenerateMipMaps3D( return hr; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } @@ -3311,11 +3322,11 @@ HRESULT DirectX::GenerateMipMaps3D( return E_INVALIDARG; if (filter & TEX_FILTER_FORCE_WIC) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; if (!metadata.IsVolumemap() || 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)) return E_INVALIDARG; @@ -3410,7 +3421,7 @@ HRESULT DirectX::GenerateMipMaps3D( return hr; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } @@ -3428,7 +3439,7 @@ HRESULT DirectX::ScaleMipMapsAlphaForCoverage( if (metadata.IsVolumemap() || 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) { @@ -3458,7 +3469,7 @@ HRESULT DirectX::ScaleMipMapsAlphaForCoverage( for (size_t h = 0; h < metadata.height; ++h) { size_t msize = std::min(dest->rowPitch, rowPitch); - memcpy_s(pDest, dest->rowPitch, pSrc, msize); + memcpy(pDest, pSrc, msize); pSrc += rowPitch; pDest += dest->rowPitch; } @@ -3482,6 +3493,6 @@ HRESULT DirectX::ScaleMipMapsAlphaForCoverage( if (FAILED(hr)) return hr; } - + return S_OK; } diff --git a/DirectXTex/DirectXTexMisc.cpp b/DirectXTex/DirectXTexMisc.cpp index b779570..fa35b80 100644 --- a/DirectXTex/DirectXTexMisc.cpp +++ b/DirectXTex/DirectXTexMisc.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexMisc.cpp -// +// // DirectX Texture Library - Misc image operations // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,6 +13,11 @@ using namespace DirectX; +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wignored-attributes" +#endif + namespace { const XMVECTORF32 g_Gamma22 = { { { 2.2f, 2.2f, 2.2f, 1.f } } }; @@ -261,7 +266,7 @@ namespace //===================================================================================== // Entry points //===================================================================================== - + //------------------------------------------------------------------------------------- // Copies a rectangle from one image into another //------------------------------------------------------------------------------------- @@ -280,7 +285,7 @@ HRESULT DirectX::CopyRectangle( if (IsCompressed(srcImage.format) || IsCompressed(dstImage.format) || IsPlanar(srcImage.format) || IsPlanar(dstImage.format) || IsPalettized(srcImage.format) || IsPalettized(dstImage.format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; // Validate rectangle/offset 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) { // 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; @@ -322,7 +327,7 @@ HRESULT DirectX::CopyRectangle( if (((pSrc + copyW) > pEndSrc) || (pDest > pEndDest)) return E_FAIL; - memcpy_s(pDest, size_t(pEndDest - pDest), pSrc, copyW); + memcpy(pDest, pSrc, copyW); pSrc += srcImage.rowPitch; pDest += dstImage.rowPitch; @@ -339,7 +344,7 @@ HRESULT DirectX::CopyRectangle( if (dbpp < 8) { // We don't support monochrome (DXGI_FORMAT_R1_UNORM) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } // Round to bytes @@ -374,7 +379,7 @@ HRESULT DirectX::CopyRectangle( return S_OK; } - + //------------------------------------------------------------------------------------- // Computes the Mean-Squared-Error (MSE) between two images //------------------------------------------------------------------------------------- @@ -398,7 +403,7 @@ HRESULT DirectX::ComputeMSE( if (IsPlanar(image1.format) || IsPlanar(image2.format) || IsPalettized(image1.format) || IsPalettized(image2.format) || IsTypeless(image1.format) || IsTypeless(image2.format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; if (IsCompressed(image1.format)) { @@ -478,7 +483,7 @@ HRESULT DirectX::EvaluateImage( return E_INVALIDARG; 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)) { @@ -513,7 +518,7 @@ HRESULT DirectX::EvaluateImage( return E_INVALIDARG; 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 || metadata.height > UINT32_MAX) @@ -607,7 +612,7 @@ HRESULT DirectX::TransformImage( return E_INVALIDARG; 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); if (FAILED(hr)) @@ -626,7 +631,7 @@ HRESULT DirectX::TransformImage( result.Release(); return hr; } - + return S_OK; } @@ -641,7 +646,7 @@ HRESULT DirectX::TransformImage( return E_INVALIDARG; 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 || metadata.height > UINT32_MAX) diff --git a/DirectXTex/DirectXTexNormalMaps.cpp b/DirectXTex/DirectXTexNormalMaps.cpp index f5375e8..0bdb5d5 100644 --- a/DirectXTex/DirectXTexNormalMaps.cpp +++ b/DirectXTex/DirectXTexNormalMaps.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexNormalMaps.cpp -// +// // DirectX Texture Library - Normal map operations // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -84,7 +84,7 @@ namespace return E_FAIL; 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 height = srcImage.height; @@ -124,7 +124,7 @@ namespace if (flags & CNMAP_MIRROR_V) { // Mirror first row - memcpy_s(row0, rowPitch, row1, rowPitch); + memcpy(row0, row1, rowPitch); } else { @@ -248,7 +248,7 @@ namespace //===================================================================================== // Entry points //===================================================================================== - + //------------------------------------------------------------------------------------- // Generates a normal map from a height-map //------------------------------------------------------------------------------------- @@ -282,7 +282,7 @@ HRESULT DirectX::ComputeNormalMap( || IsTypeless(format) || IsTypeless(srcImage.format) || IsPlanar(format) || IsPlanar(srcImage.format) || IsPalettized(format) || IsPalettized(srcImage.format)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; // Setup target image normalMap.Release(); @@ -325,7 +325,7 @@ HRESULT DirectX::ComputeNormalMap( || IsTypeless(format) || IsTypeless(metadata.format) || IsPlanar(format) || IsPlanar(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"); switch (flags & 0xf) @@ -371,7 +371,7 @@ HRESULT DirectX::ComputeNormalMap( if (IsCompressed(src.format) || IsTypeless(src.format)) { 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) diff --git a/DirectXTex/DirectXTexP.h b/DirectXTex/DirectXTexP.h index 3873ee0..63afd68 100644 --- a/DirectXTex/DirectXTexP.h +++ b/DirectXTex/DirectXTexP.h @@ -70,6 +70,7 @@ #pragma clang diagnostic ignored "-Wunknown-pragmas" #endif +#if defined(WIN32) || defined(WINAPI_FAMILY) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -104,10 +105,11 @@ #else #include #endif - -#define _XM_NO_XMVECTOR_OVERLOADS_ - -#include "DirectXTex.h" +#else // !WIN32 +#include +#include +#include +#endif #include #include @@ -117,17 +119,31 @@ #include #include +#ifndef WIN32 +#include +#include +#include +#endif + +#define _XM_NO_XMVECTOR_OVERLOADS_ + #include #if (DIRECTX_MATH_VERSION < 315) #define XM_ALIGNED_DATA(x) __declspec(align(x)) #endif +#include "DirectXTex.h" + #include +#ifdef WIN32 #include #include #include +#else +using WICPixelFormatGUID = GUID; +#endif #include "scoped.h" @@ -147,10 +163,34 @@ #define XBOX_DXGI_FORMAT_R4G4_UNORM DXGI_FORMAT(190) +// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW) +#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast(0x80070216L) + +// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) +#define HRESULT_E_NOT_SUPPORTED static_cast(0x80070032L) + +// HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) +#define HRESULT_E_HANDLE_EOF static_cast(0x80070026L) + +// HRESULT_FROM_WIN32(ERROR_INVALID_DATA) +#define HRESULT_E_INVALID_DATA static_cast(0x8007000DL) + +// HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE) +#define HRESULT_E_FILE_TOO_LARGE static_cast(0x800700DFL) + +// HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE) +#define HRESULT_E_CANNOT_MAKE static_cast(0x80070052L) + +// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) +#ifndef E_NOT_SUFFICIENT_BUFFER +#define E_NOT_SUFFICIENT_BUFFER static_cast(0x8007007AL) +#endif + namespace DirectX { //--------------------------------------------------------------------------------- // WIC helper functions +#ifdef WIN32 DXGI_FORMAT __cdecl _WICToDXGI(_In_ const GUID& guid) noexcept; bool __cdecl _DXGIToWIC(_In_ DXGI_FORMAT format, _Out_ GUID& guid, _In_ bool ignoreRGBvsBGR = false) noexcept; @@ -235,7 +275,7 @@ namespace DirectX return WICBitmapInterpolationModeFant; } } - +#endif // WIN32 //--------------------------------------------------------------------------------- // Image helper functions diff --git a/DirectXTex/DirectXTexPMAlpha.cpp b/DirectXTex/DirectXTexPMAlpha.cpp index 139a4e7..d7272ae 100644 --- a/DirectXTex/DirectXTexPMAlpha.cpp +++ b/DirectXTex/DirectXTexPMAlpha.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexPMAlpha.cpp -// +// // DirectX Texture Library - Premultiplied alpha operations // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -223,7 +223,7 @@ HRESULT DirectX::PremultiplyAlpha( || IsPalettized(srcImage.format) || IsTypeless(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)) return E_INVALIDARG; @@ -276,7 +276,7 @@ HRESULT DirectX::PremultiplyAlpha( || IsPalettized(metadata.format) || IsTypeless(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)) return E_INVALIDARG; diff --git a/DirectXTex/DirectXTexResize.cpp b/DirectXTex/DirectXTexResize.cpp index 71635b8..876dbe2 100644 --- a/DirectXTex/DirectXTexResize.cpp +++ b/DirectXTex/DirectXTexResize.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexResize.cpp -// +// // DirectX Texture Library - Image resizing operations // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -16,14 +16,17 @@ using namespace DirectX; using Microsoft::WRL::ComPtr; +#ifdef WIN32 namespace DirectX { 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; } +#endif namespace { +#ifdef WIN32 //--- Do image resize using WIC --- HRESULT PerformResizeUsingWIC( const Image& srcImage, @@ -58,7 +61,7 @@ namespace if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr source; hr = pWIC->CreateBitmapFromMemory(static_cast(srcImage.width), static_cast(srcImage.height), pfGUID, @@ -238,7 +241,7 @@ namespace return true; } - +#endif // WIN32 //------------------------------------------------------------------------------------- // Resize custom filters @@ -820,7 +823,7 @@ namespace return ResizeTriangleFilter(srcImage, filter, destImage); default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } } } @@ -856,9 +859,10 @@ HRESULT DirectX::Resize( if (IsCompressed(srcImage.format)) { // 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); WICPixelFormatGUID pfGUID = {}; @@ -872,11 +876,12 @@ HRESULT DirectX::Resize( if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) { if (filter & TEX_FILTER_FORCE_WIC) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; usewic = false; } } +#endif // WIN32 HRESULT hr = image.Initialize2D(srcImage.format, width, height, 1, 1); if (FAILED(hr)) @@ -886,6 +891,7 @@ HRESULT DirectX::Resize( if (!rimage) return E_POINTER; +#ifdef WIN32 if (usewic) { if (wicpf) @@ -900,6 +906,7 @@ HRESULT DirectX::Resize( } } else +#endif { // Case 3: not using WIC resizing hr = PerformResizeUsingCustomFilters(srcImage, filter, *rimage); @@ -942,6 +949,7 @@ HRESULT DirectX::Resize( if (FAILED(hr)) return hr; +#ifdef WIN32 bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter); WICPixelFormatGUID pfGUID = {}; @@ -955,11 +963,12 @@ HRESULT DirectX::Resize( if (expandedSize > UINT32_MAX || expandedSize2 > UINT32_MAX) { if (filter & TEX_FILTER_FORCE_WIC) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; usewic = false; } } +#endif switch (metadata.dimension) { @@ -996,6 +1005,7 @@ HRESULT DirectX::Resize( return E_FAIL; } +#ifdef WIN32 if (usewic) { if (wicpf) @@ -1010,6 +1020,7 @@ HRESULT DirectX::Resize( } } else +#endif { // Case 3: not using WIC resizing hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg); @@ -1055,6 +1066,7 @@ HRESULT DirectX::Resize( return E_FAIL; } +#ifdef WIN32 if (usewic) { if (wicpf) @@ -1069,6 +1081,7 @@ HRESULT DirectX::Resize( } } else +#endif { // Case 3: not using WIC resizing hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg); diff --git a/DirectXTex/DirectXTexTGA.cpp b/DirectXTex/DirectXTexTGA.cpp index 650b233..68e1c70 100644 --- a/DirectXTex/DirectXTexTGA.cpp +++ b/DirectXTex/DirectXTexTGA.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexTGA.cpp -// +// // DirectX Texture Library - Targa Truevision (TGA) file format reader/writer // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -148,7 +148,7 @@ namespace if (size < sizeof(TGA_HEADER)) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } auto pHeader = static_cast(pSource); @@ -156,17 +156,17 @@ namespace if (pHeader->bColorMapType != 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)) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } if (!pHeader->wWidth || !pHeader->wHeight) { - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } switch (pHeader->bImageType) @@ -214,7 +214,7 @@ namespace break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } if (convFlags && (pHeader->bImageType == TGA_BLACK_AND_WHITE_RLE)) @@ -226,10 +226,10 @@ namespace case TGA_NO_IMAGE: case TGA_COLOR_MAPPED: case TGA_COLOR_MAPPED_RLE: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; default: - return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + return HRESULT_E_INVALID_DATA; } metadata.width = pHeader->wWidth; @@ -1082,7 +1082,7 @@ namespace if ((image.width > UINT16_MAX) || (image.height > UINT16_MAX)) { - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } header.wWidth = static_cast(image.width); @@ -1127,7 +1127,7 @@ namespace break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } return S_OK; @@ -1223,15 +1223,21 @@ namespace time_t now = {}; time(&now); +#ifdef WIN32 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(info.tm_mon + 1); - ext->wStampDay = static_cast(info.tm_mday); - ext->wStampYear = static_cast(info.tm_year + 1900); - ext->wStampHour = static_cast(info.tm_hour); - ext->wStampMinute = static_cast(info.tm_min); - ext->wStampSecond = static_cast(info.tm_sec); + ext->wStampMonth = static_cast(pinfo->tm_mon + 1); + ext->wStampDay = static_cast(pinfo->tm_mday); + ext->wStampYear = static_cast(pinfo->tm_year + 1900); + ext->wStampHour = static_cast(pinfo->tm_hour); + ext->wStampMinute = static_cast(pinfo->tm_min); + ext->wStampSecond = static_cast(pinfo->tm_sec); } } } @@ -1336,6 +1342,7 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags, if (!szFile) return E_INVALIDARG; +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); #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) 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 - if (fileInfo.EndOfFile.LowPart < (sizeof(TGA_HEADER))) + if (len < (sizeof(TGA_HEADER))) { return E_FAIL; } // Read the standard header (we don't need the file footer to parse the file) uint8_t header[sizeof(TGA_HEADER)] = {}; + +#ifdef WIN32 DWORD bytesRead = 0; if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); } + auto headerLen = static_cast(bytesRead); +#else + inFile.read(reinterpret_cast(header), sizeof(TGA_HEADER)); + if (!inFile) + return E_FAIL; + + size_t headerLen = sizeof(TGA_HEADER); +#endif + size_t offset; - HRESULT hr = DecodeTGAHeader(header, bytesRead, flags, metadata, offset, nullptr); + HRESULT hr = DecodeTGAHeader(header, headerLen, flags, metadata, offset, nullptr); if (FAILED(hr)) return hr; @@ -1383,12 +1421,14 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags, const TGA_EXTENSION* ext = nullptr; TGA_EXTENSION extData = {}; { + TGA_FOOTER footer = {}; + +#ifdef WIN32 if (SetFilePointer(hFile.get(), -static_cast(sizeof(TGA_FOOTER)), nullptr, FILE_END) == INVALID_SET_FILE_POINTER) { return HRESULT_FROM_WIN32(GetLastError()); } - TGA_FOOTER footer = {}; if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -1398,12 +1438,22 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags, { return E_FAIL; } +#else + inFile.seekg(-static_cast(sizeof(TGA_FOOTER)), std::ios::end); + if (!inFile) + return E_FAIL; + + inFile.read(reinterpret_cast(&footer), sizeof(TGA_FOOTER)); + if (!inFile) + return E_FAIL; +#endif if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 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(footer.dwExtensionOffset), 0 } }; 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)); } } +#else // !WIN32 + inFile.seekg(static_cast(footer.dwExtensionOffset), std::ios::beg); + if (inFile) + { + inFile.read(reinterpret_cast(&extData), sizeof(TGA_EXTENSION)); + if (inFile) + { + ext = &extData; + metadata.SetAlphaMode(GetAlphaModeFromExtension(ext)); + } + } +#endif } } } @@ -1531,6 +1593,7 @@ HRESULT DirectX::LoadFromTGAFile( image.Release(); +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); #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) 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 - if (fileInfo.EndOfFile.LowPart < sizeof(TGA_HEADER)) + if (len < sizeof(TGA_HEADER)) { return E_FAIL; } // Read the header uint8_t header[sizeof(TGA_HEADER)] = {}; + +#ifdef WIN32 DWORD bytesRead = 0; if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); } + auto headerLen = static_cast(bytesRead); +#else + inFile.read(reinterpret_cast(header), sizeof(TGA_HEADER)); + if (!inFile) + return E_FAIL; + + size_t headerLen = sizeof(TGA_HEADER); +#endif + size_t offset; uint32_t convFlags = 0; TexMetadata mdata; - HRESULT hr = DecodeTGAHeader(header, bytesRead, flags, mdata, offset, &convFlags); + HRESULT hr = DecodeTGAHeader(header, headerLen, flags, mdata, offset, &convFlags); if (FAILED(hr)) return hr; // Read the pixels - auto remaining = static_cast(fileInfo.EndOfFile.LowPart - offset); + auto remaining = len - offset; if (remaining == 0) return E_FAIL; if (offset > sizeof(TGA_HEADER)) { +#ifdef WIN32 // Skip past the id string LARGE_INTEGER filePos = { { static_cast(offset), 0 } }; if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) { 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); @@ -1605,15 +1705,16 @@ HRESULT DirectX::LoadFromTGAFile( if (remaining < image.GetPixelsSize()) { image.Release(); - return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); + return HRESULT_E_HANDLE_EOF; } if (image.GetPixelsSize() > UINT32_MAX) { image.Release(); - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; } +#ifdef WIN32 if (!ReadFile(hFile.get(), image.GetPixels(), static_cast(image.GetPixelsSize()), &bytesRead, nullptr)) { image.Release(); @@ -1625,6 +1726,14 @@ HRESULT DirectX::LoadFromTGAFile( image.Release(); return E_FAIL; } +#else + inFile.read(reinterpret_cast(image.GetPixels()), image.GetPixelsSize()); + if (!inFile) + { + image.Release(); + return E_FAIL; + } +#endif switch (mdata.format) { @@ -1824,7 +1933,8 @@ HRESULT DirectX::LoadFromTGAFile( return E_OUTOFMEMORY; } - if (!ReadFile(hFile.get(), temp.get(), remaining, &bytesRead, nullptr)) +#ifdef WIN32 + if (!ReadFile(hFile.get(), temp.get(), static_cast(remaining), &bytesRead, nullptr)) { image.Release(); return HRESULT_FROM_WIN32(GetLastError()); @@ -1835,6 +1945,14 @@ HRESULT DirectX::LoadFromTGAFile( image.Release(); return E_FAIL; } +#else + inFile.read(reinterpret_cast(temp.get()), remaining); + if (!inFile) + { + image.Release(); + return E_FAIL; + } +#endif if (convFlags & CONV_FLAGS_RLE) { @@ -1859,12 +1977,14 @@ HRESULT DirectX::LoadFromTGAFile( const TGA_EXTENSION* ext = nullptr; TGA_EXTENSION extData = {}; { + TGA_FOOTER footer = {}; + +#ifdef WIN32 if (SetFilePointer(hFile.get(), -static_cast(sizeof(TGA_FOOTER)), nullptr, FILE_END) == INVALID_SET_FILE_POINTER) { return HRESULT_FROM_WIN32(GetLastError()); } - TGA_FOOTER footer = {}; if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr)) { image.Release(); @@ -1876,12 +1996,28 @@ HRESULT DirectX::LoadFromTGAFile( image.Release(); return E_FAIL; } +#else // !WIN32 + inFile.seekg(-static_cast(sizeof(TGA_FOOTER)), std::ios::end); + if (!inFile) + { + image.Release(); + return E_FAIL; + } + + inFile.read(reinterpret_cast(&footer), sizeof(TGA_FOOTER)); + if (!inFile) + { + image.Release(); + return E_FAIL; + } +#endif if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 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(footer.dwExtensionOffset), 0 } }; if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) { @@ -1891,6 +2027,17 @@ HRESULT DirectX::LoadFromTGAFile( ext = &extData; } } +#else // !WIN32 + inFile.seekg(static_cast(footer.dwExtensionOffset), std::ios::beg); + if (inFile) + { + inFile.read(reinterpret_cast(&extData), sizeof(TGA_EXTENSION)); + if (inFile) + { + ext = &extData; + } + } +#endif } } } @@ -1960,7 +2107,7 @@ HRESULT DirectX::SaveToTGAMemory( assert(destPtr != nullptr); 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); const uint8_t* pPixels = image.pixels; @@ -2033,6 +2180,7 @@ HRESULT DirectX::SaveToTGAFile( return hr; // Create file and write header +#ifdef WIN32 #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr))); #else @@ -2044,6 +2192,11 @@ HRESULT DirectX::SaveToTGAFile( } 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 size_t rowPitch, slicePitch; @@ -2062,6 +2215,7 @@ HRESULT DirectX::SaveToTGAFile( return hr; // Write blob +#ifdef WIN32 const DWORD bytesToWrite = static_cast(blob.GetBufferSize()); DWORD bytesWritten; if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr)) @@ -2073,6 +2227,13 @@ HRESULT DirectX::SaveToTGAFile( { return E_FAIL; } +#else + outFile.write(reinterpret_cast(blob.GetBufferPointer()), + static_cast(blob.GetBufferSize())); + + if (!outFile) + return E_FAIL; +#endif } else { @@ -2082,6 +2243,7 @@ HRESULT DirectX::SaveToTGAFile( return E_OUTOFMEMORY; // Write header +#ifdef WIN32 DWORD bytesWritten; if (!WriteFile(hFile.get(), &tga_header, sizeof(TGA_HEADER), &bytesWritten, nullptr)) { @@ -2090,9 +2252,14 @@ HRESULT DirectX::SaveToTGAFile( if (bytesWritten != sizeof(TGA_HEADER)) return E_FAIL; +#else + outFile.write(reinterpret_cast(&tga_header), sizeof(TGA_HEADER)); + if (!outFile) + return E_FAIL; +#endif if (rowPitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; // Write pixels const uint8_t* pPixels = image.pixels; @@ -2115,6 +2282,7 @@ HRESULT DirectX::SaveToTGAFile( pPixels += image.rowPitch; +#ifdef WIN32 if (!WriteFile(hFile.get(), temp.get(), static_cast(rowPitch), &bytesWritten, nullptr)) { return HRESULT_FROM_WIN32(GetLastError()); @@ -2122,6 +2290,11 @@ HRESULT DirectX::SaveToTGAFile( if (bytesWritten != rowPitch) return E_FAIL; +#else + outFile.write(reinterpret_cast(temp.get()), rowPitch); + if (!outFile) + return E_FAIL; +#endif } uint32_t extOffset = 0; @@ -2131,6 +2304,7 @@ HRESULT DirectX::SaveToTGAFile( TGA_EXTENSION ext = {}; SetExtension(&ext, flags, *metadata); +#ifdef WIN32 extOffset = SetFilePointer(hFile.get(), 0, nullptr, FILE_CURRENT); if (extOffset == INVALID_SET_FILE_POINTER) { @@ -2144,6 +2318,13 @@ HRESULT DirectX::SaveToTGAFile( if (bytesWritten != sizeof(TGA_EXTENSION)) return E_FAIL; +#else + extOffset = static_cast(outFile.tellp()); + + outFile.write(reinterpret_cast(&ext), sizeof(TGA_EXTENSION)); + if (!outFile) + return E_FAIL; +#endif } // Write TGA 2.0 footer @@ -2151,16 +2332,24 @@ HRESULT DirectX::SaveToTGAFile( footer.dwExtensionOffset = extOffset; 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()); } if (bytesWritten != sizeof(footer)) return E_FAIL; +#else + outFile.write(reinterpret_cast(&footer), sizeof(TGA_FOOTER)); + if (!outFile) + return E_FAIL; +#endif } +#ifdef WIN32 delonfail.clear(); +#endif return S_OK; } diff --git a/DirectXTex/DirectXTexUtil.cpp b/DirectXTex/DirectXTexUtil.cpp index 2d6d369..5b8a902 100644 --- a/DirectXTex/DirectXTexUtil.cpp +++ b/DirectXTex/DirectXTexUtil.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // DirectXTexUtil.cpp -// +// // DirectX Texture Library - Utilities // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -32,6 +32,7 @@ using Microsoft::WRL::ComPtr; namespace { +#ifdef WIN32 //------------------------------------------------------------------------------------- // WIC Pixel Format Translation Data //------------------------------------------------------------------------------------- @@ -113,9 +114,20 @@ namespace ifactory)) ? TRUE : FALSE; #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 //===================================================================================== @@ -317,7 +329,7 @@ void DirectX::SetWICFactory(_In_opt_ IWICImagingFactory* pWIC) noexcept if (pWIC) 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) { rowPitch = slicePitch = 0; - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; } #else static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!"); diff --git a/DirectXTex/DirectXTexWIC.cpp b/DirectXTex/DirectXTexWIC.cpp index 06b3990..7774643 100644 --- a/DirectXTex/DirectXTexWIC.cpp +++ b/DirectXTex/DirectXTexWIC.cpp @@ -314,7 +314,7 @@ namespace TEX_ALPHA_MODE alphaMode; metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert, &alphaMode); if (metadata.format == DXGI_FORMAT_UNKNOWN) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; metadata.SetAlphaMode(alphaMode); @@ -437,7 +437,7 @@ namespace return E_NOINTERFACE; 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) { @@ -509,7 +509,7 @@ namespace return E_POINTER; if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr frame; hr = decoder->GetFrame(static_cast(index), frame.GetAddressOf()); @@ -731,7 +731,7 @@ namespace WICPixelFormatGUID pfGuid; if (!_DXGIToWIC(image.format, pfGuid)) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; HRESULT hr = frame->Initialize(props); if (FAILED(hr)) @@ -741,7 +741,7 @@ namespace return E_INVALIDARG; 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(image.width), static_cast(image.height)); if (FAILED(hr)) @@ -919,7 +919,7 @@ namespace return hr; if (!mframe) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; hr = encoder->Initialize(stream, WICBitmapEncoderNoCache); if (FAILED(hr)) @@ -971,7 +971,7 @@ HRESULT DirectX::GetMetadataFromWICMemory( return E_INVALIDARG; if (size > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); + return HRESULT_E_FILE_TOO_LARGE; bool iswic2 = false; auto pWIC = GetWICFactory(iswic2); @@ -1063,7 +1063,7 @@ HRESULT DirectX::LoadFromWICMemory( return E_INVALIDARG; if (size > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); + return HRESULT_E_FILE_TOO_LARGE; bool iswic2 = false; auto pWIC = GetWICFactory(iswic2); @@ -1216,7 +1216,7 @@ HRESULT DirectX::SaveToWICMemory( return hr; 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); if (FAILED(hr)) @@ -1273,7 +1273,7 @@ HRESULT DirectX::SaveToWICMemory( return hr; 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); if (FAILED(hr)) diff --git a/DirectXTex/scoped.h b/DirectXTex/scoped.h index 977c627..31c2fa0 100644 --- a/DirectXTex/scoped.h +++ b/DirectXTex/scoped.h @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------- // scoped.h -// +// // Utility header with helper classes for exception-safe handling of resources // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -14,9 +14,39 @@ #include #include +#ifndef WIN32 +#include + +struct aligned_deleter { void operator()(void* p) noexcept { free(p); } }; + +using ScopedAlignedArrayFloat = std::unique_ptr; + +inline ScopedAlignedArrayFloat make_AlignedArrayFloat(uint64_t count) +{ + uint64_t size = sizeof(float) * count; + size = (size + 15u) & ~0xF; + if (size > static_cast(UINT32_MAX)) + return nullptr; + + auto ptr = aligned_alloc(16, static_cast(size) ); + return ScopedAlignedArrayFloat(static_cast(ptr)); +} + +using ScopedAlignedArrayXMVECTOR = std::unique_ptr; + +inline ScopedAlignedArrayXMVECTOR make_AlignedArrayXMVECTOR(uint64_t count) +{ + uint64_t size = sizeof(DirectX::XMVECTOR) * count; + if (size > static_cast(UINT32_MAX)) + return nullptr; + auto ptr = aligned_alloc(16, static_cast(size)); + return ScopedAlignedArrayXMVECTOR(static_cast(ptr)); +} + +#else // WIN32 +//--------------------------------------------------------------------------------- #include -//--------------------------------------------------------------------------------- struct aligned_deleter { void operator()(void* p) noexcept { _aligned_free(p); } }; using ScopedAlignedArrayFloat = std::unique_ptr; @@ -77,3 +107,5 @@ public: private: HANDLE m_handle; }; + +#endif // WIN32 diff --git a/ScreenGrab/ScreenGrab12.cpp b/ScreenGrab/ScreenGrab12.cpp index 1a4005a..ccb4611 100644 --- a/ScreenGrab/ScreenGrab12.cpp +++ b/ScreenGrab/ScreenGrab12.cpp @@ -29,9 +29,14 @@ #include #include +#ifdef WIN32 #include - #include +#else +#include +#include +#include +#endif #ifdef __clang__ #pragma clang diagnostic ignored "-Wtautological-type-limit-compare" @@ -41,7 +46,11 @@ #endif #define D3DX12_NO_STATE_OBJECT_HELPERS +#ifdef WIN32 #include "d3dx12.h" +#else +#include "directx/d3dx12.h" +#endif using Microsoft::WRL::ComPtr; @@ -54,6 +63,12 @@ using Microsoft::WRL::ComPtr; ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) #endif /* defined(MAKEFOURCC) */ +// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW) +#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast(0x80070216L) + +// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) +#define HRESULT_E_NOT_SUPPORTED static_cast(0x80070032L) + //-------------------------------------------------------------------------------------- // DDS file structure definitions // @@ -85,7 +100,7 @@ namespace #define DDS_ALPHA 0x00000002 // DDPF_ALPHA #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_PITCH 0x00000008 // DDSD_PITCH #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 }; //----------------------------------------------------------------------------- +#ifdef WIN32 struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } }; using ScopedHandle = std::unique_ptr; @@ -257,6 +273,7 @@ namespace const wchar_t* m_filename; ComPtr& m_handle; }; +#endif //-------------------------------------------------------------------------------------- // Return the BPP for a particular format @@ -573,7 +590,7 @@ namespace #if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64) static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!"); if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; #else static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!"); #endif @@ -663,14 +680,14 @@ namespace return E_INVALIDARG; if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; if (srcPitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; UINT numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format); if (numberOfPlanes != 1) - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; D3D12_HEAP_PROPERTIES sourceHeapProperties; D3D12_HEAP_FLAGS sourceHeapFlags; @@ -812,11 +829,18 @@ namespace // Block until the copy is complete while (fence->GetCompletedValue() < 1) + { +#ifdef WIN32 SwitchToThread(); +#else + std::this_thread::yield(); +#endif + } return S_OK; } +#ifdef WIN32 BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID* ifactory) noexcept { return SUCCEEDED(CoCreateInstance( @@ -842,6 +866,7 @@ namespace return factory; } +#endif } // anonymous namespace @@ -884,7 +909,7 @@ HRESULT DirectX::SaveDDSTextureToFile( UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFFu; if (dstRowPitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr pStaging; HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState); @@ -892,11 +917,17 @@ HRESULT DirectX::SaveDDSTextureToFile( return hr; // Create file +#ifdef WIN32 ScopedHandle hFile(safe_handle(CreateFile2(fileName, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr))); if (!hFile) return HRESULT_FROM_WIN32(GetLastError()); 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 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; switch (desc.Format) { - case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy_s(&header->ddspf, sizeof(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_R8G8_UNORM: memcpy_s(&header->ddspf, sizeof(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_R8_UNORM: memcpy_s(&header->ddspf, sizeof(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_R8G8_B8G8_UNORM: memcpy_s(&header->ddspf, sizeof(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_BC1_UNORM: memcpy_s(&header->ddspf, sizeof(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_BC3_UNORM: memcpy_s(&header->ddspf, sizeof(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_SNORM: memcpy_s(&header->ddspf, sizeof(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_SNORM: memcpy_s(&header->ddspf, sizeof(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_B5G5R5A1_UNORM: memcpy_s(&header->ddspf, sizeof(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_R8G8B8A8_SNORM: memcpy_s(&header->ddspf, sizeof(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_B8G8R8A8_UNORM: memcpy_s(&header->ddspf, sizeof(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_YUY2: memcpy_s(&header->ddspf, sizeof(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_R8G8B8A8_UNORM: memcpy(&header->ddspf, &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R16G16_UNORM: memcpy(&header->ddspf, &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8G8_UNORM: memcpy(&header->ddspf, &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R16_UNORM: memcpy(&header->ddspf, &DDSPF_L16, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8_UNORM: memcpy(&header->ddspf, &DDSPF_L8, 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(&header->ddspf, &DDSPF_R8G8_B8G8, 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(&header->ddspf, &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_BC2_UNORM: memcpy(&header->ddspf, &DDSPF_DXT3, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_BC3_UNORM: memcpy(&header->ddspf, &DDSPF_DXT5, 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(&header->ddspf, &DDSPF_BC4_SNORM, 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(&header->ddspf, &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_B5G6R5_UNORM: memcpy(&header->ddspf, &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy(&header->ddspf, &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8G8_SNORM: memcpy(&header->ddspf, &DDSPF_V8U8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R8G8B8A8_SNORM: memcpy(&header->ddspf, &DDSPF_Q8W8V8U8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_R16G16_SNORM: memcpy(&header->ddspf, &DDSPF_V16U16, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy(&header->ddspf, &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy(&header->ddspf, &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT)); break; + case DXGI_FORMAT_YUY2: memcpy(&header->ddspf, &DDSPF_YUY2, 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 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_P8: case DXGI_FORMAT_A8P8: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; 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); extHeader = reinterpret_cast(fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER)); @@ -975,7 +1006,7 @@ HRESULT DirectX::SaveDDSTextureToFile( return hr; if (rowPitch > UINT32_MAX || slicePitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; if (IsCompressed(desc.Format)) { @@ -998,7 +1029,7 @@ HRESULT DirectX::SaveDDSTextureToFile( UINT64 imageSize = dstRowPitch * UINT64(rowCount); if (imageSize > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; void* pMappedMemory = nullptr; D3D12_RANGE readRange = { 0, static_cast(imageSize) }; @@ -1019,7 +1050,7 @@ HRESULT DirectX::SaveDDSTextureToFile( size_t msize = std::min(rowPitch, size_t(dstRowPitch)); for (size_t h = 0; h < rowCount; ++h) { - memcpy_s(dptr, rowPitch, sptr, msize); + memcpy(dptr, sptr, msize); sptr += dstRowPitch; dptr += rowPitch; } @@ -1027,6 +1058,7 @@ HRESULT DirectX::SaveDDSTextureToFile( pStaging->Unmap(0, &writeRange); // Write header & pixels +#ifdef WIN32 DWORD bytesWritten; if (!WriteFile(hFile.get(), fileHeader, static_cast(headerSize), &bytesWritten, nullptr)) return HRESULT_FROM_WIN32(GetLastError()); @@ -1041,11 +1073,23 @@ HRESULT DirectX::SaveDDSTextureToFile( return E_FAIL; delonfail.clear(); +#else + outFile.write(reinterpret_cast(fileHeader), static_cast(headerSize)); + if (!outFile) + return E_FAIL; + + outFile.write(reinterpret_cast(pixels.get()), static_cast(slicePitch)); + if (!outFile) + return E_FAIL; + + outFile.close(); +#endif return S_OK; } //-------------------------------------------------------------------------------------- +#ifdef WIN32 _Use_decl_annotations_ HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ, @@ -1088,7 +1132,7 @@ HRESULT DirectX::SaveWICTextureToFile( UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFFu; if (dstRowPitch > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; ComPtr pStaging; HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState); @@ -1141,7 +1185,7 @@ HRESULT DirectX::SaveWICTextureToFile( break; default: - return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + return HRESULT_E_NOT_SUPPORTED; } auto pWIC = _GetWIC(); @@ -1297,7 +1341,7 @@ HRESULT DirectX::SaveWICTextureToFile( UINT64 imageSize = dstRowPitch * UINT64(desc.Height); if (imageSize > UINT32_MAX) - return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_E_ARITHMETIC_OVERFLOW; void* pMappedMemory = nullptr; D3D12_RANGE readRange = { 0, static_cast(imageSize) }; @@ -1369,3 +1413,4 @@ HRESULT DirectX::SaveWICTextureToFile( return S_OK; } +#endif // WIN32 diff --git a/ScreenGrab/ScreenGrab12.h b/ScreenGrab/ScreenGrab12.h index b44ed1e..9185d85 100644 --- a/ScreenGrab/ScreenGrab12.h +++ b/ScreenGrab/ScreenGrab12.h @@ -17,10 +17,17 @@ #pragma once +#ifdef WIN32 #include #include + #include +#else +#include +#include +#include +#endif namespace DirectX @@ -32,6 +39,7 @@ namespace DirectX D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_RENDER_TARGET) noexcept; +#ifdef WIN32 HRESULT __cdecl SaveWICTextureToFile( _In_ ID3D12CommandQueue* pCommandQ, _In_ ID3D12Resource* pSource, @@ -42,4 +50,5 @@ namespace DirectX _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function setCustomProps = nullptr, bool forceSRGB = false); +#endif }