[Bf-blender-cvs] [2a097527f20] master: Fix various issues with (multiview) OpenEXR file save/load.

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


Commit: 2a097527f20da98bb4c1199c2854a15eea241153
Author: Brecht Van Lommel
Date:   Fri Oct 20 15:18:26 2017 +0200
Branches: master
https://developer.blender.org/rB2a097527f20da98bb4c1199c2854a15eea241153

Fix various issues with (multiview) OpenEXR file save/load.

* Fix saving a multiview render from the image editor giving invalid files.
* Fix failure to load multiview images with a single view per part.
* Fix loss of multiview metadata when saving/loading a single view.
* Fix Z-Buffer writing option for single layer EXR not being respected.

Multiview EXRs are now always handled as multilayer internally, significantly
reducing the amount of code.

Reviewed By: dfelinto

Differential Revision: https://developer.blender.org/D2887

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

M	source/blender/blenkernel/intern/image.c
M	source/blender/editors/space_image/image_buttons.c
M	source/blender/editors/space_image/image_ops.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/extern/include/RE_pipeline.h
M	source/blender/render/intern/include/render_result.h
M	source/blender/render/intern/source/pipeline.c
M	source/blender/render/intern/source/render_result.c

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

diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 4cdf98285c0..9ba7cc1c679 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2924,7 +2924,8 @@ bool BKE_image_is_multilayer(Image *ima)
 
 bool BKE_image_is_multiview(Image *ima)
 {
-	return (BLI_listbase_count_ex(&ima->views, 2) > 1);
+	ImageView *view = ima->views.first;
+	return (view && (view->next || view->name[0]));
 }
 
 bool BKE_image_is_stereo(Image *ima)
@@ -3030,51 +3031,6 @@ void BKE_image_backup_render(Scene *scene, Image *ima, bool free_current_slot)
 	ima->last_render_slot = slot;
 }
 
-/**************************** multiview save openexr *********************************/
-#ifdef WITH_OPENEXR
-static const char *image_get_view_cb(void *base, const int view_id)
-{
-	Image *ima = base;
-	ImageView *iv = BLI_findlink(&ima->views, view_id);
-	return iv ? iv->name : "";
-}
-#endif  /* WITH_OPENEXR */
-
-#ifdef WITH_OPENEXR
-static ImBuf *image_get_buffer_cb(void *base, const int view_id)
-{
-	Image *ima = base;
-	ImageUser iuser = {0};
-
-	iuser.view = view_id;
-	iuser.ok = 1;
-
-	BKE_image_multiview_index(ima, &iuser);
-
-	return image_acquire_ibuf(ima, &iuser, NULL);
-}
-#endif  /* WITH_OPENEXR */
-
-bool BKE_image_save_openexr_multiview(Image *ima, ImBuf *ibuf, const char *filepath, const int flags)
-{
-#ifdef WITH_OPENEXR
-	char name[FILE_MAX];
-	bool ok;
-
-	BLI_strncpy(name, filepath, sizeof(name));
-	BLI_path_abs(name, G.main->name);
-
-	ibuf->userdata = ima;
-	ok = IMB_exr_multiview_save(ibuf, name, flags, BLI_listbase_count(&ima->views), image_get_view_cb, image_get_buffer_cb);
-	ibuf->userdata = NULL;
-
-	return ok;
-#else
-	UNUSED_VARS(ima, ibuf, filepath, flags);
-	return false;
-#endif
-}
-
 /**************************** multiview load openexr *********************************/
 
 static void image_add_view(Image *ima, const char *viewname, const char *filepath)
@@ -3107,51 +3063,6 @@ static void image_add_view(Image *ima, const char *viewname, const char *filepat
 	}
 }
 
