[Bf-blender-cvs] [c36dfb5] multiview: Support OpenEXR opening of single layer multiview files

Dalai Felinto noreply at git.blender.org
Wed Sep 17 14:12:24 CEST 2014


Commit: c36dfb595068c8c1f212dbfc94fdb4f5da3c0667
Author: Dalai Felinto
Date:   Sat Sep 13 00:26:54 2014 +0200
Branches: multiview
https://developer.blender.org/rBc36dfb595068c8c1f212dbfc94fdb4f5da3c0667

Support OpenEXR opening of single layer multiview files

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

M	release/datafiles/locale
M	release/scripts/addons
M	release/scripts/addons_contrib
M	scons
M	source/blender/blenkernel/intern/image.c
M	source/blender/imbuf/intern/openexr/openexr_api.cpp
M	source/blender/imbuf/intern/openexr/openexr_multi.h
M	source/blender/imbuf/intern/openexr/openexr_stub.cpp
M	source/blender/render/intern/source/render_result.c

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

diff --git a/release/datafiles/locale b/release/datafiles/locale
index b02bd60..a9a4c6e 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit b02bd6054548c2daa4a223e035835b626cc9476e
+Subproject commit a9a4c6e84c31fc4d3f21f75e714816e8a2261cf8
diff --git a/release/scripts/addons b/release/scripts/addons
index fcec730..f539dbf 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit fcec7304a00de3b612c6a5435328fdfd753fecd3
+Subproject commit f539dbf1906eeb2ef0ddc0d4b8f109e5a8f84d90
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
index 103b024..8f33ffc 160000
--- a/release/scripts/addons_contrib
+++ b/release/scripts/addons_contrib
@@ -1 +1 @@
-Subproject commit 103b024c9476ad849152fbba329e9fae2ebe137a
+Subproject commit 8f33ffcebed445755d3453b8f486306bcf2b142a
diff --git a/scons b/scons
index 1ec9310..625d446 160000
--- a/scons
+++ b/scons
@@ -1 +1 @@
-Subproject commit 1ec93106c40fab0c339d09c7ed9897c85ddf3da5
+Subproject commit 625d446ae8996ff1b3d660c44e2827fc832cf12b
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 9ea2f42..476aae4 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2786,6 +2786,76 @@ void BKE_image_backup_render(Scene *scene, Image *ima)
 	ima->last_render_slot = slot;
 }
 
+static void image_add_view_cb(void *base, const char *str)
+{
+	Image *ima = base;
+	ImageView *iv;
+
+	iv = MEM_mallocN(sizeof(ImageView), "Viewer Image View");
+	BLI_strncpy(iv->name, str, sizeof(iv->name));
+	BLI_addtail(&ima->views, iv);
+}
+
+static void image_add_buffer_cb(void *base, const char *str, ImBuf *ibuf, const int frame)
+{
+	Image *ima = base;
+	size_t id;
+	bool predivide = (ima->alpha_mode == IMA_ALPHA_PREMUL);
+	const char *colorspace = ima->colorspace_settings.name;
+	const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+	
+	if (ibuf == NULL)
+		return;
+	
+	id = BLI_findstringindex(&ima->views, str, offsetof(ImageView, name));
+
+	printf("%s : %s : %lu\n", __func__, str, id);
+	
+	if (id == -1)
+		return;
+
+	if (ibuf->channels >= 3)
+		IMB_colormanagement_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
+		                              colorspace, to_colorspace, predivide);
+
+	image_assign_ibuf(ima, ibuf, id, frame);
+}
+
+static void image_update_multiview_flags(Image *ima)
+{
+	if (BLI_countlist(&ima->views) > 1) {
+		ima->flag |= IMA_IS_MULTIVIEW;
+
+		if (BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) &&
+		    BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)))
+		{
+			ima->flag |= IMA_IS_STEREO;
+		}
+		else {
+			ima->flag &= ~IMA_IS_STEREO;
+		}
+	}
+	else {
+		ima->flag &= ~IMA_IS_STEREO;
+		ima->flag &= ~IMA_IS_MULTIVIEW;
+	}
+}
+
+/* after imbuf load, openexr type can return with a exrhandle open */
+/* in that case we have to build a render-result */
+static void image_create_multiview(Image *ima, ImBuf *ibuf, const int frame)
+{
+	image_free_views(ima);
+
+	IMB_exr_singlelayer_multiview_convert(ibuf->userdata, ima, image_add_view_cb, image_add_buffer_cb, frame);
+
+	image_update_multiview_flags(ima);
+
+#ifdef WITH_OPENEXR
+	IMB_exr_close(ibuf->userdata);
+#endif
+}
+
 /* after imbuf load, openexr type can return with a exrhandle open */
 /* in that case we have to build a render-result */
 static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
