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
This commit is contained in:
Philipp Oeser 2020-03-31 17:51:50 +02:00
parent 59e001cbf6
commit 029a714fc7
Notes: blender-bot 2023-02-13 23:01:27 +01:00
Referenced by issue #75234, Saving UDIM tiled texture as OpenEXR saves only the first tile
1 changed files with 28 additions and 13 deletions

View File

@ -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;
}