Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/image_save.c
| Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
| static void image_save_post(ReportList *reports, | static void image_save_post(ReportList *reports, | ||||
| Main *bmain, | Main *bmain, | ||||
| Image *ima, | Image *ima, | ||||
| ImBuf *ibuf, | ImBuf *ibuf, | ||||
| int ok, | int ok, | ||||
| ImageSaveOptions *opts, | ImageSaveOptions *opts, | ||||
| int save_copy, | int save_copy, | ||||
| const char *filepath) | const char *filepath, | ||||
| const bool skip_post_signal) | |||||
| { | { | ||||
| if (!ok) { | if (!ok) { | ||||
| BKE_reportf(reports, RPT_ERROR, "Could not write image: %s", strerror(errno)); | BKE_reportf(reports, RPT_ERROR, "Could not write image: %s", strerror(errno)); | ||||
| return; | return; | ||||
| } | } | ||||
| if (save_copy) { | if (save_copy) { | ||||
| return; | return; | ||||
| Show All 36 Lines | if (opts->relative) { | ||||
| const char *relbase = ID_BLEND_PATH(opts->bmain, &ima->id); | const char *relbase = ID_BLEND_PATH(opts->bmain, &ima->id); | ||||
| BLI_path_rel(ima->name, relbase); /* only after saving */ | BLI_path_rel(ima->name, relbase); /* only after saving */ | ||||
| } | } | ||||
| ColorManagedColorspaceSettings old_colorspace_settings; | ColorManagedColorspaceSettings old_colorspace_settings; | ||||
| BKE_color_managed_colorspace_settings_copy(&old_colorspace_settings, &ima->colorspace_settings); | BKE_color_managed_colorspace_settings_copy(&old_colorspace_settings, &ima->colorspace_settings); | ||||
| IMB_colormanagement_colorspace_from_ibuf_ftype(&ima->colorspace_settings, ibuf); | IMB_colormanagement_colorspace_from_ibuf_ftype(&ima->colorspace_settings, ibuf); | ||||
| if (!BKE_color_managed_colorspace_settings_equals(&old_colorspace_settings, | if (!BKE_color_managed_colorspace_settings_equals(&old_colorspace_settings, | ||||
| &ima->colorspace_settings)) { | &ima->colorspace_settings) && | ||||
| !skip_post_signal) { | |||||
| BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_COLORMANAGE); | BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_COLORMANAGE); | ||||
| } | } | ||||
| } | } | ||||
| static void imbuf_save_post(ImBuf *ibuf, ImBuf *colormanaged_ibuf) | static void imbuf_save_post(ImBuf *ibuf, ImBuf *colormanaged_ibuf) | ||||
| { | { | ||||
| if (colormanaged_ibuf != ibuf) { | if (colormanaged_ibuf != ibuf) { | ||||
| /* This guys might be modified by image buffer write functions, | /* This guys might be modified by image buffer write functions, | ||||
| ▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | if (imf->views_format == R_IMF_VIEWS_STEREO_3D) { | ||||
| STEREO_RIGHT_NAME); | STEREO_RIGHT_NAME); | ||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| goto cleanup; | goto cleanup; | ||||
| } | } | ||||
| } | } | ||||
| BKE_imbuf_stamp_info(rr, ibuf); | BKE_imbuf_stamp_info(rr, ibuf); | ||||
| } | } | ||||
| /* In case of multiple UDIM tiles [which all get saved through image_save_single()] | |||||
| * avoid to send `IMA_SIGNAL_COLORMANAGE` (in case colorspaces differ) for each tile, so we dont | |||||
| * loose the image cache early, so only do for last tile. */ | |||||
| bool skip_post_signal = false; | |||||
| if (ima->source == IMA_SRC_TILED && !BLI_listbase_is_single(&ima->tiles)) { | |||||
| ImageTile *tile_last = ima->tiles.last; | |||||
| if (iuser->tile != tile_last->tile_number) { | |||||
| skip_post_signal = true; | |||||
| } | |||||
| } | |||||
brecht: It's not ideal to make assumptions about the calling function saving all UDIM tiles.
Instead I… | |||||
| /* fancy multiview OpenEXR */ | /* fancy multiview OpenEXR */ | ||||
| if (imf->views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) { | if (imf->views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) { | ||||
| /* save render result */ | /* save render result */ | ||||
| ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, NULL, layer); | 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, bmain, ima, ibuf, ok, opts, true, opts->filepath, skip_post_signal); | ||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| } | } | ||||
| /* regular mono pipeline */ | /* regular mono pipeline */ | ||||
| else if (is_mono) { | else if (is_mono) { | ||||
| if (is_exr_rr) { | if (is_exr_rr) { | ||||
| ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, NULL, layer); | ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, NULL, layer); | ||||
| } | } | ||||
| else { | else { | ||||
| colormanaged_ibuf = IMB_colormanagement_imbuf_for_write( | colormanaged_ibuf = IMB_colormanagement_imbuf_for_write( | ||||
| ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf); | ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf); | ||||
| ok = BKE_imbuf_write_as(colormanaged_ibuf, opts->filepath, imf, save_copy); | ok = BKE_imbuf_write_as(colormanaged_ibuf, opts->filepath, imf, save_copy); | ||||
| imbuf_save_post(ibuf, colormanaged_ibuf); | imbuf_save_post(ibuf, colormanaged_ibuf); | ||||
| } | } | ||||
| image_save_post( | image_save_post(reports, | ||||
| reports, bmain, ima, ibuf, ok, opts, (is_exr_rr ? true : save_copy), opts->filepath); | bmain, | ||||
| ima, | |||||
| ibuf, | |||||
| ok, | |||||
| opts, | |||||
| (is_exr_rr ? true : save_copy), | |||||
| opts->filepath, | |||||
| skip_post_signal); | |||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| } | } | ||||
| /* individual multiview images */ | /* individual multiview images */ | ||||
| else if (imf->views_format == R_IMF_VIEWS_INDIVIDUAL) { | else if (imf->views_format == R_IMF_VIEWS_INDIVIDUAL) { | ||||
| int i; | int i; | ||||
| unsigned char planes = ibuf->planes; | unsigned char planes = ibuf->planes; | ||||
| const int totviews = (rr ? BLI_listbase_count(&rr->views) : BLI_listbase_count(&ima->views)); | const int totviews = (rr ? BLI_listbase_count(&rr->views) : BLI_listbase_count(&ima->views)); | ||||
| if (!is_exr_rr) { | if (!is_exr_rr) { | ||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| } | } | ||||
| for (i = 0; i < totviews; i++) { | for (i = 0; i < totviews; i++) { | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| bool ok_view = false; | bool ok_view = false; | ||||
| const char *view = rr ? ((RenderView *)BLI_findlink(&rr->views, i))->name : | const char *view = rr ? ((RenderView *)BLI_findlink(&rr->views, i))->name : | ||||
| ((ImageView *)BLI_findlink(&ima->views, i))->name; | ((ImageView *)BLI_findlink(&ima->views, i))->name; | ||||
| if (is_exr_rr) { | if (is_exr_rr) { | ||||
| BKE_scene_multiview_view_filepath_get(&opts->scene->r, opts->filepath, view, filepath); | BKE_scene_multiview_view_filepath_get(&opts->scene->r, opts->filepath, view, filepath); | ||||
| ok_view = RE_WriteRenderResult(reports, rr, filepath, imf, view, layer); | 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, bmain, ima, ibuf, ok_view, opts, true, filepath, skip_post_signal); | |||||
| } | } | ||||
| else { | else { | ||||
| /* copy iuser to get the correct ibuf for this view */ | /* copy iuser to get the correct ibuf for this view */ | ||||
| ImageUser view_iuser; | ImageUser view_iuser; | ||||
| if (iuser) { | if (iuser) { | ||||
| /* copy iuser to get the correct ibuf for this view */ | /* copy iuser to get the correct ibuf for this view */ | ||||
| view_iuser = *iuser; | view_iuser = *iuser; | ||||
| Show All 16 Lines | for (i = 0; i < totviews; i++) { | ||||
| ibuf->planes = planes; | ibuf->planes = planes; | ||||
| BKE_scene_multiview_view_filepath_get(&opts->scene->r, opts->filepath, view, filepath); | BKE_scene_multiview_view_filepath_get(&opts->scene->r, opts->filepath, view, filepath); | ||||
| colormanaged_ibuf = IMB_colormanagement_imbuf_for_write( | colormanaged_ibuf = IMB_colormanagement_imbuf_for_write( | ||||
| ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf); | 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); | ok_view = BKE_imbuf_write_as(colormanaged_ibuf, filepath, &opts->im_format, save_copy); | ||||
| imbuf_save_post(ibuf, colormanaged_ibuf); | imbuf_save_post(ibuf, colormanaged_ibuf); | ||||
| image_save_post(reports, bmain, ima, ibuf, ok_view, opts, true, filepath); | image_save_post( | ||||
| reports, bmain, ima, ibuf, ok_view, opts, true, filepath, skip_post_signal); | |||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| } | } | ||||
| ok &= ok_view; | ok &= ok_view; | ||||
| } | } | ||||
| if (is_exr_rr) { | if (is_exr_rr) { | ||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| } | } | ||||
| } | } | ||||
| /* stereo (multiview) images */ | /* stereo (multiview) images */ | ||||
| else if (opts->im_format.views_format == R_IMF_VIEWS_STEREO_3D) { | else if (opts->im_format.views_format == R_IMF_VIEWS_STEREO_3D) { | ||||
| if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) { | if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) { | ||||
| ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, NULL, layer); | 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, bmain, ima, ibuf, ok, opts, true, opts->filepath, skip_post_signal); | ||||
| BKE_image_release_ibuf(ima, ibuf, lock); | BKE_image_release_ibuf(ima, ibuf, lock); | ||||
| } | } | ||||
| else { | else { | ||||
| ImBuf *ibuf_stereo[2] = {NULL}; | ImBuf *ibuf_stereo[2] = {NULL}; | ||||
| unsigned char planes = ibuf->planes; | unsigned char planes = ibuf->planes; | ||||
| const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; | const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; | ||||
| int i; | int i; | ||||
| ▲ Show 20 Lines • Show All 122 Lines • Show Last 20 Lines | |||||
It's not ideal to make assumptions about the calling function saving all UDIM tiles.
Instead I would add a bool *colorspace_changed parameter to image_save_single and image_save_post, which can then be used by BKE_image_save to determine if it should call BKE_image_signal.