From 029a714fc72d79a4dc8d80c3397c308112a7fea9 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 31 Mar 2020 17:51:50 +0200 Subject: Fix T75234: Saving UDIM tiled texture as OpenEXR saves only the first tile This happened when the UDIM tiled image needed to be colormanaged, so - when you set up the image as sRGB, then save as EXR/HDR/... - other way around as well: when you set up the images as Linear then save as PNG/JPG/... Reason being that for UDIM tiled images, `image_save_single` is called multiple times [once for each tile] and everytime `image_save_post` will fire the `IMA_SIGNAL_COLORMANAGE` signal which clears the cache if any of the above two is the case. Without the cache, the next tiles cannot be saved. Now determine if the colorspace changed from `image_save_single`/'image_save_post' and only fire IMA_SIGNAL_COLORMANAGE once from BKE_image_save in the end. (thx @brecht for suggesting this alternative to the original fix) Maniphest Tasks: T75234 Differential Revision: https://developer.blender.org/D7296 --- source/blender/blenkernel/intern/image_save.c | 41 ++++++++++++++++++--------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'source/blender/blenkernel/intern/image_save.c') diff --git a/source/blender/blenkernel/intern/image_save.c b/source/blender/blenkernel/intern/image_save.c index bd570c9688b..b2e0f234f1e 100644 --- a/source/blender/blenkernel/intern/image_save.c +++ b/source/blender/blenkernel/intern/image_save.c @@ -54,13 +54,13 @@ void BKE_image_save_options_init(ImageSaveOptions *opts, Main *bmain, Scene *sce } static void image_save_post(ReportList *reports, - Main *bmain, Image *ima, ImBuf *ibuf, int ok, ImageSaveOptions *opts, int save_copy, - const char *filepath) + const char *filepath, + bool *r_colorspace_changed) { if (!ok) { BKE_reportf(reports, RPT_ERROR, "Could not write image: %s", strerror(errno)); @@ -114,7 +114,7 @@ static void image_save_post(ReportList *reports, IMB_colormanagement_colorspace_from_ibuf_ftype(&ima->colorspace_settings, ibuf); if (!BKE_color_managed_colorspace_settings_equals(&old_colorspace_settings, &ima->colorspace_settings)) { - BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_COLORMANAGE); + *r_colorspace_changed = true; } } @@ -138,8 +138,11 @@ static void imbuf_save_post(ImBuf *ibuf, ImBuf *colormanaged_ibuf) * \note ``ima->name`` and ``ibuf->name`` should end up the same. * \note for multiview the first ``ibuf`` is important to get the settings. */ -static bool image_save_single( - ReportList *reports, Main *bmain, Image *ima, ImageUser *iuser, ImageSaveOptions *opts) +static bool image_save_single(ReportList *reports, + Image *ima, + ImageUser *iuser, + ImageSaveOptions *opts, + bool *r_colorspace_changed) { void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); @@ -223,7 +226,7 @@ static bool image_save_single( if (imf->views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) { /* save render result */ ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, NULL, layer); - image_save_post(reports, bmain, ima, ibuf, ok, opts, true, opts->filepath); + image_save_post(reports, ima, ibuf, ok, opts, true, opts->filepath, r_colorspace_changed); BKE_image_release_ibuf(ima, ibuf, lock); } /* regular mono pipeline */ @@ -237,8 +240,14 @@ static bool image_save_single( ok = BKE_imbuf_write_as(colormanaged_ibuf, opts->filepath, imf, save_copy); imbuf_save_post(ibuf, colormanaged_ibuf); } - image_save_post( - reports, bmain, ima, ibuf, ok, opts, (is_exr_rr ? true : save_copy), opts->filepath); + image_save_post(reports, + ima, + ibuf, + ok, + opts, + (is_exr_rr ? true : save_copy), + opts->filepath, + r_colorspace_changed); BKE_image_release_ibuf(ima, ibuf, lock); } /* individual multiview images */ @@ -260,7 +269,7 @@ static bool image_save_single( if (is_exr_rr) { BKE_scene_multiview_view_filepath_get(&opts->scene->r, opts->filepath, view, filepath); ok_view = RE_WriteRenderResult(reports, rr, filepath, imf, view, layer); - image_save_post(reports, bmain, ima, ibuf, ok_view, opts, true, filepath); + image_save_post(reports, ima, ibuf, ok_view, opts, true, filepath, r_colorspace_changed); } else { /* copy iuser to get the correct ibuf for this view */ @@ -293,7 +302,7 @@ static bool image_save_single( ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf); ok_view = BKE_imbuf_write_as(colormanaged_ibuf, filepath, &opts->im_format, save_copy); imbuf_save_post(ibuf, colormanaged_ibuf); - image_save_post(reports, bmain, ima, ibuf, ok_view, opts, true, filepath); + image_save_post(reports, ima, ibuf, ok_view, opts, true, filepath, r_colorspace_changed); BKE_image_release_ibuf(ima, ibuf, lock); } ok &= ok_view; @@ -307,7 +316,7 @@ static bool image_save_single( else if (opts->im_format.views_format == R_IMF_VIEWS_STEREO_3D) { if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) { ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, NULL, layer); - image_save_post(reports, bmain, ima, ibuf, ok, opts, true, opts->filepath); + image_save_post(reports, ima, ibuf, ok, opts, true, opts->filepath, r_colorspace_changed); BKE_image_release_ibuf(ima, ibuf, lock); } else { @@ -393,6 +402,8 @@ bool BKE_image_save( ImageUser save_iuser; BKE_imageuser_default(&save_iuser); + bool colorspace_changed = false; + if (ima->source == IMA_SRC_TILED) { /* Verify filepath for tiles images. */ if (BLI_stringdec(opts->filepath, NULL, NULL, NULL) != 1001) { @@ -410,7 +421,7 @@ bool BKE_image_save( } /* Save image - or, for tiled images, the first tile. */ - bool ok = image_save_single(reports, bmain, ima, iuser, opts); + bool ok = image_save_single(reports, ima, iuser, opts, &colorspace_changed); if (ok && ima->source == IMA_SRC_TILED) { char filepath[FILE_MAX]; @@ -431,10 +442,14 @@ bool BKE_image_save( BLI_stringenc(opts->filepath, head, tail, numlen, tile->tile_number); iuser->tile = tile->tile_number; - ok = ok && image_save_single(reports, bmain, ima, iuser, opts); + ok = ok && image_save_single(reports, ima, iuser, opts, &colorspace_changed); } BLI_strncpy(opts->filepath, filepath, sizeof(opts->filepath)); } + if (colorspace_changed) { + BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_COLORMANAGE); + } + return ok; } -- cgit v1.2.3