Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2016-02-20 16:52:36 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-04-18 20:42:20 +0300
commit8326d59dbb0a7acc4a0dea003ca96cabec6be96f (patch)
treecce16fa2bed844d419f77e0c8018abe36cd5f150 /source/blender
parent624d010fe50496a4d28e2f61d7cb831dd24f549b (diff)
OpenEXR: add support for writing EXR files to memory.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp132
-rw-r--r--source/blender/imbuf/intern/png.c2
2 files changed, 92 insertions, 42 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 4e801c8e3aa..25e4ae6cf0d 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -116,50 +116,48 @@ static void imb_exr_type_by_channels(ChannelList &channels,
/* Memory Input Stream */
-class Mem_IStream : public Imf::IStream {
+class IMemStream : public Imf::IStream {
public:
- Mem_IStream(unsigned char *exrbuf, size_t exrsize)
- : IStream("dummy"), _exrpos(0), _exrsize(exrsize)
+ IMemStream(unsigned char *exrbuf, size_t exrsize)
+ : IStream("<memory>"), _exrpos(0), _exrsize(exrsize)
{
_exrbuf = exrbuf;
}
- virtual bool read(char c[], int n);
- virtual Int64 tellg();
- virtual void seekg(Int64 pos);
- virtual void clear();
- //virtual ~Mem_IStream() {}; // unused
+ virtual ~IMemStream()
+ {
+ }
- private:
- Int64 _exrpos;
- Int64 _exrsize;
- unsigned char *_exrbuf;
-};
+ virtual bool read(char c[], int n)
+ {
+ if (n + _exrpos <= _exrsize) {
+ memcpy(c, (void *)(&_exrbuf[_exrpos]), n);
+ _exrpos += n;
+ return true;
+ }
+ else
+ return false;
+ }
-bool Mem_IStream::read(char c[], int n)
-{
- if (n + _exrpos <= _exrsize) {
- memcpy(c, (void *)(&_exrbuf[_exrpos]), n);
- _exrpos += n;
- return true;
+ virtual Int64 tellg()
+ {
+ return _exrpos;
}
- else
- return false;
-}
-Int64 Mem_IStream::tellg()
-{
- return _exrpos;
-}
+ virtual void seekg(Int64 pos)
+ {
+ _exrpos = pos;
+ }
-void Mem_IStream::seekg(Int64 pos)
-{
- _exrpos = pos;
-}
+ virtual void clear()
+ {
+ }
-void Mem_IStream::clear()
-{
-}
+ private:
+ Int64 _exrpos;
+ Int64 _exrsize;
+ unsigned char *_exrbuf;
+};
/* File Input Stream */
@@ -222,6 +220,48 @@ class IFileStream : public Imf::IStream {
std::ifstream ifs;
};
+/* Memory Output Stream */
+
+class OMemStream : public OStream {
+ public:
+ OMemStream(ImBuf *ibuf_) : OStream("<memory>"), ibuf(ibuf_), offset(0)
+ {
+ }
+
+ virtual void write(const char c[], int n)
+ {
+ ensure_size(offset + n);
+ memcpy(ibuf->encodedbuffer + offset, c, n);
+ offset += n;
+ ibuf->encodedsize += n;
+ }
+
+ virtual Int64 tellp()
+ {
+ return offset;
+ }
+
+ virtual void seekp(Int64 pos)
+ {
+ offset = pos;
+ ensure_size(offset);
+ }
+
+ private:
+ void ensure_size(Int64 size)
+ {
+ /* if buffer is too small increase it. */
+ while (size > ibuf->encodedbuffersize) {
+ if (!imb_enlargeencodedbufferImBuf(ibuf)) {
+ throw Iex::ErrnoExc("Out of memory.");
+ }
+ }
+ }
+
+ ImBuf *ibuf;
+ Int64 offset;
+};
+
/* File Output Stream */
class OFileStream : public OStream {
@@ -367,6 +407,7 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags
const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */
const int width = ibuf->x;
const int height = ibuf->y;
+ OStream *file_stream = NULL;
try {
Header header(width, height);
@@ -386,8 +427,11 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags
FrameBuffer frameBuffer;
/* manually create ofstream, so we can handle utf-8 filepaths on windows */
- OFileStream file_stream(name);
- OutputFile file(file_stream, header);
+ if (flags & IB_mem)
+ file_stream = new OMemStream(ibuf);
+ else
+ file_stream = new OFileStream(name);
+ OutputFile file(*file_stream, header);
/* we store first everything in half array */
std::vector<RGBAZ> pixels(height * width);
@@ -448,11 +492,13 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags
file.writePixels(height);
}
catch (const std::exception &exc) {
+ delete file_stream;
printf("OpenEXR-save: ERROR: %s\n", exc.what());
return false;
}
+ delete file_stream;
return true;
}
@@ -463,6 +509,7 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flag
const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */
const int width = ibuf->x;
const int height = ibuf->y;
+ OStream *file_stream = NULL;
try {
Header header(width, height);
@@ -482,8 +529,11 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flag
FrameBuffer frameBuffer;
/* manually create ofstream, so we can handle utf-8 filepaths on windows */
- OFileStream file_stream(name);
- OutputFile file(file_stream, header);
+ if (flags & IB_mem)
+ file_stream = new OMemStream(ibuf);
+ else
+ file_stream = new OFileStream(name);
+ OutputFile file(*file_stream, header);
int xstride = sizeof(float) * channels;
int ystride = -xstride * width;
@@ -516,19 +566,19 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flag
}
catch (const std::exception &exc) {
printf("OpenEXR-save: ERROR: %s\n", exc.what());
+ delete file_stream;
return false;
}
+ delete file_stream;
return true;
}
int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags)
{
if (flags & IB_mem) {
- printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n");
imb_addencodedbufferImBuf(ibuf);
ibuf->encodedsize = 0;
- return (0);
}
if (ibuf->foptions.flag & OPENEXR_HALF)
@@ -1792,7 +1842,7 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
char colorspace[IM_MAX_SPACE])
{
struct ImBuf *ibuf = NULL;
- Mem_IStream *membuf = NULL;
+ IMemStream *membuf = NULL;
MultiPartInputFile *file = NULL;
if (imb_is_a_openexr(mem) == 0)
@@ -1803,7 +1853,7 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
try {
bool is_multi;
- membuf = new Mem_IStream((unsigned char *)mem, size);
+ membuf = new IMemStream((unsigned char *)mem, size);
file = new MultiPartInputFile(*membuf);
Box2i dw = file->header(0).dataWindow();
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index bff2ac62fdf..3adc29222e3 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -83,7 +83,7 @@ static void WriteData(png_structp png_ptr, png_bytep data, png_size_t length)
{
ImBuf *ibuf = (ImBuf *)png_get_io_ptr(png_ptr);
- /* if buffer is to small increase it. */
+ /* if buffer is too small increase it. */
while (ibuf->encodedsize + length > ibuf->encodedbuffersize) {
imb_enlargeencodedbufferImBuf(ibuf);
}