Skip to content
Open
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
246 changes: 155 additions & 91 deletions Auxiliary/DirectXTexEXR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ namespace
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 +103,11 @@ namespace
}
}

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 +153,7 @@ namespace
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,17 +165,17 @@ namespace
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 @@ -210,60 +210,70 @@ namespace
private:
HANDLE m_hFile;
};
}
#endif // _WIN32


//=====================================================================================
// Entry-points
//=====================================================================================
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;
}

#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;
};
}
#endif // _WIN32

//-------------------------------------------------------------------------------------
// Obtain metadata from EXR file on disk
// Load
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& metadata)
template <typename StreamType>
HRESULT LoadFromEXRCommon(StreamType& stream, TexMetadata* metadata, ScratchImage& image)
{
if (!szFile)
return E_INVALIDARG;

#ifdef _WIN32
std::string fileName;
const int nameLength = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, nullptr, 0, nullptr, nullptr);
if (nameLength > 0)
{
fileName.resize(static_cast<size_t>(nameLength));
const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName.data(), nameLength, nullptr, nullptr);
if (result <= 0)
{
fileName.clear();
}
}
image.Release();

ScopedHandle hFile(safe_handle(CreateFile2(
szFile,
GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING,
nullptr)));
if (!hFile)
if (metadata)
{
return HRESULT_FROM_WIN32(GetLastError());
memset(metadata, 0, sizeof(TexMetadata));
}

InputStream stream(hFile.get(), fileName.c_str());
#else
std::wstring wFileName(szFile);
std::string fileName(wFileName.cbegin(), wFileName.cend());
#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();

Expand All @@ -283,19 +293,31 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta
}
}

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;
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
#ifdef _DEBUG
OutputDebugStringA(exc.what());
#endif
#endif
hr = exc.get_result();
}
#endif
Expand All @@ -316,26 +338,27 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta
hr = E_UNEXPECTED;
}

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

return hr;
}

//=====================================================================================
// Entry-points
//=====================================================================================

//-------------------------------------------------------------------------------------
// Load a EXR file from disk
// Obtain metadata from EXR file on disk
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, ScratchImage& image)
HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& metadata)
{
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 @@ -358,7 +381,7 @@ HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, S
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 @@ -392,24 +415,12 @@ HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, S
}
}

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);
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;
}
#ifdef _WIN32
catch (const com_exception& exc)
Expand Down Expand Up @@ -437,12 +448,65 @@ HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, S
hr = E_UNEXPECTED;
}

if (FAILED(hr))
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;

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

//-------------------------------------------------------------------------------------
// Load a EXR file from disk
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, ScratchImage& image)
{
if (!szFile)
return E_INVALIDARG;

#ifdef _WIN32
std::string fileName;
const int nameLength = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, nullptr, 0, nullptr, nullptr);
if (nameLength > 0)
{
image.Release();
fileName.resize(static_cast<size_t>(nameLength));
const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName.data(), nameLength, nullptr, nullptr);
if (result <= 0)
{
fileName.clear();
}
}

return hr;
ScopedHandle hFile(safe_handle(CreateFile2(
szFile,
GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING,
nullptr)));
if (!hFile)
{
return HRESULT_FROM_WIN32(GetLastError());
}

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

#ifdef _WIN32
return LoadFromEXRCommon(stream, metadata, image);
#else
return LoadFromEXRCommon(fileName.c_str(), metadata, image);
#endif
}


Expand Down Expand Up @@ -503,7 +567,7 @@ HRESULT DirectX::SaveToEXRFile(const Image& image, const wchar_t* szFile)

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