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:
authorTon Roosendaal <ton@blender.org>2010-11-27 22:33:40 +0300
committerTon Roosendaal <ton@blender.org>2010-11-27 22:33:40 +0300
commitf973be9fe4977ebec1a4fc4ddeef9a502ed23195 (patch)
tree1cb453f28ca0293ac3b3ed4a41e32eefe2cc5ac1 /source/blender/imbuf
parent1e579c780ca1bd043ba77a77b807cdeaf1dc4bd8 (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')
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp30
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);
}