diff options
Diffstat (limited to 'source/blender/imbuf/intern/openexr/openexr_api.cpp')
-rw-r--r-- | source/blender/imbuf/intern/openexr/openexr_api.cpp | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 9b68e0e45eb..fe18984e528 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -1,4 +1,4 @@ -/** +/* * * ***** BEGIN GPLLICENSE BLOCK ***** * @@ -28,6 +28,7 @@ #include <stdlib.h> #include <stdio.h> +#include <stddef.h> #include <string> @@ -93,7 +94,7 @@ class Mem_IStream: public IStream { public: - Mem_IStream (unsigned char *exrbuf, int exrsize): + Mem_IStream (unsigned char *exrbuf, size_t exrsize): IStream("dummy"), _exrpos (0), _exrsize(exrsize) { _exrbuf = exrbuf; } virtual bool read (char c[], int n); @@ -187,7 +188,7 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf) header->insert(info->key, StringAttribute(info->value)); } -static int imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags) +static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags) { int channels = ibuf->channels; int width = ibuf->x; @@ -314,7 +315,7 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags) return (1); } -static int imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags) +static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flags) { int channels = ibuf->channels; int width = ibuf->x; @@ -342,6 +343,7 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags) int ystride = - xstride*width; float *rect[4] = {NULL, NULL, NULL, NULL}; + /* last scanline, stride negative */ rect[0]= ibuf->rect_float + channels*(height-1)*width; rect[1]= rect[0]+1; rect[2]= rect[0]+2; @@ -372,7 +374,7 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags) } -int imb_save_openexr(struct ImBuf *ibuf, char *name, int flags) +int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) { if (flags & IB_mem) { @@ -482,7 +484,7 @@ void IMB_exr_add_channel(void *handle, const char *layname, const char *passname } /* only used for writing temp. render results (not image files) */ -void IMB_exr_begin_write(void *handle, char *filename, int width, int height, int compress) +void IMB_exr_begin_write(void *handle, const char *filename, int width, int height, int compress) { ExrHandle *data= (ExrHandle *)handle; Header header (width, height); @@ -498,12 +500,12 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height, in // openexr_header_metadata(&header, ibuf); // no imbuf. cant write /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */ - header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43 and newer")); + header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.55.1 and newer")); data->ofile = new OutputFile(filename, header); } -void IMB_exrtile_begin_write(void *handle, char *filename, int mipmap, int width, int height, int tilex, int tiley) +void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley) { ExrHandle *data= (ExrHandle *)handle; Header header (width, height); @@ -528,7 +530,7 @@ void IMB_exrtile_begin_write(void *handle, char *filename, int mipmap, int width } /* read from file */ -int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height) +int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *height) { ExrHandle *data= (ExrHandle *)handle; @@ -551,7 +553,7 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height) } /* still clumsy name handling, layers/channels can be ordered as list in list later */ -void IMB_exr_set_channel(void *handle, char *layname, char *passname, int xstride, int ystride, float *rect) +void IMB_exr_set_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect) { ExrHandle *data= (ExrHandle *)handle; ExrChannel *echan; @@ -615,9 +617,13 @@ void IMB_exr_write_channels(void *handle) ExrChannel *echan; if(data->channels.first) { - for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) - frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { + /* last scanline, stride negative */ + float *rect = echan->rect + echan->xstride*(data->height-1)*data->width; + + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)rect, + echan->xstride*sizeof(float), -echan->ystride*sizeof(float))); + } data->ofile->setFrameBuffer (frameBuffer); try { @@ -638,11 +644,20 @@ void IMB_exr_read_channels(void *handle) FrameBuffer frameBuffer; ExrChannel *echan; + /* check if exr was saved with previous versions of blender which flipped images */ + const StringAttribute *ta = data->ifile->header().findTypedAttribute <StringAttribute> ("BlenderMultiChannel"); + short flip = (ta && strncmp(ta->value().c_str(), "Blender V2.43", 13)==0); /* 'previous multilayer attribute, flipped */ + for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) { - /* no datawindow correction needed */ - if(echan->rect) - frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + + if(echan->rect) { + if(flip) + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, + echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + else + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)(echan->rect + echan->xstride*(data->height-1)*data->width), + echan->xstride*sizeof(float), -echan->ystride*sizeof(float))); + } else printf("warning, channel with no rect set %s\n", echan->name); } @@ -943,7 +958,7 @@ static int exr_is_renderresult(InputFile *file) return 0; } -struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags) +struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags) { struct ImBuf *ibuf = NULL; InputFile *file = NULL; @@ -975,7 +990,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags) } else { - ibuf = IMB_allocImBuf(width, height, 32, 0, 0); + ibuf = IMB_allocImBuf(width, height, 32, 0); ibuf->ftype = OPENEXR; /* openEXR is linear as per EXR spec */ |