1
0
mirror of https://github.com/microsoft/DirectXTex synced 2024-11-21 12:00:06 +00:00

Support for Windows Subsystem for Linux (#208)

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

7
.gitignore vendored
View File

@ -18,7 +18,7 @@
*.VC.db
*.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

View File

@ -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()

View File

@ -20,6 +20,11 @@
#include <cassert>
#include <memory>
#ifndef WIN32
#include <fstream>
#include <filesystem>
#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<HRESULT>(0x80070216L)
// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
#define HRESULT_E_NOT_SUPPORTED static_cast<HRESULT>(0x80070032L)
// HRESULT_FROM_WIN32(ERROR_HANDLE_EOF)
#define HRESULT_E_HANDLE_EOF static_cast<HRESULT>(0x80070026L)
// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
#define HRESULT_E_INVALID_DATA static_cast<HRESULT>(0x8007000DL)
//--------------------------------------------------------------------------------------
// DDS file structure definitions
//
@ -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<void, handle_closer>;
inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
#endif
template<UINT TNameLength>
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<char*>(ddsData.get()), fileLen);
if (!inFile)
{
ddsData.reset();
return E_FAIL;
}
inFile.close();
size_t len = fileLen;
#endif
// DDS files always start with the same magic number ("DDS ")
auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(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<D3D12_RESOURCE_DIMENSION>(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)

View File

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

View File

@ -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<size_t>(sizeInBytes);

View File

@ -17,6 +17,7 @@
#include <utility>
#include <vector>
#if defined(WIN32) || defined(WINAPI_FAMILY)
#if !defined(__d3d11_h__) && !defined(__d3d11_x_h__) && !defined(__d3d12_h__) && !defined(__d3d12_x_h__) && !defined(__XBOX_D3D12_X__)
#ifdef _GAMING_XBOX_SCARLETT
#include <d3d12_xs.h>
@ -28,13 +29,19 @@
#include <d3d11_1.h>
#endif
#endif
#else
#include <directx/dxgiformat.h>
#include <wsl/winadapter.h>
#endif
#include <DirectXMath.h>
#ifdef WIN32
#include <OCIdl.h>
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<void __cdecl(IWICMetadataQueryReader*)> 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<void __cdecl(IPropertyBag2*)> 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

View File

@ -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<size_t>(1, (image.width + 3) / 4) * std::max<size_t>(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();

View File

@ -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<GPUCompressBC> 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;

View File

@ -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<size_t>(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<size_t>(outSize, inSize);
memcpy_s(pDestination, outSize, pSource, size);
memcpy(pDestination, pSource, size);
}
@ -777,7 +777,7 @@ _Use_decl_annotations_ bool DirectX::_LoadScanline(
case DXGI_FORMAT_R32G32B32A32_FLOAT:
{
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<const ConvertData*>(ptr1);
auto p2 = static_cast<const ConvertData*>(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<const ConvertData*>(bsearch_s(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData),
ConvertCompare, nullptr));
auto in = reinterpret_cast<const ConvertData*>(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<const ConvertData*>(
bsearch_s(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare, nullptr));
bsearch(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare));
key.format = outFormat;
auto out = reinterpret_cast<const ConvertData*>(
bsearch_s(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare, nullptr));
bsearch(&key, g_ConvertTable, std::size(g_ConvertTable), sizeof(ConvertData), ConvertCompare));
if (!in || !out)
{
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<IWICBitmap> source;
hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(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;

View File

@ -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<size_t>(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<size_t>(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;

View File

@ -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 <d3dx12_xs.h>
#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)
{

View File

@ -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<int>(TEX_MISC_TEXTURECUBE) == static_cast<int>(DDS_RESOURCE_MISC_TEXTURECUBE), "DDS header mismatch");
@ -343,7 +343,7 @@ namespace
// D3DX writes 1D textures with a fixed Height of 1
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<int>(TEX_MISC2_ALPHA_MODE_MASK) == static_cast<int>(DDS_MISC_FLAGS2_ALPHA_MODE_MASK), "DDS header mismatch");
@ -411,7 +411,7 @@ namespace
{
// We require all six faces to be defined
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<DDS_HEADER_DXT10*>(reinterpret_cast<uint8_t*>(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<const uint8_t*>(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<Image[]> timages(new (std::nothrow) Image[nimages]);
@ -1324,14 +1324,14 @@ namespace
if (IsCompressed(metadata.format))
{
size_t csize = std::min<size_t>(images[index].slicePitch, timages[index].slicePitch);
memcpy_s(pDest, images[index].slicePitch, pSrc, csize);
memcpy(pDest, pSrc, csize);
if (cpFlags & CP_FLAGS_BAD_DXTN_TAILS)
{
if (images[index].width < 4 || images[index].height < 4)
{
csize = std::min<size_t>(images[index].slicePitch, timages[lastgood].slicePitch);
memcpy_s(pDest, images[index].slicePitch, timages[lastgood].pixels, csize);
memcpy(pDest, timages[lastgood].pixels, csize);
}
else
{
@ -1348,7 +1348,7 @@ namespace
size_t csize = std::min<size_t>(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<size_t>(images[index].slicePitch, timages[index].slicePitch);
memcpy_s(pDest, images[index].slicePitch, pSrc, csize);
memcpy(pDest, pSrc, csize);
if (cpFlags & CP_FLAGS_BAD_DXTN_TAILS)
{
if (images[index].width < 4 || images[index].height < 4)
{
csize = std::min<size_t>(images[index].slicePitch, timages[lastgood + slice].slicePitch);
memcpy_s(pDest, images[index].slicePitch, timages[lastgood + slice].pixels, csize);
memcpy(pDest, timages[lastgood + slice].pixels, csize);
}
else if (!slice)
{
@ -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<size_t>(bytesRead);
#else
auto headerLen = std::min<size_t>(len, MAX_HEADER_SIZE);
inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile)
return E_FAIL;
#endif
uint32_t convFlags = 0;
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<size_t>(bytesRead);
#else
auto headerLen = std::min<size_t>(len, MAX_HEADER_SIZE);
inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile)
return E_FAIL;
#endif
uint32_t convFlags = 0;
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<char*>(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<DWORD>(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<char*>(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<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
{
image.Release();
return HRESULT_FROM_WIN32(GetLastError());
}
#else
inFile.read(reinterpret_cast<char*>(image.GetPixels()), image.GetPixelsSize());
if (!inFile)
{
image.Release();
return E_FAIL;
}
#endif
if (convFlags & (CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA))
{
@ -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<char*>(header), static_cast<std::streamsize>(required));
if (!outFile)
return E_FAIL;
#endif
// Write images
switch (static_cast<DDS_RESOURCE_DIMENSION>(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<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2192,6 +2276,11 @@ HRESULT DirectX::SaveToDDSFile(
{
return E_FAIL;
}
#else
outFile.write(reinterpret_cast<char*>(images[index].pixels), static_cast<std::streamsize>(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<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2219,6 +2309,11 @@ HRESULT DirectX::SaveToDDSFile(
{
return E_FAIL;
}
#else
outFile.write(reinterpret_cast<const char*>(sPtr), static_cast<std::streamsize>(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<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2265,6 +2361,11 @@ HRESULT DirectX::SaveToDDSFile(
{
return E_FAIL;
}
#else
outFile.write(reinterpret_cast<char*>(images[index].pixels), static_cast<std::streamsize>(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<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2292,7 +2394,11 @@ HRESULT DirectX::SaveToDDSFile(
{
return E_FAIL;
}
#else
outFile.write(reinterpret_cast<const char*>(sPtr), static_cast<std::streamsize>(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;
}

View File

@ -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<IWICBitmap> source;
HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(srcImage.height), pfGUID,
@ -63,7 +63,7 @@ namespace
if (memcmp(&pfFR, &pfGUID, sizeof(GUID)) != 0)
{
// 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<int>(TEX_FR_ROTATE0) == static_cast<int>(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC");
@ -292,7 +292,7 @@ HRESULT DirectX::FlipRotate(
if (IsCompressed(metadata.format))
{
// We don't support flip/rotate operations on compressed images
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
return HRESULT_E_NOT_SUPPORTED;
}
static_assert(static_cast<int>(TEX_FR_ROTATE0) == static_cast<int>(WICBitmapTransformRotate0), "TEX_FR_ROTATE0 no longer matches WIC");

View File

@ -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 <cstdarg>
#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<size_t sizeOfBuffer>
inline int sprintf_s(char (&buffer)[sizeOfBuffer], const char* format, ...)
{
// This is adapter code. It is not a full implementation of sprintf_s!
va_list ap;
va_start(ap, format);
int result = vsprintf(buffer, format, ap);
va_end(ap);
return result;
}
#endif
//-------------------------------------------------------------------------------------
// Decodes HDR header
//-------------------------------------------------------------------------------------
@ -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<unsigned long>(((orientation[0] == '+' || orientation[0] == '-') && (orientation[1] == 'X' || orientation[1] == 'Y'))
? ERROR_NOT_SUPPORTED : ERROR_INVALID_DATA)
);
return (static_cast<unsigned long>(((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<DWORD>(sizeof(header), fileInfo.EndOfFile.LowPart), &bytesRead, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
}
auto headerLen = static_cast<size_t>(bytesRead);
#else
auto headerLen = std::min<size_t>(sizeof(header), len);
inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile)
return E_FAIL;
#endif
size_t offset;
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<float*>(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<uint8_t[]> temp(new (std::nothrow) uint8_t[fileInfo.EndOfFile.LowPart]);
std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[len]);
if (!temp)
{
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<char*>(temp.get()), len);
if (!inFile)
return E_FAIL;
#endif
return LoadFromHDRMemory(temp.get(), fileInfo.EndOfFile.LowPart, metadata, image);
return LoadFromHDRMemory(temp.get(), len, metadata, image);
}
@ -917,7 +994,7 @@ HRESULT DirectX::SaveToHDRMemory(const Image& image, Blob& blob) noexcept
{
// Images larger than this can't be RLE encoded. They are technically allowed as
// 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<uint8_t*>(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<size_t>(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<const DWORD>(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<char*>(blob.GetBufferPointer()),
static_cast<std::streamsize>(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<DWORD>(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<char*>(header), static_cast<std::streamsize>(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<const float*>(sPtr), image.width, fpp);
sPtr += image.rowPitch;
#ifdef WIN32
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(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<char*>(rgbe), static_cast<std::streamsize>(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<DWORD>(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<char*>(enc), static_cast<std::streamsize>(encSize));
if (!outFile)
return E_FAIL;
#endif
}
else
{
#ifdef WIN32
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(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<char*>(rgbe), static_cast<std::streamsize>(rowPitch));
if (!outFile)
return E_FAIL;
#endif
}
}
#endif
}
#ifdef WIN32
delonfail.clear();
#endif
return S_OK;
}

View File

@ -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;
}

View File

@ -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<IWICBitmap> 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<IWICBitmap> source;
HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(width), static_cast<UINT>(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<UINT>(width), static_cast<UINT>(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<size_t>(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<size_t>(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<size_t>(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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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 <d3d11_1.h>
#endif
#define _XM_NO_XMVECTOR_OVERLOADS_
#include "DirectXTex.h"
#else // !WIN32
#include <wsl/winadapter.h>
#include <wsl/wrladapter.h>
#include <directx/d3d12.h>
#endif
#include <algorithm>
#include <cassert>
@ -117,17 +119,31 @@
#include <iterator>
#include <memory>
#ifndef WIN32
#include <fstream>
#include <filesystem>
#include <thread>
#endif
#define _XM_NO_XMVECTOR_OVERLOADS_
#include <DirectXPackedVector.h>
#if (DIRECTX_MATH_VERSION < 315)
#define XM_ALIGNED_DATA(x) __declspec(align(x))
#endif
#include "DirectXTex.h"
#include <malloc.h>
#ifdef WIN32
#include <Ole2.h>
#include <wincodec.h>
#include <wrl\client.h>
#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<HRESULT>(0x80070216L)
// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
#define HRESULT_E_NOT_SUPPORTED static_cast<HRESULT>(0x80070032L)
// HRESULT_FROM_WIN32(ERROR_HANDLE_EOF)
#define HRESULT_E_HANDLE_EOF static_cast<HRESULT>(0x80070026L)
// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
#define HRESULT_E_INVALID_DATA static_cast<HRESULT>(0x8007000DL)
// HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE)
#define HRESULT_E_FILE_TOO_LARGE static_cast<HRESULT>(0x800700DFL)
// HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE)
#define HRESULT_E_CANNOT_MAKE static_cast<HRESULT>(0x80070052L)
// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)
#ifndef E_NOT_SUFFICIENT_BUFFER
#define E_NOT_SUFFICIENT_BUFFER static_cast<HRESULT>(0x8007007AL)
#endif
namespace DirectX
{
//---------------------------------------------------------------------------------
// 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

View File

@ -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;

View File

@ -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<IWICBitmap> source;
hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(srcImage.width), static_cast<UINT>(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);

View File

@ -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<const TGA_HEADER*>(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<uint16_t>(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<uint16_t>(info.tm_mon + 1);
ext->wStampDay = static_cast<uint16_t>(info.tm_mday);
ext->wStampYear = static_cast<uint16_t>(info.tm_year + 1900);
ext->wStampHour = static_cast<uint16_t>(info.tm_hour);
ext->wStampMinute = static_cast<uint16_t>(info.tm_min);
ext->wStampSecond = static_cast<uint16_t>(info.tm_sec);
ext->wStampMonth = static_cast<uint16_t>(pinfo->tm_mon + 1);
ext->wStampDay = static_cast<uint16_t>(pinfo->tm_mday);
ext->wStampYear = static_cast<uint16_t>(pinfo->tm_year + 1900);
ext->wStampHour = static_cast<uint16_t>(pinfo->tm_hour);
ext->wStampMinute = static_cast<uint16_t>(pinfo->tm_min);
ext->wStampSecond = static_cast<uint16_t>(pinfo->tm_sec);
}
}
}
@ -1336,6 +1342,7 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
if (!szFile)
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<size_t>(bytesRead);
#else
inFile.read(reinterpret_cast<char*>(header), sizeof(TGA_HEADER));
if (!inFile)
return E_FAIL;
size_t headerLen = sizeof(TGA_HEADER);
#endif
size_t offset;
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<int>(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<int>(sizeof(TGA_FOOTER)), std::ios::end);
if (!inFile)
return E_FAIL;
inFile.read(reinterpret_cast<char*>(&footer), sizeof(TGA_FOOTER));
if (!inFile)
return E_FAIL;
#endif
if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 0)
{
if (footer.dwExtensionOffset != 0
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= fileInfo.EndOfFile.LowPart))
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= len))
{
#ifdef WIN32
LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } };
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<std::streampos>(footer.dwExtensionOffset), std::ios::beg);
if (inFile)
{
inFile.read(reinterpret_cast<char*>(&extData), sizeof(TGA_EXTENSION));
if (inFile)
{
ext = &extData;
metadata.SetAlphaMode(GetAlphaModeFromExtension(ext));
}
}
#endif
}
}
}
@ -1531,6 +1593,7 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release();
#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<size_t>(bytesRead);
#else
inFile.read(reinterpret_cast<char*>(header), sizeof(TGA_HEADER));
if (!inFile)
return E_FAIL;
size_t headerLen = sizeof(TGA_HEADER);
#endif
size_t offset;
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<DWORD>(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<DWORD>(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<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
{
image.Release();
@ -1625,6 +1726,14 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release();
return E_FAIL;
}
#else
inFile.read(reinterpret_cast<char*>(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<DWORD>(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<char*>(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<int>(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<int>(sizeof(TGA_FOOTER)), std::ios::end);
if (!inFile)
{
image.Release();
return E_FAIL;
}
inFile.read(reinterpret_cast<char*>(&footer), sizeof(TGA_FOOTER));
if (!inFile)
{
image.Release();
return E_FAIL;
}
#endif
if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 0)
{
if (footer.dwExtensionOffset != 0
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= fileInfo.EndOfFile.LowPart))
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= len))
{
#ifdef WIN32
LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } };
if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{
@ -1891,6 +2027,17 @@ HRESULT DirectX::LoadFromTGAFile(
ext = &extData;
}
}
#else // !WIN32
inFile.seekg(static_cast<std::streampos>(footer.dwExtensionOffset), std::ios::beg);
if (inFile)
{
inFile.read(reinterpret_cast<char*>(&extData), sizeof(TGA_EXTENSION));
if (inFile)
{
ext = &extData;
}
}
#endif
}
}
}
@ -1960,7 +2107,7 @@ HRESULT DirectX::SaveToTGAMemory(
assert(destPtr != nullptr);
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<DWORD>(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<char*>(blob.GetBufferPointer()),
static_cast<std::streamsize>(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<char*>(&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<DWORD>(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<char*>(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<uint32_t>(outFile.tellp());
outFile.write(reinterpret_cast<char*>(&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<char*>(&footer), sizeof(TGA_FOOTER));
if (!outFile)
return E_FAIL;
#endif
}
#ifdef WIN32
delonfail.clear();
#endif
return S_OK;
}

View File

@ -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!");

View File

@ -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<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame(static_cast<UINT>(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<UINT>(image.width), static_cast<UINT>(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))

View File

@ -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 <cstdint>
#include <memory>
#ifndef WIN32
#include <cstdlib>
struct aligned_deleter { void operator()(void* p) noexcept { free(p); } };
using ScopedAlignedArrayFloat = std::unique_ptr<float[], aligned_deleter>;
inline ScopedAlignedArrayFloat make_AlignedArrayFloat(uint64_t count)
{
uint64_t size = sizeof(float) * count;
size = (size + 15u) & ~0xF;
if (size > static_cast<uint64_t>(UINT32_MAX))
return nullptr;
auto ptr = aligned_alloc(16, static_cast<size_t>(size) );
return ScopedAlignedArrayFloat(static_cast<float*>(ptr));
}
using ScopedAlignedArrayXMVECTOR = std::unique_ptr<DirectX::XMVECTOR[], aligned_deleter>;
inline ScopedAlignedArrayXMVECTOR make_AlignedArrayXMVECTOR(uint64_t count)
{
uint64_t size = sizeof(DirectX::XMVECTOR) * count;
if (size > static_cast<uint64_t>(UINT32_MAX))
return nullptr;
auto ptr = aligned_alloc(16, static_cast<size_t>(size));
return ScopedAlignedArrayXMVECTOR(static_cast<DirectX::XMVECTOR*>(ptr));
}
#else // WIN32
//---------------------------------------------------------------------------------
#include <malloc.h>
//---------------------------------------------------------------------------------
struct aligned_deleter { void operator()(void* p) noexcept { _aligned_free(p); } };
using ScopedAlignedArrayFloat = std::unique_ptr<float[], aligned_deleter>;
@ -77,3 +107,5 @@ public:
private:
HANDLE m_handle;
};
#endif // WIN32

View File

@ -29,9 +29,14 @@
#include <cstring>
#include <memory>
#ifdef WIN32
#include <wincodec.h>
#include <wrl\client.h>
#else
#include <fstream>
#include <filesystem>
#include <thread>
#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<HRESULT>(0x80070216L)
// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
#define HRESULT_E_NOT_SUPPORTED static_cast<HRESULT>(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<void, handle_closer>;
@ -257,6 +273,7 @@ namespace
const wchar_t* m_filename;
ComPtr<IWICStream>& 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<ID3D12Resource> 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<DDS_HEADER_DXT10*>(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<SIZE_T>(imageSize) };
@ -1019,7 +1050,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
size_t msize = std::min<size_t>(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<DWORD>(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<char*>(fileHeader), static_cast<std::streamsize>(headerSize));
if (!outFile)
return E_FAIL;
outFile.write(reinterpret_cast<char*>(pixels.get()), static_cast<std::streamsize>(slicePitch));
if (!outFile)
return E_FAIL;
outFile.close();
#endif
return S_OK;
}
//--------------------------------------------------------------------------------------
#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<ID3D12Resource> 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<SIZE_T>(imageSize) };
@ -1369,3 +1413,4 @@ HRESULT DirectX::SaveWICTextureToFile(
return S_OK;
}
#endif // WIN32

View File

@ -17,10 +17,17 @@
#pragma once
#ifdef WIN32
#include <d3d12.h>
#include <OCIdl.h>
#include <functional>
#else
#include <wsl/winadapter.h>
#include <wsl/wrladapter.h>
#include <directx/d3d12.h>
#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<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr,
bool forceSRGB = false);
#endif
}