Bugfix #21385
Blender MultiLayer openEXR files now save with correct scanline order. Code also provides backward compatibility. Also thanks to Troy Sobotka!
This commit is contained in:
@@ -45,7 +45,7 @@ struct Scene;
|
||||
struct Main;
|
||||
|
||||
#define BLENDER_VERSION 255
|
||||
#define BLENDER_SUBVERSION 0
|
||||
#define BLENDER_SUBVERSION 1
|
||||
|
||||
#define BLENDER_MINVERSION 250
|
||||
#define BLENDER_MINSUBVERSION 0
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user