@@ -61,9 +61,50 @@ static_assert(sizeof(Imf::Rgba) == 8, "Mismatch size");
6161using namespace DirectX ;
6262using PackedVector::XMHALF4;
6363
64- #ifdef _WIN32
6564namespace
6665{
66+ class InputStream : public Imf ::IStream
67+ {
68+ public:
69+ InputStream (const uint8_t * data, size_t size)
70+ : IStream(" InputStream" )
71+ , m_DataPtr(data)
72+ , m_DataSize(size)
73+ , m_Position(0 )
74+ {}
75+
76+ bool read (char c[], int n) override
77+ {
78+ memcpy (c, m_DataPtr + m_Position, n);
79+ m_Position += n;
80+
81+ return m_Position < m_DataSize;
82+ }
83+
84+ uint64_t tellg () override
85+ {
86+ return m_Position;
87+ }
88+
89+ void seekg (uint64_t pos) override
90+ {
91+ m_Position = pos;
92+ }
93+
94+ #if COMBINED_OPENEXR_VERSION > 30300
95+ int64_t read (void *buf, uint64_t sz, uint64_t offset) override
96+ {
97+ return Imf::IStream::read (buf, sz, offset);
98+ }
99+ #endif
100+
101+ private:
102+ const uint8_t * m_DataPtr;
103+ size_t m_DataSize;
104+ size_t m_Position;
105+ };
106+
107+ #ifdef _WIN32
67108 class com_exception : public std ::exception
68109 {
69110 public:
@@ -82,10 +123,10 @@ namespace
82123 HRESULT result;
83124 };
84125
85- class InputStream : public Imf ::IStream
126+ class InputFileStream : public Imf ::IStream
86127 {
87128 public:
88- InputStream (HANDLE hFile, const char fileName[]) :
129+ InputFileStream (HANDLE hFile, const char fileName[]) :
89130 IStream (fileName), m_hFile(hFile)
90131 {
91132 const LARGE_INTEGER dist = {};
@@ -103,11 +144,11 @@ namespace
103144 }
104145 }
105146
106- InputStream (const InputStream &) = delete ;
107- InputStream & operator = (const InputStream &) = delete ;
147+ InputFileStream (const InputFileStream &) = delete ;
148+ InputFileStream & operator = (const InputFileStream &) = delete ;
108149
109- InputStream (InputStream &&) = delete ;
110- InputStream & operator =(InputStream &&) = delete ;
150+ InputFileStream (InputFileStream &&) = delete ;
151+ InputFileStream & operator =(InputFileStream &&) = delete ;
111152
112153 bool read (char c[], int n) override
113154 {
@@ -153,7 +194,7 @@ namespace
153194 SetLastError (0 );
154195 }
155196
156- #if COMBINED_OPENEXR_VERSION >= 30300
197+ #if COMBINED_OPENEXR_VERSION > 30300
157198 int64_t read (void *buf, uint64_t sz, uint64_t offset) override
158199 {
159200 return Imf::IStream::read (buf, sz, offset);
@@ -165,18 +206,18 @@ namespace
165206 LONGLONG m_EOF;
166207 };
167208
168- class OutputStream : public Imf ::OStream
209+ class OutputFileStream : public Imf ::OStream
169210 {
170211 public:
171- OutputStream (HANDLE hFile, const char fileName[]) :
212+ OutputFileStream (HANDLE hFile, const char fileName[]) :
172213 OStream (fileName), m_hFile(hFile)
173214 {}
174215
175- OutputStream (const OutputStream &) = delete ;
176- OutputStream & operator = (const OutputStream &) = delete ;
216+ OutputFileStream (const OutputFileStream &) = delete ;
217+ OutputFileStream & operator = (const OutputFileStream &) = delete ;
177218
178- OutputStream (OutputStream &&) = delete ;
179- OutputStream & operator =(OutputStream &&) = delete ;
219+ OutputFileStream (OutputFileStream &&) = delete ;
220+ OutputFileStream & operator =(OutputFileStream &&) = delete ;
180221
181222 void write (const char c[], int n) override
182223 {
@@ -211,9 +252,8 @@ namespace
211252 private:
212253 HANDLE m_hFile;
213254 };
214- }
215255#endif // _WIN32
216-
256+ }
217257
218258// =====================================================================================
219259// Entry-points
@@ -250,7 +290,7 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta
250290 return HRESULT_FROM_WIN32 (GetLastError ());
251291 }
252292
253- InputStream stream (hFile.get (), fileName.c_str ());
293+ InputFileStream stream (hFile.get (), fileName.c_str ());
254294#else
255295 std::wstring wFileName (szFile);
256296 std::string fileName (wFileName.cbegin (), wFileName.cend ());
@@ -320,60 +360,25 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta
320360 return hr;
321361}
322362
323-
324363// -------------------------------------------------------------------------------------
325- // Load a EXR file from disk
364+ // Load
326365// -------------------------------------------------------------------------------------
327366_Use_decl_annotations_
328- HRESULT DirectX::LoadFromEXRFile (const wchar_t * szFile, TexMetadata* metadata, ScratchImage& image)
367+ template <typename StreamType>
368+ HRESULT LoadFromEXRCommon (StreamType& stream, TexMetadata* metadata, ScratchImage& image)
329369{
330- if (!szFile)
331- return E_INVALIDARG;
332-
333370 image.Release ();
334371
335372 if (metadata)
336373 {
337374 memset (metadata, 0 , sizeof (TexMetadata));
338375 }
339376
340- #ifdef _WIN32
341- std::string fileName;
342- const int nameLength = WideCharToMultiByte (CP_UTF8, 0 , szFile, -1 , nullptr , 0 , nullptr , nullptr );
343- if (nameLength > 0 )
344- {
345- fileName.resize (static_cast <size_t >(nameLength));
346- const int result = WideCharToMultiByte (CP_UTF8, 0 , szFile, -1 , fileName.data (), nameLength, nullptr , nullptr );
347- if (result <= 0 )
348- {
349- fileName.clear ();
350- }
351- }
352-
353- ScopedHandle hFile (safe_handle (CreateFile2 (
354- szFile,
355- GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING,
356- nullptr )));
357- if (!hFile)
358- {
359- return HRESULT_FROM_WIN32 (GetLastError ());
360- }
361-
362- InputStream stream (hFile.get (), fileName.c_str ());
363- #else
364- std::wstring wFileName (szFile);
365- std::string fileName (wFileName.cbegin (), wFileName.cend ());
366- #endif
367-
368377 HRESULT hr = S_OK;
369378
370379 try
371380 {
372- #ifdef _WIN32
373381 Imf::RgbaInputFile file (stream);
374- #else
375- Imf::RgbaInputFile file (fileName.c_str ());
376- #endif
377382
378383 const auto dw = file.dataWindow ();
379384
@@ -446,6 +451,59 @@ HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, S
446451 return hr;
447452}
448453
454+ // -------------------------------------------------------------------------------------
455+ // Load a EXR file from memory
456+ // -------------------------------------------------------------------------------------
457+ _Use_decl_annotations_
458+ HRESULT DirectX::LoadFromEXRMemory (const uint8_t * pSource, size_t size, TexMetadata* metadata, ScratchImage& image)
459+ {
460+ if (!pSource || !size)
461+ return E_INVALIDARG;
462+
463+ InputStream stream (pSource, size);
464+ return LoadFromEXRCommon (stream, metadata, image);
465+ }
466+
467+ // -------------------------------------------------------------------------------------
468+ // Load a EXR file from disk
469+ // -------------------------------------------------------------------------------------
470+ _Use_decl_annotations_
471+ HRESULT DirectX::LoadFromEXRFile (const wchar_t * szFile, TexMetadata* metadata, ScratchImage& image)
472+ {
473+ if (!szFile)
474+ return E_INVALIDARG;
475+
476+ #ifdef _WIN32
477+ std::string fileName;
478+ const int nameLength = WideCharToMultiByte (CP_UTF8, 0 , szFile, -1 , nullptr , 0 , nullptr , nullptr );
479+ if (nameLength > 0 )
480+ {
481+ fileName.resize (static_cast <size_t >(nameLength));
482+ const int result = WideCharToMultiByte (CP_UTF8, 0 , szFile, -1 , fileName.data (), nameLength, nullptr , nullptr );
483+ if (result <= 0 )
484+ {
485+ fileName.clear ();
486+ }
487+ }
488+
489+ ScopedHandle hFile (safe_handle (CreateFile2 (
490+ szFile,
491+ GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING,
492+ nullptr )));
493+ if (!hFile)
494+ {
495+ return HRESULT_FROM_WIN32 (GetLastError ());
496+ }
497+
498+ InputFileStream stream (hFile.get (), fileName.c_str ());
499+ return LoadFromEXRCommon (stream, metadata, image);
500+ #else
501+ std::wstring wFileName (szFile);
502+ std::string fileName (wFileName.cbegin (), wFileName.cend ());
503+ return LoadFromEXRCommon (fileName.c_str (), metadata, image);
504+ #endif
505+ }
506+
449507
450508// -------------------------------------------------------------------------------------
451509// Save a EXR file to disk
@@ -502,7 +560,7 @@ HRESULT DirectX::SaveToEXRFile(const Image& image, const wchar_t* szFile)
502560
503561 auto_delete_file delonfail (hFile.get ());
504562
505- OutputStream stream (hFile.get (), fileName.c_str ());
563+ OutputFileStream stream (hFile.get (), fileName.c_str ());
506564#else
507565 std::wstring wFileName (szFile);
508566 std::string fileName (wFileName.cbegin (), wFileName.cend ());
0 commit comments