-
-
Notifications
You must be signed in to change notification settings - Fork 296
Feature/1187 Read EXR files from memory #1448
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
Changes from 5 commits
a9d19fa
ec8dc6c
e38c111
2e0ab33
35e9c9f
5f9ae1a
c4a65f0
6d66a8f
69dc5e8
d15f044
88622bc
4ea8564
a9a6c81
ef76977
82e2b40
767eec2
e513d7a
0f910f8
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 |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
#include <ImfArray.h> | ||
#include <ImfRgbaFile.h> | ||
|
||
#include <cstring> | ||
#include <sstream> | ||
#include <thread> | ||
|
||
|
@@ -38,13 +39,13 @@ | |
this->ComputeInternalFileName(this->DataExtent[4]); | ||
if (this->InternalFileName == nullptr || this->InternalFileName[0] == '\0') | ||
{ | ||
return; | ||
// If we have no file then maybe we have the file in memory | ||
if (!this->MemoryBuffer) | ||
return; | ||
nabielkandiel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
try | ||
auto execute = [&](Imf::RgbaInputFile& file) | ||
{ | ||
Imf::RgbaInputFile file(this->InternalFileName); | ||
|
||
Imath::Box2i dw = file.dataWindow(); | ||
this->DataExtent[0] = dw.min.x; | ||
this->DataExtent[1] = dw.max.x; | ||
|
@@ -56,6 +57,21 @@ | |
{ | ||
throw std::runtime_error("only RGB and RGBA channels are supported"); | ||
} | ||
}; | ||
|
||
try | ||
{ | ||
if (this->MemoryBuffer) | ||
{ | ||
MemStream memoryStream("EXRmemoryStream", this->MemoryBuffer, this->MemoryBufferLength); | ||
Imf::RgbaInputFile file = Imf::RgbaInputFile(memoryStream); | ||
execute(file); | ||
} | ||
else | ||
{ | ||
Imf::RgbaInputFile file(this->InternalFileName); | ||
execute(file); | ||
} | ||
} | ||
catch (const std::exception& e) | ||
{ | ||
|
@@ -112,12 +128,8 @@ | |
scalars->SetName("Pixels"); | ||
float* dataPtr = scalars->GetPointer(0); | ||
|
||
try | ||
auto execute = [&](Imf::RgbaInputFile& file) | ||
{ | ||
assert(this->InternalFileName); | ||
Imf::setGlobalThreadCount(std::thread::hardware_concurrency()); | ||
Imf::RgbaInputFile file(this->InternalFileName); | ||
|
||
Imf::Array2D<Imf::Rgba> pixels(this->GetHeight(), this->GetWidth()); | ||
|
||
file.setFrameBuffer(&pixels[0][0], 1, this->GetWidth()); | ||
|
@@ -134,6 +146,24 @@ | |
dataPtr += 3; | ||
} | ||
} | ||
}; | ||
|
||
try | ||
{ | ||
assert(this->InternalFileName); | ||
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. i think this assert should not be here for the memory stream part. BTW it may be better to make it an actual if test since we now can have an empty InteralFileName, I think. 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. Yes when loading a USD scene the EXRReader will have an empty filename. Interestingly in the test case TestF3DEXRMemReader, If i omit the filename on line 33 I get an error in vtkImageReader2.cxx:111 for not setting a filename. |
||
Imf::setGlobalThreadCount(std::thread::hardware_concurrency()); | ||
|
||
if (this->MemoryBuffer) | ||
{ | ||
MemStream memoryStream("EXRmemoryStream", this->MemoryBuffer, this->MemoryBufferLength); | ||
Imf::RgbaInputFile file = Imf::RgbaInputFile(memoryStream); | ||
execute(file); | ||
} | ||
else | ||
{ | ||
Imf::RgbaInputFile file(this->InternalFileName); | ||
execute(file); | ||
} | ||
} | ||
catch (const std::exception& e) | ||
{ | ||
|
@@ -142,6 +172,24 @@ | |
} | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
/** | ||
* Read from memory instead of file | ||
*/ | ||
void vtkF3DEXRReader::SetMemoryBuffer(const void* buff) | ||
mwestphal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
this->MemoryBuffer = buff; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
/** | ||
* Specify the in memory image buffer length. | ||
*/ | ||
void vtkF3DEXRReader::SetMemoryBufferLength(vtkIdType bufferLen) | ||
{ | ||
this->MemoryBufferLength = bufferLen; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
int vtkF3DEXRReader::GetWidth() const | ||
{ | ||
|
@@ -153,3 +201,15 @@ | |
{ | ||
return this->DataExtent[3] - this->DataExtent[2] + 1; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
bool vtkF3DEXRReader::MemStream::read(char c[], int n) | ||
{ | ||
if (pos + n <= bufflen) | ||
{ | ||
memcpy(c, buffer + pos, n); | ||
pos += n; | ||
return true; | ||
} | ||
return false; | ||
} |
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.
can you put this check in the line above ?