[Bf-blender-cvs] [05b08a3b6d8] master: Fix T53092: errors reading EXR files with different data/display window.

Brecht Van Lommel noreply at git.blender.org
Wed Nov 8 00:02:53 CET 2017


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;
 	}
 }



More information about the Bf-blender-cvs mailing list