[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