-#ifdef WITH_OPENEXR
-static void image_add_view_cb(void *base, const char *str)
-{
-	Image *ima = base;
-	image_add_view(ima, str, ima->name);
-}
-
-static void image_add_buffer_cb(void *base, const char *str, ImBuf *ibuf, const int frame)
-{
-	Image *ima = base;
-	int 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));
-
-	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);
-	IMB_freeImBuf(ibuf);
-}
-#endif  /* WITH_OPENEXR */
-
-/* after imbuf load, openexr type can return with a exrhandle open */
-/* in that case we have to build a render-result */
-#ifdef WITH_OPENEXR
-static void image_create_multiview(Image *ima, ImBuf *ibuf, const int frame)
-{
-	BKE_image_free_views(ima);
-
-	IMB_exr_multiview_convert(ibuf->userdata, ima, image_add_view_cb, image_add_buffer_cb, frame);
-
-	IMB_exr_close(ibuf->userdata);
-}
-#endif  /* WITH_OPENEXR */
-
 /* after imbuf load, openexr type can return with a exrhandle open */
 /* in that case we have to build a render-result */
 #ifdef WITH_OPENEXR
@@ -3263,16 +3174,10 @@ static ImBuf *load_sequence_single(Image *ima, ImageUser *iuser, int frame, cons
 
 	if (ibuf) {
 #ifdef WITH_OPENEXR
-		/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
 		if (ibuf->ftype == IMB_FTYPE_OPENEXR && ibuf->userdata) {
-			/* handle singlelayer multiview case assign ibuf based on available views */
-			if (IMB_exr_has_singlelayer_multiview(ibuf->userdata)) {
-				image_create_multiview(ima, ibuf, frame);
-				IMB_freeImBuf(ibuf);
-				ibuf = NULL;
-			}
-			else if (IMB_exr_has_multilayer(ibuf->userdata)) {
-				/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
+			/* Handle multilayer and multiview cases, don't assign ibuf here.
+			 * will be set layer in BKE_image_acquire_ibuf from ima->rr. */
+			if (IMB_exr_has_multilayer(ibuf->userdata)) {
 				image_create_multilayer(ima, ibuf, frame);
 				ima->type = IMA_TYPE_MULTILAYER;
 				IMB_freeImBuf(ibuf);
@@ -3561,14 +3466,9 @@ static ImBuf *load_image_single(
 	if (ibuf) {
 #ifdef WITH_OPENEXR
 		if (ibuf->ftype == IMB_FTYPE_OPENEXR && ibuf->userdata) {
-			if (IMB_exr_has_singlelayer_multiview(ibuf->userdata)) {
-				/* handle singlelayer multiview case assign ibuf based on available views */
-				image_create_multiview(ima, ibuf, cfra);
-				IMB_freeImBuf(ibuf);
-				ibuf = NULL;
-			}
-			else if (IMB_exr_has_multilayer(ibuf->userdata)) {
-				/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
+			/* Handle multilayer and multiview cases, don't assign ibuf here.
+			 * will be set layer in BKE_image_acquire_ibuf from ima->rr. */
+			if (IMB_exr_has_multilayer(ibuf->userdata)) {
 				image_create_multilayer(ima, ibuf, cfra);
 				ima->type = IMA_TYPE_MULTILAYER;
 				IMB_freeImBuf(ibuf);
@@ -4408,7 +4308,7 @@ void BKE_image_update_frame(const Main *bmain, int cfra)
 
 void BKE_image_user_file_path(ImageUser *iuser, Image *ima, char *filepath)
 {
-	if (BKE_image_is_multiview(ima) && (ima->rr == NULL)) {
+	if (BKE_image_is_multiview(ima)) {
 		ImageView *iv = BLI_findlink(&ima->views, iuser->view);
 		if (iv->filepath[0])
 			BLI_strncpy(filepath, iv->filepath, FILE_MAX);
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index d68e4c88935..d2897c7264b 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -1112,7 +1112,7 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
 		uiItemR(row, imfptr, "use_zbuffer", 0, NULL, ICON_NONE);
 	}
 
-	if (is_render_out && (imf->imtype == R_IMF_IMTYPE_OPENEXR)) {
+	if (is_render_out && ELEM(imf->imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
 		show_preview = true;
 		uiItemR(row, imfptr, "use_preview", 0, NULL, ICON_NONE);
 	}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index dacef926df1..f7df29ed2b6 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1824,9 +1824,6 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
 		const bool save_as_render = (RNA_struct_find_property(op->ptr, "save_as_render") && RNA_boolean_get(op->ptr, "save_as_render"));
 		ImageFormatData *imf = &simopts->im_format;
 
-		const bool is_multilayer = imf->imtype == R_IMF_IMTYPE_MULTILAYER;
-		bool is_mono;
-
 		/* old global to ensure a 2nd save goes to same dir */
 		BLI_strncpy(G.ima, simopts->filepath, sizeof(G.ima));
 
@@ -1853,7 +1850,8 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
 		/* we need renderresult for exr and rendered multiview */
 		scene = CTX_data_scene(C);
 		rr = BKE_image_acquire_renderresult(scene, ima);
-		is_mono = rr ? BLI_listbase_count_ex(&rr->views, 2) < 2 : BLI_listbase_count_ex(&ima->views, 2) < 2;
+		bool is_mono = rr ? BLI_listbase_count_ex(&rr->views, 2) < 2 : BLI_listbase_count_ex(&ima->views, 2) < 2;
+		bool is_exr_rr = rr && ELEM(imf->imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER);
 
 		/* error handling */
 		if (!rr) {
@@ -1883,28 +1881,23 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
 		}
 
 		/* fancy multiview OpenEXR */
-		if ((imf->imtype == R_IMF_IMTYPE_MULTILAYER) && (imf->views_format == R_IMF_VIEWS_MULTIVIEW)) {
-			ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, imf, true, NULL);
+		if (imf->views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) {
+			/* save render result */
+			ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, imf, NULL, sima->iuser.layer);
 			save_image_post(op, ibuf, ima, ok, true, relbase, relative, do_newpath, simopts->filepath);
 			ED_space_image_release_buffer(sima, ibuf, lock);
 		}
-		else if ((imf->imtype == R_IMF_IMTYPE_OPENEXR) && (imf->views_format == R_IMF_VIEWS_MULTIVIEW)) {
-			/* treat special Openexr case separetely (this is the singlelayer multiview OpenEXR */
-			BKE_imbuf_write_prepare(ibuf, imf);
-			ok = BKE_image_save_openexr_multiview(ima, ibuf, simopts->filepath, (IB_rect | IB_zbuf | IB_zbuffloat | IB_multiview));
-			ED_space_image_release_buffer(sima, ibuf, lock);
-		}
 		/* regular mono pipeline */
 		else if (is_mono) {
-			if (is_multilayer) {
-				ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, imf, false, NULL);
+			if (is_exr_rr) {
+				ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, imf, NULL, -1);
 			}
 			else {
 				colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf);
 				ok = BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, imf, save_copy);
 				save_imbuf_post(ibuf, colormanaged_ibuf);
 			}
-			save_image_post(op, ibuf, ima, ok, (is_multilayer ? true : save_copy), relbase, relative, do_newpath, simopts->filepath);
+			save_image_post(op, ibuf, ima, ok, (is_exr_rr ? true : save_copy), relbase, relative, do_newpath, simopts->filepath);
 			ED_space_image_release_buffer(sima, ibuf, lock);
 		}
 		/* individual multiview images */
@@ -1913,7 +1906,7 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
 			unsigned char planes = ibuf->planes;
 			const int totviews = (rr ? BLI_listbase_count(&rr->views) : BLI_listbase_count(&ima->views));
 
-			if (!is_multilayer) {
+			if (!is_exr_rr) {
 				ED_space_image_release_buffer(sima, ibuf, lock);
 			}
 
@@ -1923,9 +1916,9 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperato

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list