-
Notifications
You must be signed in to change notification settings - Fork 473
Add support for LoadFromEXRMemory as other formats #645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,9 +61,50 @@ static_assert(sizeof(Imf::Rgba) == 8, "Mismatch size"); | |
| 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; | ||
| } | ||
|
|
||
| #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: | ||
|
|
@@ -82,10 +123,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 = {}; | ||
|
|
@@ -103,11 +144,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 | ||
| { | ||
|
|
@@ -153,7 +194,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); | ||
|
|
@@ -165,18 +206,18 @@ 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 | ||
| { | ||
|
|
@@ -211,9 +252,8 @@ namespace | |
| private: | ||
| HANDLE m_hFile; | ||
| }; | ||
| } | ||
| #endif // _WIN32 | ||
|
|
||
| } | ||
|
|
||
| //===================================================================================== | ||
| // Entry-points | ||
|
|
@@ -250,7 +290,7 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta | |
| 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()); | ||
|
|
@@ -320,60 +360,25 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta | |
| return hr; | ||
| } | ||
|
|
||
|
|
||
| //------------------------------------------------------------------------------------- | ||
| // Load a EXR file from disk | ||
| // Load | ||
| //------------------------------------------------------------------------------------- | ||
| _Use_decl_annotations_ | ||
| HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, ScratchImage& image) | ||
| template <typename StreamType> | ||
| HRESULT LoadFromEXRCommon(StreamType stream, TexMetadata* metadata, ScratchImage& image) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was, however the EXR API expects Instead, exploited the rvalue object stream for Win32. Could modify it with std::move for better visibillity? |
||
| { | ||
| 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); | ||
| 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(); | ||
| } | ||
| } | ||
|
|
||
| ScopedHandle hFile(safe_handle(CreateFile2( | ||
| szFile, | ||
| GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, | ||
| nullptr))); | ||
| if (!hFile) | ||
| { | ||
| return HRESULT_FROM_WIN32(GetLastError()); | ||
| } | ||
|
|
||
| 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(); | ||
|
|
||
|
|
@@ -446,6 +451,57 @@ HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, S | |
| 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 | ||
| //------------------------------------------------------------------------------------- | ||
| _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) | ||
| { | ||
| 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(); | ||
| } | ||
| } | ||
|
|
||
| ScopedHandle hFile(safe_handle(CreateFile2( | ||
| szFile, | ||
| GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, | ||
| nullptr))); | ||
| if (!hFile) | ||
| { | ||
| return HRESULT_FROM_WIN32(GetLastError()); | ||
| } | ||
|
|
||
| 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); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code won't build. You are passing a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is |
||
| #endif | ||
| } | ||
|
|
||
|
|
||
| //------------------------------------------------------------------------------------- | ||
| // Save a EXR file to disk | ||
|
|
@@ -502,7 +558,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()); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This template is not public so it should be placed in an anonymous namespace.
_Use_decl_annotations_is not valid here and instead it needs to be SAL annotated directly. In this case, it's sufficient to make it:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The diff was really bad when it was in the anonymous namespace. Can move it after approval with the removal of
_Use_decl_annotations_