Fix T100281: image save after copy not using correct filepath

Always use the image datablock filepath for saving. The only apparent reason
use the image buffer file path is image sequences, for which the current frame
filepath is now computed.
This commit is contained in:
Brecht Van Lommel 2022-08-08 13:29:24 +02:00
parent 1382514bf2
commit 4b3315fc98
Notes: blender-bot 2023-02-14 09:03:55 +01:00
Referenced by issue #102421, Image.save() more heavy than original when using bpy
Referenced by issue #100281, Regression: Fail to save to right image via bpy when copying image
3 changed files with 28 additions and 25 deletions

View File

@ -237,11 +237,13 @@ void BKE_image_ensure_viewer_views(const struct RenderData *rd,
*/
void BKE_image_user_frame_calc(struct Image *ima, struct ImageUser *iuser, int cfra);
int BKE_image_user_frame_get(const struct ImageUser *iuser, int cfra, bool *r_is_in_range);
void BKE_image_user_file_path(struct ImageUser *iuser, struct Image *ima, char *path);
void BKE_image_user_file_path_ex(struct ImageUser *iuser,
struct Image *ima,
void BKE_image_user_file_path(const struct ImageUser *iuser, const struct Image *ima, char *path);
void BKE_image_user_file_path_ex(const struct Main *bmain,
const struct ImageUser *iuser,
const struct Image *ima,
char *path,
bool resolve_udim);
const bool resolve_udim,
const bool resolve_multiview);
void BKE_image_editors_update_frame(const struct Main *bmain, int cfra);
/**
@ -259,15 +261,15 @@ struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct Im
/**
* Sets index offset for multi-view files.
*/
void BKE_image_multiview_index(struct Image *ima, struct ImageUser *iuser);
void BKE_image_multiview_index(const struct Image *ima, struct ImageUser *iuser);
/**
* For multi-layer images as well as for render-viewer
* and because rendered results use fake layer/passes, don't correct for wrong indices here.
*/
bool BKE_image_is_multilayer(struct Image *ima);
bool BKE_image_is_multiview(struct Image *ima);
bool BKE_image_is_stereo(struct Image *ima);
bool BKE_image_is_multilayer(const struct Image *ima);
bool BKE_image_is_multiview(const struct Image *ima);
bool BKE_image_is_stereo(const 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);

View File

@ -785,7 +785,7 @@ bool BKE_image_has_opengl_texture(Image *ima)
return false;
}
static int image_get_tile_number_from_iuser(Image *ima, const ImageUser *iuser)
static int image_get_tile_number_from_iuser(const Image *ima, const ImageUser *iuser)
{
BLI_assert(ima != nullptr && ima->tiles.first);
ImageTile *tile = static_cast<ImageTile *>(ima->tiles.first);
@ -3562,7 +3562,7 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
return rpass;
}
void BKE_image_multiview_index(Image *ima, ImageUser *iuser)
void BKE_image_multiview_index(const Image *ima, ImageUser *iuser)
{
if (iuser) {
bool is_stereo = BKE_image_is_stereo(ima) && (iuser->flag & IMA_SHOW_STEREO);
@ -3583,7 +3583,7 @@ void BKE_image_multiview_index(Image *ima, ImageUser *iuser)
/* if layer or pass changes, we need an index for the imbufs list */
/* note it is called for rendered results, but it doesn't use the index! */
bool BKE_image_is_multilayer(Image *ima)
bool BKE_image_is_multilayer(const Image *ima)
{
if (ELEM(ima->source, IMA_SRC_FILE, IMA_SRC_SEQUENCE, IMA_SRC_TILED)) {
if (ima->type == IMA_TYPE_MULTILAYER) {
@ -3598,13 +3598,13 @@ bool BKE_image_is_multilayer(Image *ima)
return false;
}
bool BKE_image_is_multiview(Image *ima)
bool BKE_image_is_multiview(const Image *ima)
{
ImageView *view = static_cast<ImageView *>(ima->views.first);
return (view && (view->next || view->name[0]));
}
bool BKE_image_is_stereo(Image *ima)
bool BKE_image_is_stereo(const Image *ima)
{
return BKE_image_is_multiview(ima) &&
(BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) &&
@ -5002,14 +5002,19 @@ void BKE_image_user_id_eval_animation(Depsgraph *depsgraph, ID *id)
image_walk_id_all_users(id, skip_nested_nodes, depsgraph, image_user_id_eval_animation);
}
void BKE_image_user_file_path(ImageUser *iuser, Image *ima, char *filepath)
void BKE_image_user_file_path(const ImageUser *iuser, const Image *ima, char *filepath)
{
BKE_image_user_file_path_ex(iuser, ima, filepath, true);
BKE_image_user_file_path_ex(G_MAIN, iuser, ima, filepath, true, true);
}
void BKE_image_user_file_path_ex(ImageUser *iuser, Image *ima, char *filepath, bool resolve_udim)
void BKE_image_user_file_path_ex(const Main *bmain,
const ImageUser *iuser,
const Image *ima,
char *filepath,
const bool resolve_udim,
const bool resolve_multiview)
{
if (BKE_image_is_multiview(ima)) {
if (resolve_multiview && BKE_image_is_multiview(ima)) {
ImageView *iv = static_cast<ImageView *>(BLI_findlink(&ima->views, iuser->view));
if (iv->filepath[0]) {
BLI_strncpy(filepath, iv->filepath, FILE_MAX);
@ -5042,7 +5047,7 @@ void BKE_image_user_file_path_ex(ImageUser *iuser, Image *ima, char *filepath, b
}
}
BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&ima->id));
BLI_path_abs(filepath, ID_BLEND_PATH(bmain, &ima->id));
}
bool BKE_image_has_alpha(Image *image)

View File

@ -144,13 +144,9 @@ bool BKE_image_save_options_init(ImageSaveOptions *opts,
opts->im_format.color_management = R_IMF_COLOR_MANAGEMENT_FOLLOW_SCENE;
if (ibuf->name[0] == '\0' || ima->source == IMA_SRC_TILED) {
BLI_strncpy(opts->filepath, ima->filepath, sizeof(opts->filepath));
BLI_path_abs(opts->filepath, ID_BLEND_PATH_FROM_GLOBAL(&ima->id));
}
else {
BLI_strncpy(opts->filepath, ibuf->name, sizeof(opts->filepath));
}
/* Compute filepath, but don't resolve multiview and UDIM which are handled
* by the image saving code itself. */
BKE_image_user_file_path_ex(bmain, iuser, ima, opts->filepath, false, false);
/* sanitize all settings */