Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 161 additions & 105 deletions Auxiliary/DirectXTexEXR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,50 @@
using namespace DirectX;
using PackedVector::XMHALF4;

#ifdef _WIN32
namespace
{
class InputStream : public Imf::IStream
{
public:
InputStream(const uint8_t* data, size_t size)
: IStream("InputStream")
, m_DataPtr(data)
, m_DataSize(size)
, m_Position(0)
{}

bool read(char c[], int n) override
{
memcpy(c, m_DataPtr + m_Position, n);
m_Position += n;

return m_Position < m_DataSize;
}

uint64_t tellg() override
{
return m_Position;
}

void seekg(uint64_t pos) override
{
m_Position = pos;

Check warning on line 91 in Auxiliary/DirectXTexEXR.cpp

View workflow job for this annotation

GitHub Actions / build (14, x86-Debug-VCPKG, amd64_x86, OFF)

'=': conversion from 'uint64_t' to 'size_t', possible loss of data
}

#if COMBINED_OPENEXR_VERSION > 30300
int64_t read(void *buf, uint64_t sz, uint64_t offset) override
{
return Imf::IStream::read(buf, sz, offset);
}
#endif

private:
const uint8_t* m_DataPtr;
size_t m_DataSize;
size_t m_Position;
};

#ifdef _WIN32
class com_exception : public std::exception
{
public:
Expand All @@ -82,10 +123,10 @@
HRESULT result;
};

class InputStream : public Imf::IStream
class InputFileStream : public Imf::IStream
{
public:
InputStream(HANDLE hFile, const char fileName[]) :
InputFileStream(HANDLE hFile, const char fileName[]) :
IStream(fileName), m_hFile(hFile)
{
const LARGE_INTEGER dist = {};
Expand All @@ -103,11 +144,11 @@
}
}

InputStream(const InputStream&) = delete;
InputStream& operator = (const InputStream&) = delete;
InputFileStream(const InputFileStream&) = delete;
InputFileStream& operator = (const InputFileStream&) = delete;

InputStream(InputStream&&) = delete;
InputStream& operator=(InputStream&&) = delete;
InputFileStream(InputFileStream&&) = delete;
InputFileStream& operator=(InputFileStream&&) = delete;

bool read(char c[], int n) override
{
Expand Down Expand Up @@ -153,7 +194,7 @@
SetLastError(0);
}

#if COMBINED_OPENEXR_VERSION >= 30300
#if COMBINED_OPENEXR_VERSION > 30300
int64_t read(void *buf, uint64_t sz, uint64_t offset) override
{
return Imf::IStream::read(buf, sz, offset);
Expand All @@ -165,18 +206,18 @@
LONGLONG m_EOF;
};

class OutputStream : public Imf::OStream
class OutputFileStream : public Imf::OStream
{
public:
OutputStream(HANDLE hFile, const char fileName[]) :
OutputFileStream(HANDLE hFile, const char fileName[]) :
OStream(fileName), m_hFile(hFile)
{}

OutputStream(const OutputStream&) = delete;
OutputStream& operator = (const OutputStream&) = delete;
OutputFileStream(const OutputFileStream&) = delete;
OutputFileStream& operator = (const OutputFileStream&) = delete;

OutputStream(OutputStream&&) = delete;
OutputStream& operator=(OutputStream&&) = delete;
OutputFileStream(OutputFileStream&&) = delete;
OutputFileStream& operator=(OutputFileStream&&) = delete;

void write(const char c[], int n) override
{
Expand Down Expand Up @@ -211,9 +252,98 @@
private:
HANDLE m_hFile;
};
}
#endif // _WIN32

//-------------------------------------------------------------------------------------
// Load
//-------------------------------------------------------------------------------------
template <typename StreamType>
HRESULT LoadFromEXRCommon(StreamType stream, _Out_opt_ TexMetadata* metadata, ScratchImage& image)
{
image.Release();

if (metadata)
{
memset(metadata, 0, sizeof(TexMetadata));
}

HRESULT hr = S_OK;

try
{
Imf::RgbaInputFile file(stream);

const auto dw = file.dataWindow();

const int width = dw.max.x - dw.min.x + 1;
int height = dw.max.y - dw.min.y + 1;
size_t arraySize = 1;

if (width < 1 || height < 1)
return E_FAIL;

if (file.header().find("envmap") != file.header().end())
{
if (width == height / 6)
{
height = width;
arraySize = 6;
}
}

if (metadata)
{
metadata->width = static_cast<size_t>(width);
metadata->height = static_cast<size_t>(height);
metadata->depth = metadata->mipLevels = 1;
metadata->arraySize = arraySize;
metadata->format = DXGI_FORMAT_R16G16B16A16_FLOAT;
metadata->dimension = TEX_DIMENSION_TEXTURE2D;
}

hr = image.Initialize2D(DXGI_FORMAT_R16G16B16A16_FLOAT,
static_cast<size_t>(width), static_cast<size_t>(height), arraySize, 1u);

if (FAILED(hr))
return hr;

file.setFrameBuffer(reinterpret_cast<Imf::Rgba*>(image.GetPixels()) - dw.min.x - dw.min.y * width, 1, static_cast<size_t>(width));
file.readPixels(dw.min.y, dw.max.y);
}
#ifdef _WIN32
catch (const com_exception& exc)
{
#ifdef _DEBUG
OutputDebugStringA(exc.what());
#endif
hr = exc.get_result();
}
#endif
#if defined(_WIN32) && defined(_DEBUG)
catch (const std::exception& exc)
{
OutputDebugStringA(exc.what());
hr = E_FAIL;
}
#else
catch (const std::exception&)
{
hr = E_FAIL;
}
#endif
catch (...)
{
hr = E_UNEXPECTED;
}

if (FAILED(hr))
{
image.Release();
}

return hr;
}
}

