From 3211ab140832adefebb45377298f217317410f7c Mon Sep 17 00:00:00 2001 From: Jacob Boerema Date: Wed, 13 Aug 2025 11:34:12 -0400 Subject: [PATCH] libgimp: fix #14644 Wrong comment synchronized with metadata On export, when synchronizing the comment with the metadata equivalents, we did not consider that the comment could have been changed in the export dialog comment field. In fact, we already updated the metadata before that happened in gimp_image_metadata_save_prepare. To fix that - We remove it from the above mentioned function, since that is too early. - Add the (possibly) updated comment to the exported_image as a comment parasite so that we can access the updated value, but only when synchronizing metadata is allowed, and saving comments is enabled. - Synchronize the comment, taken from the parasite, with its metadata counterparts in gimp_image_metadata_save_filter, but only when synchronizing is allowed and saving comments is enabled. Note that due to this the synchronized metadata comments are only visible in the exported file. The metadata in the opened image is not updated. --- libgimp/gimpimagemetadata-save.c | 83 +++++++++++++++++--------------- libgimp/gimpprocedureconfig.c | 28 +++++++++++ 2 files changed, 73 insertions(+), 38 deletions(-) diff --git a/libgimp/gimpimagemetadata-save.c b/libgimp/gimpimagemetadata-save.c index d639685917..75e7471cce 100644 --- a/libgimp/gimpimagemetadata-save.c +++ b/libgimp/gimpimagemetadata-save.c @@ -106,8 +106,6 @@ gimp_image_metadata_save_prepare (GimpImage *image, if (metadata) { GDateTime *datetime; - GimpParasite *comment_parasite; - gchar *comment = NULL; gint image_width; gint image_height; gdouble xres; @@ -121,17 +119,6 @@ gimp_image_metadata_save_prepare (GimpImage *image, datetime = g_date_time_new_now_local (); - comment_parasite = gimp_image_get_parasite (image, "gimp-comment"); - if (comment_parasite) - { - guint32 parasite_size; - - comment = (gchar *) gimp_parasite_get_data (comment_parasite, ¶site_size); - comment = g_strndup (comment, parasite_size); - - gimp_parasite_free (comment_parasite); - } - if (! gimp_update_metadata ()) *suggested_flags &= ~GIMP_METADATA_SAVE_UPDATE; @@ -143,29 +130,6 @@ gimp_image_metadata_save_prepare (GimpImage *image, if (gimp_update_metadata ()) { - if (comment) - { - gexiv2_metadata_try_set_tag_string (g2metadata, - "Exif.Photo.UserComment", - comment, &error); - if (error) - { - g_warning ("%s: failed to set metadata '%s': %s\n", - G_STRFUNC, "Exif.Photo.UserComment", error->message); - g_clear_error (&error); - } - - gexiv2_metadata_try_set_tag_string (g2metadata, - "Exif.Image.ImageDescription", - comment, &error); - if (error) - { - g_warning ("%s: failed to set metadata '%s': %s\n", - G_STRFUNC, "Exif.Image.ImageDescription", error->message); - g_clear_error (&error); - } - } - g_snprintf (buffer, sizeof (buffer), "%d:%02d:%02d %02d:%02d:%02d", g_date_time_get_year (datetime), @@ -291,7 +255,6 @@ gimp_image_metadata_save_prepare (GimpImage *image, g_free (datetime_buf); g_date_time_unref (datetime); - g_clear_pointer (&comment, g_free); /* EXIF Thumbnail */ @@ -737,7 +700,51 @@ gimp_image_metadata_save_filter (GimpImage *image, if ((flags & GIMP_METADATA_SAVE_EXIF) && support_exif) { - gchar **exif_data = gexiv2_metadata_get_exif_tags (GEXIV2_METADATA (metadata)); + gchar **exif_data = NULL; + + if (gimp_update_metadata () && (flags & GIMP_METADATA_SAVE_COMMENT)) + { + GimpParasite *comment_parasite; + + comment_parasite = gimp_image_get_parasite (image, "gimp-comment"); + if (comment_parasite) + { + guint32 parasite_size; + gchar *comment = NULL; + + comment = (gchar *) gimp_parasite_get_data (comment_parasite, ¶site_size); + comment = g_strndup (comment, parasite_size); + + gimp_parasite_free (comment_parasite); + + if (comment) + { + gexiv2_metadata_try_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Photo.UserComment", + comment, &code_error); + if (code_error) + { + g_warning ("%s: failed to set metadata '%s': %s\n", + G_STRFUNC, "Exif.Photo.UserComment", code_error->message); + g_clear_error (&code_error); + } + + gexiv2_metadata_try_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Image.ImageDescription", + comment, &code_error); + if (code_error) + { + g_warning ("%s: failed to set metadata '%s': %s\n", + G_STRFUNC, "Exif.Image.ImageDescription", code_error->message); + g_clear_error (&code_error); + } + + g_free (comment); + } + } + } + + exif_data = gexiv2_metadata_get_exif_tags (GEXIV2_METADATA (metadata)); for (i = 0; exif_data[i] != NULL; i++) { diff --git a/libgimp/gimpprocedureconfig.c b/libgimp/gimpprocedureconfig.c index 0769fe874f..e14dbc7e93 100644 --- a/libgimp/gimpprocedureconfig.c +++ b/libgimp/gimpprocedureconfig.c @@ -426,6 +426,34 @@ gimp_procedure_config_save_metadata (GimpProcedureConfig *config, } } + if (gimp_update_metadata () && + (priv->metadata_flags & GIMP_METADATA_SAVE_COMMENT)) + { + gchar *comment_value = NULL; + gint len; + + /* To be able to synchronize the comment with metadata in + * _gimp_image_metadata_save_finish, we need the comment value + * that was possibly updated in the export dialog. + */ + + g_object_get (config, + "gimp-comment", &comment_value, + NULL); + if (comment_value && (len = strlen (comment_value)) > 0) + { + GimpParasite *parasite; + + parasite = gimp_parasite_new ("gimp-comment", + GIMP_PARASITE_PERSISTENT, + len + 1, comment_value); + + gimp_image_attach_parasite (exported_image, parasite); + gimp_parasite_free (parasite); + } + g_free (comment_value); + } + if (! _gimp_image_metadata_save_finish (exported_image, priv->mime_type, priv->metadata,