From 8191066c0b6d17936f088baa6a549ee83e7b0db0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 11 Oct 2015 01:14:02 +0200 Subject: Fix T46223: multiview image sequences crashing. Differential Revision: https://developer.blender.org/D1549 --- source/blender/blenkernel/BKE_image.h | 2 + source/blender/blenkernel/intern/image.c | 135 +++++++++++-------------------- 2 files changed, 47 insertions(+), 90 deletions(-) (limited to 'source/blender/blenkernel') diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 94afc8a16ea..ea63161e008 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -212,6 +212,8 @@ void BKE_image_multiview_index(struct Image *ima, struct ImageUser *iuser); /* for multilayer images as well as for render-viewer */ bool BKE_image_is_multilayer(struct Image *ima); +bool BKE_image_is_multiview(struct Image *ima); +bool BKE_image_is_stereo(struct Image *ima); struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima); void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 1b329815493..f451149c948 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -280,14 +280,9 @@ void BKE_image_free_packedfiles(Image *ima) image_free_packedfiles(ima); } -static void image_free_views(Image *ima) -{ - BLI_freelistN(&ima->views); -} - void BKE_image_free_views(Image *image) { - image_free_views(image); + BLI_freelistN(&image->views); } static void image_free_anims(Image *ima) @@ -350,7 +345,7 @@ void BKE_image_free(Image *ima) } } - image_free_views(ima); + BKE_image_free_views(ima); MEM_freeN(ima->stereo3d_format); } @@ -866,8 +861,6 @@ Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int hei } ima->ok = IMA_OK_LOADED; - if (stereo3d) - ima->flag |= IMA_IS_STEREO | IMA_IS_MULTIVIEW; } return ima; @@ -957,7 +950,7 @@ void BKE_image_memorypack(Image *ima) { ImBuf *ibuf; - if ((ima->flag & IMA_IS_MULTIVIEW)) { + if (BKE_image_is_multiview(ima)) { image_memorypack_multiview(ima); return; } @@ -2483,15 +2476,8 @@ void BKE_image_verify_viewer_views(const RenderData *rd, Image *ima, ImageUser * BLI_lock_thread(LOCK_DRAW_IMAGE); - if (BKE_scene_multiview_is_stereo3d(rd)) { - ima->flag |= IMA_IS_STEREO; - ima->flag |= IMA_IS_MULTIVIEW; - } - else { - ima->flag &= ~IMA_IS_STEREO; - ima->flag &= ~IMA_IS_MULTIVIEW; + if (!BKE_scene_multiview_is_stereo3d(rd)) iuser->flag &= ~IMA_SHOW_STEREO; - } /* see if all scene render views are in the image view list */ do_reset = (BKE_scene_multiview_num_views_get(rd) != BLI_listbase_count(&ima->views)); @@ -2832,7 +2818,7 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser) void BKE_image_multiview_index(Image *ima, ImageUser *iuser) { if (iuser) { - bool is_stereo = (ima->flag & IMA_IS_STEREO) && (iuser->flag & IMA_SHOW_STEREO); + bool is_stereo = BKE_image_is_stereo(ima) && (iuser->flag & IMA_SHOW_STEREO); if (is_stereo) { iuser->multi_index = iuser->multiview_eye; } @@ -2865,27 +2851,27 @@ bool BKE_image_is_multilayer(Image *ima) return false; } -static void image_init_multilayer_multiview_flag(Image *ima, RenderResult *rr) +bool BKE_image_is_multiview(Image *ima) { + return (BLI_listbase_count_ex(&ima->views, 2) > 1); +} + +bool BKE_image_is_stereo(Image *ima) +{ + return BKE_image_is_multiview(ima) && + (BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) && + BLI_findstring(&ima->views, STEREO_RIGHT_NAME, offsetof(ImageView, name))); +} + +static void image_init_multilayer_multiview(Image *ima, RenderResult *rr) +{ + BKE_image_free_views(ima); if (rr) { - if (RE_RenderResult_is_stereo(rr)) { - ima->flag |= IMA_IS_STEREO; - ima->flag |= IMA_IS_MULTIVIEW; - } - else { - ima->flag &= ~IMA_IS_STEREO; - if (BLI_listbase_count_ex(&rr->views, 2) > 1) - ima->flag |= IMA_IS_MULTIVIEW; - else - ima->flag &= ~IMA_IS_MULTIVIEW; - } - } - else { - ima->flag &= ~IMA_IS_STEREO; - ima->flag &= ~IMA_IS_MULTIVIEW; + BLI_duplicatelist(&ima->views, &rr->views); } } + RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima) { RenderResult *rr = NULL; @@ -2898,8 +2884,8 @@ RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima) else rr = ima->renders[ima->render_slot]; - /* set proper multiview flag */ - image_init_multilayer_multiview_flag(ima, rr); + /* set proper views */ + image_init_multilayer_multiview(ima, rr); } return rr; @@ -3057,39 +3043,15 @@ static void image_add_buffer_cb(void *base, const char *str, ImBuf *ibuf, const } #endif /* WITH_OPENEXR */ -#ifdef WITH_OPENEXR -static void image_update_multiview_flags(Image *ima) -{ - if (BLI_listbase_count_ex(&ima->views, 2) > 1) { - ima->flag |= IMA_IS_MULTIVIEW; - - if (BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) && - BLI_findstring(&ima->views, STEREO_RIGHT_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; - } -} -#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) { - image_free_views(ima); + BKE_image_free_views(ima); IMB_exr_multiview_convert(ibuf->userdata, ima, image_add_view_cb, image_add_buffer_cb, frame); - image_update_multiview_flags(ima); - IMB_exr_close(ibuf->userdata); } #endif /* WITH_OPENEXR */ @@ -3110,8 +3072,8 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr) if (ima->rr) ima->rr->framenr = framenr; - /* set proper multiview flag */ - image_init_multilayer_multiview_flag(ima, ima->rr); + /* set proper views */ + image_init_multilayer_multiview(ima, ima->rr); } #endif /* WITH_OPENEXR */ @@ -3149,7 +3111,7 @@ static int imbuf_alpha_flags_for_image(Image *ima) /* the number of files will vary according to the stereo format */ static size_t image_num_files(Image *ima) { - const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0; + const bool is_multiview = BKE_image_is_multiview(ima); if (!is_multiview) { return 1; @@ -3231,7 +3193,7 @@ static ImBuf *load_sequence_single(Image *ima, ImageUser *iuser, int frame, cons static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) { struct ImBuf *ibuf = NULL; - const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0; + const bool is_multiview = BKE_image_is_multiview(ima); const size_t totfiles = image_num_files(ima); bool assign = false; @@ -3251,7 +3213,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) for (i = 0; i < totfiles; i++) ibuf_arr[i] = load_sequence_single(ima, iuser, frame, i, &assign); - if ((ima->flag & IMA_IS_STEREO) && ima->views_format == R_IMF_VIEWS_STEREO_3D) + if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D) IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); /* return the original requested ImBuf */ @@ -3388,7 +3350,7 @@ static ImBuf *load_movie_single(Image *ima, ImageUser *iuser, int frame, const s static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) { struct ImBuf *ibuf = NULL; - const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0; + const bool is_multiview = BKE_image_is_multiview(ima); const size_t totfiles = image_num_files(ima); size_t i; @@ -3416,7 +3378,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) ibuf_arr[i] = load_movie_single(ima, iuser, frame, i); } - if ((ima->flag & IMA_IS_STEREO) && ima->views_format == R_IMF_VIEWS_STEREO_3D) + if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D) IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); for (i = 0; i < totviews; i++) { @@ -3544,7 +3506,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) { struct ImBuf *ibuf = NULL; bool assign = false; - const bool is_multiview = (ima->flag & IMA_IS_MULTIVIEW) != 0; + const bool is_multiview = BKE_image_is_multiview(ima); const size_t totfiles = image_num_files(ima); bool has_packed = BKE_image_has_packedfile(ima); @@ -3577,7 +3539,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) ibuf_arr[i] = load_image_single(ima, iuser, cfra, i, has_packed, &assign); /* multi-views/multi-layers OpenEXR files directly populate ima, and return NULL ibuf... */ - if ((ima->flag & IMA_IS_STEREO) && ima->views_format == R_IMF_VIEWS_STEREO_3D && + if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D && ibuf_arr[0] && totfiles == 1 && totviews >= 2) { IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); @@ -3677,7 +3639,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc pass = iuser->pass; actview = iuser->view; - if ((ima->flag & IMA_IS_STEREO) && (iuser->flag & IMA_SHOW_STEREO)) + if (BKE_image_is_stereo(ima) && (iuser->flag & IMA_SHOW_STEREO)) actview = iuser->multiview_eye; if (from_render) { @@ -3851,12 +3813,12 @@ static size_t image_get_multiview_index(Image *ima, ImageUser *iuser) return iuser ? iuser->multi_index : index; } else if (is_backdrop) { - if ((ima->flag & IMA_IS_STEREO)) { + if (BKE_image_is_stereo(ima)) { /* backdrop hackaround (since there is no iuser */ return ima->eye; } } - else if ((ima->flag & IMA_IS_MULTIVIEW)) { + else if (BKE_image_is_multiview(ima)) { return iuser ? iuser->multi_index : index; } @@ -4345,9 +4307,12 @@ void BKE_image_update_frame(const Main *bmain, int cfra) void BKE_image_user_file_path(ImageUser *iuser, Image *ima, char *filepath) { - if ((ima->flag & IMA_IS_MULTIVIEW) && (ima->rr == NULL)) { + if (BKE_image_is_multiview(ima) && (ima->rr == NULL)) { ImageView *iv = BLI_findlink(&ima->views, iuser->view); - BLI_strncpy(filepath, iv->filepath, FILE_MAX); + if (iv->filepath[0]) + BLI_strncpy(filepath, iv->filepath, FILE_MAX); + else + BLI_strncpy(filepath, ima->name, FILE_MAX); } else { BLI_strncpy(filepath, ima->name, FILE_MAX); @@ -4642,15 +4607,12 @@ static void image_update_views_format(Image *ima, ImageUser *iuser) BKE_image_free_views(ima); if (!is_multiview) { - goto monoview; + /* nothing to do */ } else if (ima->views_format == R_IMF_VIEWS_STEREO_3D) { size_t i; const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; - ima->flag |= IMA_IS_MULTIVIEW; - ima->flag |= IMA_IS_STEREO; - for (i = 0; i < 2; i++) { image_add_view(ima, names[i], ima->name); } @@ -4665,7 +4627,8 @@ static void image_update_views_format(Image *ima, ImageUser *iuser) BKE_scene_multiview_view_prefix_get(scene, name, prefix, &ext); if (prefix[0] == '\0') { - goto monoview; + BKE_image_free_views(ima); + return; } /* create all the image views */ @@ -4701,15 +4664,7 @@ static void image_update_views_format(Image *ima, ImageUser *iuser) } /* all good */ - if (BLI_listbase_count_ex(&ima->views, 2) > 1) { - ima->flag |= IMA_IS_MULTIVIEW; - if (BKE_scene_multiview_is_stereo3d(&scene->r)) - ima->flag |= IMA_IS_STEREO; - } - else { -monoview: - ima->flag &= ~IMA_IS_STEREO; - ima->flag &= ~IMA_IS_MULTIVIEW; + if (!BKE_image_is_multiview(ima)) { BKE_image_free_views(ima); } } -- cgit v1.2.3