diff options
author | Ton Roosendaal <ton@blender.org> | 2010-11-27 22:33:40 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2010-11-27 22:33:40 +0300 |
commit | f973be9fe4977ebec1a4fc4ddeef9a502ed23195 (patch) | |
tree | 1cb453f28ca0293ac3b3ed4a41e32eefe2cc5ac1 /source/blender/imbuf/intern/openexr | |
parent | 1e579c780ca1bd043ba77a77b807cdeaf1dc4bd8 (diff) |
Bugfix #21385
Blender MultiLayer openEXR files now save with correct scanline order.
Code also provides backward compatibility. Also thanks to Troy Sobotka!
Diffstat (limited to 'source/blender/imbuf/intern/openexr')
-rw-r--r-- | source/blender/imbuf/intern/openexr/openexr_api.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 964e57f6cfe..81ec43c4c10 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -342,6 +342,7 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag 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; @@ -498,7 +499,7 @@ void IMB_exr_begin_write(void *handle, const char *filename, int width, int heig // 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); } @@ -615,9 +616,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 +643,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); } |