diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2016-02-20 16:52:36 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-04-18 20:42:20 +0300 |
commit | 8326d59dbb0a7acc4a0dea003ca96cabec6be96f (patch) | |
tree | cce16fa2bed844d419f77e0c8018abe36cd5f150 /source/blender/imbuf/intern | |
parent | 624d010fe50496a4d28e2f61d7cb831dd24f549b (diff) |
OpenEXR: add support for writing EXR files to memory.
Diffstat (limited to 'source/blender/imbuf/intern')
-rw-r--r-- | source/blender/imbuf/intern/openexr/openexr_api.cpp | 132 | ||||
-rw-r--r-- | source/blender/imbuf/intern/png.c | 2 |
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); } |