Commit: 05b08a3b6d864d760942c052a92c42c2bbe2c54d
Author: Brecht Van Lommel
Date:   Thu Oct 19 03:55:11 2017 +0200
Branches: master
https://developer.blender.org/rB05b08a3b6d864d760942c052a92c42c2bbe2c54d

Fix T53092: errors reading EXR files with different data/display window.

Multilayer/multiview OpenEXRs did not read the full data window like single
layer, now it should be consistent.

===================================================================

M       source/blender/imbuf/intern/openexr/openexr_api.cpp

===================================================================

diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp 
b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index b3286bfbd98..451869415e7 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1106,10 +1106,7 @@ void IMB_exrtile_write_channels(void *handle, int partx, 
int party, int level, c
 void IMB_exr_read_channels(void *handle)
 {
        ExrHandle *data = (ExrHandle *)handle;
-       ExrChannel *echan;
        int numparts = data->ifile->parts();
-       std::vector<FrameBuffer> frameBuffers(numparts);
-       std::vector<InputPart> inputParts;
 
        /* check if exr was saved with previous versions of blender which 
flipped images */
        const StringAttribute *ta = data->ifile->header(0).findTypedAttribute 
<StringAttribute> ("BlenderMultiChannel");
@@ -1117,37 +1114,56 @@ void IMB_exr_read_channels(void *handle)
 
        exr_printf("\nIMB_exr_read_channels\n%s %-6s %-22s 
\"%s\"\n---------------------------------------------------------------------\n",
 "p", "view", "name", "internal_name");
 
-       for (echan = (ExrChannel *)data->channels.first; echan; echan = 
echan->next) {
-               exr_printf("%d %-6s %-22s \"%s\"\n", echan->m->part_number, 
echan->m->view.c_str(), echan->m->name.c_str(), 
echan->m->internal_name.c_str());
+       for (int i = 0; i < numparts; i++) {
+               /* Read part header. */
+               InputPart in(*data->ifile, i);
+               Header header = in.header();
+               Box2i dw = header.dataWindow();
+
+               /* Insert all matching channel into framebuffer. */
+               FrameBuffer frameBuffer;
+               ExrChannel *echan;
+
+               for (echan = (ExrChannel *)data->channels.first; echan; echan = 
echan->next) {
+                       if(echan->m->part_number != i) {
+                               continue;
+                       }
+
+                       exr_printf("%d %-6s %-22s \"%s\"\n", 
echan->m->part_number, echan->m->view.c_str(), echan->m->name.c_str(), 
echan->m->internal_name.c_str());
+
+                       if (echan->rect) {
+                               float *rect = echan->rect;
+                               size_t xstride = echan->xstride * sizeof(float);
+                               size_t ystride = echan->ystride * sizeof(float);
+
+                               if (!flip) {
+                                       /* inverse correct first pixel for 
datawindow coordinates */
+                                       rect -= echan->xstride * (dw.min.x - 
dw.min.y * data->width);
+                                       /* move to last scanline to flip to 
Blender convention */
+                                       rect += echan->xstride * (data->height 
- 1) * data->width;
+                                       ystride = -ystride;
+                               }
+                               else {
+                                       /* inverse correct first pixel for 
datawindow coordinates */
+                                       rect -= echan->xstride * (dw.min.x + 
dw.min.y * data->width);
+                               }
 
-               if (echan->rect) {
-                       if (flip)
-                               
frameBuffers[echan->m->part_number].insert(echan->m->internal_name, 
Slice(Imf::FLOAT,  (char *)echan->rect,
-                                                                     
echan->xstride * sizeof(float), echan->ystride * sizeof(float)));
+                               frameBuffer.insert(echan->m->internal_name, 
Slice(Imf::FLOAT, (char *)rect, xstride, ystride));
+                       }
                        else
-                               
frameBuffers[echan->m->part_number].insert(echan->m->internal_name, 
Slice(Imf::FLOAT,  (char *)(echan->rect + echan->xstride * (data->height - 1) * 
data->width),
-                                                                     
echan->xstride * sizeof(float), -echan->ystride * sizeof(float)));
+                               printf("warning, channel with no rect set 
%s\n", echan->m->internal_name.c_str());
                }
-               else
-                       printf("warning, channel with no rect set %s\n", 
echan->m->internal_name.c_str());
-       }
 
-       for (int i = 0; i < numparts; i++) {
-               InputPart in (*data->ifile, i);
-               in.setFrameBuffer(frameBuffers[i]);
-               inputParts.push_back(in);
-       }
-
-       try {
-               for (int i = 0; i < numparts; i++) {
-                       Header header = inputParts[i].header();
-                       exr_printf("readPixels:readPixels[%d]: min.y: %d, 
max.y: %d\n", i, header.dataWindow().min.y, header.dataWindow().max.y);
-                       inputParts[i].readPixels(header.dataWindow().min.y, 
header.dataWindow().max.y);
-                       inputParts[i].readPixels(0, data->height - 1);
+               /* Read pixels. */
+               try {
+                       in.setFrameBuffer(frameBuffer);
+                       exr_printf("readPixels:readPixels[%d]: min.y: %d, 
max.y: %d\n", i, dw.min.y, dw.max.y);
+                       in.readPixels(dw.min.y, dw.max.y);
+               }
+               catch (const std::exception& exc) {
+                       std::cerr << "OpenEXR-readPixels: ERROR: " << 
exc.what() << std::endl;
+                       break;
                }
-       }
-       catch (const std::exception& exc) {
-               std::cerr << "OpenEXR-readPixels: ERROR: " << exc.what() << 
std::endl;
        }
 }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to