//=====================================================================================
// Entry-points
Expand Down Expand Up @@ -250,7 +380,7 @@
return HRESULT_FROM_WIN32(GetLastError());
}

InputStream stream(hFile.get(), fileName.c_str());
InputFileStream stream(hFile.get(), fileName.c_str());
#else
std::wstring wFileName(szFile);
std::string fileName(wFileName.cbegin(), wFileName.cend());
Expand Down Expand Up @@ -284,6 +414,7 @@
}
}

metadata = {};
metadata.width = static_cast<size_t>(width);
metadata.height = static_cast<size_t>(height);
metadata.depth = metadata.mipLevels = 1;
Expand Down Expand Up @@ -320,6 +451,17 @@
return hr;
}

//-------------------------------------------------------------------------------------
// Load a EXR file from memory
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::LoadFromEXRMemory(const uint8_t* pSource, size_t size, TexMetadata* metadata, ScratchImage& image)
{
if (!pSource || !size)
return E_INVALIDARG;

return LoadFromEXRCommon(InputStream(pSource, size), metadata, image);
}

//-------------------------------------------------------------------------------------
// Load a EXR file from disk
Expand All @@ -330,13 +472,6 @@
if (!szFile)
return E_INVALIDARG;

image.Release();

if (metadata)
{
memset(metadata, 0, sizeof(TexMetadata));
}

#ifdef _WIN32
std::string fileName;
const int nameLength = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, nullptr, 0, nullptr, nullptr);
Expand All @@ -359,91 +494,12 @@
return HRESULT_FROM_WIN32(GetLastError());
}

InputStream stream(hFile.get(), fileName.c_str());
return LoadFromEXRCommon(InputFileStream(hFile.get(), fileName.c_str()), metadata, image);
#else
std::wstring wFileName(szFile);
std::string fileName(wFileName.cbegin(), wFileName.cend());
return LoadFromEXRCommon(fileName.c_str(), metadata, image);
#endif

HRESULT hr = S_OK;

try
{
#ifdef _WIN32
Imf::RgbaInputFile file(stream);
#else
Imf::RgbaInputFile file(fileName.c_str());
#endif

const auto dw = file.dataWindow();

const int width = dw.max.x - dw.min.x + 1;
int height = dw.max.y - dw.min.y + 1;
size_t arraySize = 1;

if (width < 1 || height < 1)
return E_FAIL;

if (file.header().find("envmap") != file.header().end())
{
if (width == height / 6)
{
height = width;
arraySize = 6;
}
}

if (metadata)
{
metadata->width = static_cast<size_t>(width);
metadata->height = static_cast<size_t>(height);
metadata->depth = metadata->mipLevels = 1;
metadata->arraySize = arraySize;
metadata->format = DXGI_FORMAT_R16G16B16A16_FLOAT;
metadata->dimension = TEX_DIMENSION_TEXTURE2D;
}

hr = image.Initialize2D(DXGI_FORMAT_R16G16B16A16_FLOAT,
static_cast<size_t>(width), static_cast<size_t>(height), arraySize, 1u);

if (FAILED(hr))
return hr;

file.setFrameBuffer(reinterpret_cast<Imf::Rgba*>(image.GetPixels()) - dw.min.x - dw.min.y * width, 1, static_cast<size_t>(width));
file.readPixels(dw.min.y, dw.max.y);
}
#ifdef _WIN32
catch (const com_exception& exc)
{
#ifdef _DEBUG
OutputDebugStringA(exc.what());
#endif
hr = exc.get_result();
}
#endif
#if defined(_WIN32) && defined(_DEBUG)
catch (const std::exception& exc)
{
OutputDebugStringA(exc.what());
hr = E_FAIL;
}
#else
catch (const std::exception&)
{
hr = E_FAIL;
}
#endif
catch (...)
{
hr = E_UNEXPECTED;
}

if (FAILED(hr))
{
image.Release();
}

return hr;
}


Expand Down Expand Up @@ -502,7 +558,7 @@

auto_delete_file delonfail(hFile.get());

OutputStream stream(hFile.get(), fileName.c_str());
OutputFileStream stream(hFile.get(), fileName.c_str());
#else
std::wstring wFileName(szFile);
std::string fileName(wFileName.cbegin(), wFileName.cend());
Expand Down
4 changes: 4 additions & 0 deletions Auxiliary/DirectXTexEXR.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ namespace DirectX
_In_z_ const wchar_t* szFile,
_Out_ TexMetadata& metadata);

DIRECTX_TEX_API HRESULT __cdecl LoadFromEXRMemory(
_In_reads_bytes_(size) const uint8_t* pSource, _In_ size_t size,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image);

DIRECTX_TEX_API HRESULT __cdecl LoadFromEXRFile(
_In_z_ const wchar_t* szFile,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image);
Expand Down
Loading