@@ -2909,18 +2979,26 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
 	for (i = 0; i < totfiles; i++) {
 		if (ibuf[i]) {
 #ifdef WITH_OPENEXR
-			/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
 			if (ibuf[i]->ftype == OPENEXR && ibuf[i]->userdata) {
-				image_create_multilayer(ima, ibuf[i], frame);
-				ima->type = IMA_TYPE_MULTILAYER;
-				IMB_freeImBuf(ibuf[i]);
-				ibuf[i] = NULL;
+				/* handle singlelayer multiview case assign ibuf based on available views */
+				if (IMB_exr_has_singlelayer_multiview(ibuf[i]->userdata)) {
+					image_create_multiview(ima, ibuf[i], frame);
+					IMB_freeImBuf(ibuf[i]);
+					ibuf[i] = NULL;
+				}
+				else if (IMB_exr_has_multilayer(ibuf[i]->userdata)) {
+					/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
+					image_create_multilayer(ima, ibuf[i], frame);
+					ima->type = IMA_TYPE_MULTILAYER;
+					IMB_freeImBuf(ibuf[i]);
+					ibuf[i] = NULL;
+				}
 			}
 			else {
 				image_initialize_after_load(ima, ibuf[i]);
 				assign = true;
 			}
-	#else
+#else
 			image_initialize_after_load(ima, ibuf[i]);
 			assign = true;
 #endif
@@ -3169,12 +3247,21 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
 
 	for (i = 0; i < totfiles; i++) {
 		if (ibuf[i]) {
-			/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
+#ifdef WITH_OPENEXR
 			if (ibuf[i]->ftype == OPENEXR && ibuf[i]->userdata) {
-				image_create_multilayer(ima, ibuf[i], cfra);
-				ima->type = IMA_TYPE_MULTILAYER;
-				IMB_freeImBuf(ibuf[i]);
-				ibuf[i] = NULL;
+				/* handle singlelayer multiview case assign ibuf based on available views */
+				if (IMB_exr_has_singlelayer_multiview(ibuf[i]->userdata)) {
+					image_create_multiview(ima, ibuf[i], cfra);
+					IMB_freeImBuf(ibuf[i]);
+					ibuf[i] = NULL;
+				}
+				else if (IMB_exr_has_multilayer(ibuf[i]->userdata)) {
+					/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
+					image_create_multilayer(ima, ibuf[i], cfra);
+					ima->type = IMA_TYPE_MULTILAYER;
+					IMB_freeImBuf(ibuf[i]);
+					ibuf[i] = NULL;
+				}
 			}
 			else {
 				image_initialize_after_load(ima, ibuf[i]);
@@ -3192,6 +3279,10 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
 					BLI_addtail(&ima->packedfiles, imapf);
 				}
 			}
+#else
+			image_initialize_after_load(ima, ibuf[i]);
+			assign = true;
+#endif
 		}
 		else
 			ima->ok = 0;
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 65e397c..ee779e7 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -105,6 +105,10 @@ extern "C"
 {
 /* prototype */
 static struct ExrPass *imb_exr_get_pass(ListBase *lb, char *passname);
+static bool imb_exr_is_multiview(MultiPartInputFile *file);
+static bool imb_exr_is_multipart(MultiPartInputFile *file);
+static int exr_has_alpha(MultiPartInputFile *file);
+static int exr_has_zbuffer(MultiPartInputFile *file);
 
 static void exr_printf(const char *__restrict format, ...);
 }
@@ -622,8 +626,8 @@ static int imb_exr_get_multiView_id(StringVector& views, const std::string& name
 
 static void imb_exr_get_views(MultiPartInputFile *file, StringVector& views)
 {
-	if(file->parts() == 1) {
-		if(hasMultiView(file->header(0))) {
+	if(imb_exr_is_multipart(file) == false) {
+		if(imb_exr_is_multiview(file)) {
 			StringVector sv = multiView(file->header(0));
 			for (StringVector::const_iterator i = sv.begin(); i != sv.end(); ++i)
 				views.push_back(*i);
@@ -632,9 +636,9 @@ static void imb_exr_get_views(MultiPartInputFile *file, StringVector& views)
 
 	else {
 		for(int p = 0; p < file->parts(); p++) {
-			std::string view="";
+			std::string view = "";
 			if(file->header(p).hasView())
-				view=file->header(p).view();
+				view = file->header(p).view();
 
 			if (imb_exr_get_multiView_id(views, view) == -1)
 				views.push_back(view);
@@ -1288,6 +1292,75 @@ void IMB_exr_multilayer_convert(void *handle, void *base,
 	}
 }
 
+void IMB_exr_singlelayer_multiview_convert(void *handle, void *base,
+                                           void (*addview)(void *base, const char *str),
+                                           void (*addbuffer)(void *base, const char *str, ImBuf *ibuf, const int frame),
+                                           const int frame)
+{
+	ExrHandle *data = (ExrHandle *)handle;
+	MultiPartInputFile *file = data->ifile;
+	ExrLayer *lay;
+	ExrPass *pass;
+	ImBuf *ibuf = NULL;
+	const int is_alpha = exr_has_alpha(file);
+	Box2i dw = file->header(0).dataWindow();
+	const size_t width  = dw.max.x - dw.min.x + 1;
+	const size_t height = dw.max.y - dw.min.y + 1;
+	const bool is_depth = exr_has_zbuffer(file);
+	
+	/* add views to RenderResult */
+	for (StringVector::const_iterator i = data->multiView->begin(); i != data->multiView->end(); ++i) {
+		addview(base, (*i).c_str());
+	}
+	
+	if (BLI_listbase_is_empty(&data->layers)) {
+		printf("cannot convert multiviews, no views in handle\n");
+		return;
+	}
+	
+	/* there is one float/pass per layer (layer here is a view) */
+	BLI_assert(BLI_countlist(&data->layers) == 1);
+	lay = (ExrLayer *)data->layers.first;
+	for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) {
+		if (STREQ(pass->chan_id, "RGB") || STREQ(pass->chan_id, "RGBA")) {
+			ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, IB_rectfloat);
+
+			if (!ibuf) {
+				printf("error creating multiview buffer\n");
+				return;
+			}
+
+			IMB_buffer_float_from_float(
+			        ibuf->rect_float, pass->rect, pass->totchan,
+			        IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
+			        ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+
+			if (hasXDensity(file->header(0))) {
+				ibuf->ppm[0] = xDensity(file->header(0)) * 39.3700787f;
+				ibuf->ppm[1] = ibuf->ppm[0] * (double)file->header(0).pixelAspectRatio();
+			}
+
+			if (is_depth) {
+				ExrPass *zpass;
+				for (zpass = (ExrPass *)lay->passes.first; zpass; zpass = zpass->next) {
+					if (STREQ(zpass->chan_id, "Z") && STREQ(zpass->view, pass->view)) {
+						addzbuffloatImBuf(ibuf);
+
+						IMB_buffer_float_from_float(
+						        ibuf->zbuf_float, zpass->rect, zpass->totchan,
+						        IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
+						        ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+						zpass->rect = NULL;
+					}
+				}
+			}
+
+			addbuffer(base, pass->view, ibuf, frame);
+			pass->rect = NULL;
+		}

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list