libgimp: clean up the GimpImage's metadata API.

gimp_image_metadata_load_prepare(), gimp_image_metadata_load_finish()
and gimp_image_metadata_save_finish() are only ever used internally now,
so there is no need to expose them.

If we realize that we need them as public functions later, or someone
reports a valid use case, we can always bring them back later.

Also improves a bit various annotations.
This commit is contained in:
Jehan 2024-09-28 14:49:41 +02:00
parent aa2527843b
commit 68ee943200
9 changed files with 173 additions and 191 deletions

View file

@ -484,11 +484,8 @@ EXPORTS
gimp_image_lower_item_to_bottom gimp_image_lower_item_to_bottom
gimp_image_merge_down gimp_image_merge_down
gimp_image_merge_visible_layers gimp_image_merge_visible_layers
gimp_image_metadata_load_finish
gimp_image_metadata_load_prepare
gimp_image_metadata_load_thumbnail gimp_image_metadata_load_thumbnail
gimp_image_metadata_save_filter gimp_image_metadata_save_filter
gimp_image_metadata_save_finish
gimp_image_metadata_save_prepare gimp_image_metadata_save_prepare
gimp_image_new gimp_image_new
gimp_image_new_with_precision gimp_image_new_with_precision

View file

@ -57,23 +57,31 @@ static GList* gimp_image_metadata_set_xmp_structs (GList
* gimp_image_metadata_save_prepare: * gimp_image_metadata_save_prepare:
* @image: The original image * @image: The original image
* @mime_type: The saved file's mime-type * @mime_type: The saved file's mime-type
* @suggested_flags: Suggested default values for the @flags passed to * @suggested_flags: Suggested default values for the metadata to export.
* gimp_image_metadata_save_finish()
* *
* Gets the image metadata for saving it using * Gets the image metadata for storing it in an exported file.
* gimp_image_metadata_save_finish().
* *
* The @suggested_flags are determined from what kind of metadata * *Note: There is normally no need to call this function because it's
* (Exif, XMP, ...) is actually present in the image and the preferences * already called by [class@ExportProcedure] at the start and the
* for metadata exporting. * metadata is passed to the `run()` callback.*
* The calling application may still update @available_flags, for *
* *You may call it separately for instance if you set @export_metadata
* to %NULL in [ctor@Gimp.ExportProcedure.new] to prevent `libgimp`
* from trying to store the metadata in the exported file, yet you wish
* to process and store the metadata yourself using custom API.*
*
* The @suggested_flags are determined from what kind of metadata (Exif,
* XMP, ...) is actually present in the image and the preferences for
* metadata exporting.
* The calling application may still ignore @suggested_flags, for
* instance to follow the settings from a previous export in the same * instance to follow the settings from a previous export in the same
* session, or a previous export of the same image. But it should not * session, or a previous export of the same image. But it should not
* override the preferences without a good reason since it is a data * override the preferences without a good reason since it is a data
* leak. * leak.
* *
* The suggested value for %GIMP_METADATA_SAVE_THUMBNAIL is determined by * The suggested value for [flags@Gimp.MetadataSaveFlags.THUMBNAIL] is
* whether there was a thumbnail in the previously imported image. * determined by whether there was a thumbnail in the previously
* imported image.
* *
* Returns: (transfer full): The image's metadata, prepared for saving. * Returns: (transfer full): The image's metadata, prepared for saving.
* *
@ -644,19 +652,24 @@ gimp_image_metadata_set_xmp_structs (GList *xmp_list,
* @error: Return location for error message * @error: Return location for error message
* *
* Filters the @metadata retrieved from the image with * Filters the @metadata retrieved from the image with
* gimp_image_metadata_save_prepare(), * [method@Gimp.Image.metadata_save_prepare], taking into account the
* taking into account the passed @flags. * passed @flags.
*
* *Note: There is normally no need to call this function because it's
* already called by [class@ExportProcedure] after the `run()`
* callback.*
* *
* Note that the @image passed to this function might be different * Note that the @image passed to this function might be different
* from the image passed to gimp_image_metadata_save_prepare(), due * from the image passed to `gimp_image_metadata_save_prepare()`, due
* to whatever file export conversion happened in the meantime * to whatever file export conversion happened in the meantime
* *
* This is an alternative to gimp_image_metadata_save_finish when you * This can be used as an alternative to core metadata handling when you
* want to save metadata yourself and you need only filtering processing. * want to save metadata yourself and you need only filtering
* processing.
* *
* Returns: (transfer full): Filtered metadata or NULL in case of failure. * Returns: (transfer full): Filtered metadata or %NULL in case of failure.
* * Use [GObject.Object.unref] when returned metadata are no
* Use g_object_unref() when returned metadata are no longer needed * longer needed
* *
* Since: 3.0 * Since: 3.0
*/ */
@ -1008,8 +1021,11 @@ gimp_image_metadata_save_filter (GimpImage *image,
return new_metadata; return new_metadata;
} }
/* Internal functions */
/** /**
* gimp_image_metadata_save_finish: * _gimp_image_metadata_save_finish:
* @image: The actually saved image * @image: The actually saved image
* @mime_type: The saved file's mime-type * @mime_type: The saved file's mime-type
* @metadata: The metadata to write to @file * @metadata: The metadata to write to @file
@ -1017,25 +1033,28 @@ gimp_image_metadata_save_filter (GimpImage *image,
* @file: The file @image was saved to * @file: The file @image was saved to
* @error: Return location for error message * @error: Return location for error message
* *
* *Note: There is normally no need to call this function because it's
* already called by [class@ExportProcedure] at the end of the `run()` callback.*
*
* Saves the @metadata retrieved from the image with * Saves the @metadata retrieved from the image with
* gimp_image_metadata_save_prepare() to @file, taking into account * [method@Gimp.Image.metadata_save_prepare] to @file, taking into
* the passed @flags. * account the passed @flags.
* *
* Note that the @image passed to this function might be different * Note that the @image passed to this function might be different
* from the image passed to gimp_image_metadata_save_prepare(), due * from the image passed to `gimp_image_metadata_save_prepare()`, due to
* to whatever file export conversion happened in the meantime * whatever file export conversion happened in the meantime
* *
* Returns: Whether the save was successful. * Returns: Whether the save was successful.
* *
* Since: 2.10 * Since: 2.10
*/ */
gboolean gboolean
gimp_image_metadata_save_finish (GimpImage *image, _gimp_image_metadata_save_finish (GimpImage *image,
const gchar *mime_type, const gchar *mime_type,
GimpMetadata *metadata, GimpMetadata *metadata,
GimpMetadataSaveFlags flags, GimpMetadataSaveFlags flags,
GFile *file, GFile *file,
GError **error) GError **error)
{ {
GimpMetadata *new_metadata; GimpMetadata *new_metadata;
gboolean success = FALSE; gboolean success = FALSE;

View file

@ -38,38 +38,6 @@ static void gimp_image_metadata_rotate (GimpImage *
/* public functions */ /* public functions */
/**
* gimp_image_metadata_load_prepare:
* @image: The image
* @mime_type: The loaded file's mime-type
* @file: The file to load the metadata from
* @error: Return location for error
*
* Loads and returns metadata from @file to be passed into
* gimp_image_metadata_load_finish().
*
* Returns: (transfer full): The file's metadata.
*
* Since: 2.10
*/
GimpMetadata *
gimp_image_metadata_load_prepare (GimpImage *image,
const gchar *mime_type,
GFile *file,
GError **error)
{
GimpMetadata *metadata;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (mime_type != NULL, NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
metadata = gimp_metadata_load_from_file (file, error);
return metadata;
}
static gchar * static gchar *
gimp_image_metadata_interpret_comment (gchar *comment) gimp_image_metadata_interpret_comment (gchar *comment)
{ {
@ -102,23 +70,96 @@ gimp_image_metadata_interpret_comment (gchar *comment)
} }
/** /**
* gimp_image_metadata_load_finish: * gimp_image_metadata_load_thumbnail:
* @file: A #GFile image
* @error: Return location for error message
*
* Retrieves a thumbnail from metadata if present.
*
* Returns: (transfer none) (nullable): a #GimpImage of the @file thumbnail.
*
* Since: 2.10
*/
GimpImage *
gimp_image_metadata_load_thumbnail (GFile *file,
GError **error)
{
GimpMetadata *metadata;
GInputStream *input_stream;
GdkPixbuf *pixbuf;
guint8 *thumbnail_buffer;
gint thumbnail_size;
GimpImage *image = NULL;
g_return_val_if_fail (G_IS_FILE (file), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
metadata = gimp_metadata_load_from_file (file, error);
if (! metadata)
return NULL;
if (! gexiv2_metadata_get_exif_thumbnail (GEXIV2_METADATA (metadata),
&thumbnail_buffer,
&thumbnail_size))
{
g_object_unref (metadata);
return NULL;
}
input_stream = g_memory_input_stream_new_from_data (thumbnail_buffer,
thumbnail_size,
(GDestroyNotify) g_free);
pixbuf = gdk_pixbuf_new_from_stream (input_stream, NULL, error);
g_object_unref (input_stream);
if (pixbuf)
{
GimpLayer *layer;
image = gimp_image_new (gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf),
GIMP_RGB);
gimp_image_undo_disable (image);
layer = gimp_layer_new_from_pixbuf (image, _("Background"),
pixbuf,
100.0,
gimp_image_get_default_new_layer_mode (image),
0.0, 0.0);
g_object_unref (pixbuf);
gimp_image_insert_layer (image, layer, NULL, 0);
gimp_image_metadata_rotate (image,
gexiv2_metadata_try_get_orientation (GEXIV2_METADATA (metadata), NULL));
}
g_object_unref (metadata);
return image;
}
/* Internal functions */
/**
* _gimp_image_metadata_load_finish:
* @image: The image * @image: The image
* @mime_type: The loaded file's mime-type * @mime_type: The loaded file's mime-type
* @metadata: The metadata to set on the image * @metadata: The metadata to set on the image
* @flags: Flags to specify what of the metadata to apply to the image * @flags: Flags to specify what of the metadata to apply to the image
* *
* Applies the @metadata previously loaded with * Applies the @metadata previously loaded with
* gimp_image_metadata_load_prepare() to the image, taking into account * gimp_metadata_load_from_file() to the image, taking into account
* the passed @flags. * the passed @flags.
* *
* Since: 3.0 * Since: 3.0
*/ */
void void
gimp_image_metadata_load_finish (GimpImage *image, _gimp_image_metadata_load_finish (GimpImage *image,
const gchar *mime_type, const gchar *mime_type,
GimpMetadata *metadata, GimpMetadata *metadata,
GimpMetadataLoadFlags flags) GimpMetadataLoadFlags flags)
{ {
g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (GEXIV2_IS_METADATA (metadata)); g_return_if_fail (GEXIV2_IS_METADATA (metadata));
@ -274,76 +315,6 @@ gimp_image_metadata_load_finish (GimpImage *image,
gimp_image_set_metadata (image, metadata); gimp_image_set_metadata (image, metadata);
} }
/**
* gimp_image_metadata_load_thumbnail:
* @file: A #GFile image
* @error: Return location for error message
*
* Retrieves a thumbnail from metadata if present.
*
* Returns: (transfer none) (nullable): a #GimpImage of the @file thumbnail.
*
* Since: 2.10
*/
GimpImage *
gimp_image_metadata_load_thumbnail (GFile *file,
GError **error)
{
GimpMetadata *metadata;
GInputStream *input_stream;
GdkPixbuf *pixbuf;
guint8 *thumbnail_buffer;
gint thumbnail_size;
GimpImage *image = NULL;
g_return_val_if_fail (G_IS_FILE (file), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
metadata = gimp_metadata_load_from_file (file, error);
if (! metadata)
return NULL;
if (! gexiv2_metadata_get_exif_thumbnail (GEXIV2_METADATA (metadata),
&thumbnail_buffer,
&thumbnail_size))
{
g_object_unref (metadata);
return NULL;
}
input_stream = g_memory_input_stream_new_from_data (thumbnail_buffer,
thumbnail_size,
(GDestroyNotify) g_free);
pixbuf = gdk_pixbuf_new_from_stream (input_stream, NULL, error);
g_object_unref (input_stream);
if (pixbuf)
{
GimpLayer *layer;
image = gimp_image_new (gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf),
GIMP_RGB);
gimp_image_undo_disable (image);
layer = gimp_layer_new_from_pixbuf (image, _("Background"),
pixbuf,
100.0,
gimp_image_get_default_new_layer_mode (image),
0.0, 0.0);
g_object_unref (pixbuf);
gimp_image_insert_layer (image, layer, NULL, 0);
gimp_image_metadata_rotate (image,
gexiv2_metadata_try_get_orientation (GEXIV2_METADATA (metadata), NULL));
}
g_object_unref (metadata);
return image;
}
/* private functions */ /* private functions */

View file

@ -31,15 +31,6 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */ /* For information look into the C source or the html documentation */
GimpMetadata * gimp_image_metadata_load_prepare (GimpImage *image,
const gchar *mime_type,
GFile *file,
GError **error);
void gimp_image_metadata_load_finish (GimpImage *image,
const gchar *mime_type,
GimpMetadata *metadata,
GimpMetadataLoadFlags flags);
GimpMetadata * gimp_image_metadata_save_prepare (GimpImage *image, GimpMetadata * gimp_image_metadata_save_prepare (GimpImage *image,
const gchar *mime_type, const gchar *mime_type,
GimpMetadataSaveFlags *suggested_flags); GimpMetadataSaveFlags *suggested_flags);
@ -49,17 +40,26 @@ GimpMetadata * gimp_image_metadata_save_filter (GimpImage *image,
GimpMetadataSaveFlags flags, GimpMetadataSaveFlags flags,
GFile *file, GFile *file,
GError **error); GError **error);
gboolean gimp_image_metadata_save_finish (GimpImage *image,
const gchar *mime_type,
GimpMetadata *metadata,
GimpMetadataSaveFlags flags,
GFile *file,
GError **error);
GimpImage * gimp_image_metadata_load_thumbnail (GFile *file, GimpImage * gimp_image_metadata_load_thumbnail (GFile *file,
GError **error); GError **error);
/* for internal use only */
G_GNUC_INTERNAL void _gimp_image_metadata_load_finish (GimpImage *image,
const gchar *mime_type,
GimpMetadata *metadata,
GimpMetadataLoadFlags flags);
G_GNUC_INTERNAL gboolean _gimp_image_metadata_save_finish (GimpImage *image,
const gchar *mime_type,
GimpMetadata *metadata,
GimpMetadataSaveFlags flags,
GFile *file,
GError **error);
G_END_DECLS G_END_DECLS
#endif /* __GIMP_IMAGE_METADATA_H__ */ #endif /* __GIMP_IMAGE_METADATA_H__ */

View file

@ -280,7 +280,7 @@ gimp_load_procedure_run (GimpProcedure *procedure,
} }
if (image != NULL && metadata != NULL && flags != GIMP_METADATA_LOAD_NONE) if (image != NULL && metadata != NULL && flags != GIMP_METADATA_LOAD_NONE)
gimp_image_metadata_load_finish (image, NULL, metadata, flags); _gimp_image_metadata_load_finish (image, NULL, metadata, flags);
/* This is debug printing to help plug-in developers figure out best /* This is debug printing to help plug-in developers figure out best
* practices. * practices.

View file

@ -25,26 +25,25 @@
G_BEGIN_DECLS G_BEGIN_DECLS
void _gimp_procedure_config_get_values (GimpProcedureConfig *config, G_GNUC_INTERNAL void _gimp_procedure_config_get_values (GimpProcedureConfig *config,
GimpValueArray *values); GimpValueArray *values);
void _gimp_procedure_config_begin_run (GimpProcedureConfig *config, G_GNUC_INTERNAL void _gimp_procedure_config_begin_run (GimpProcedureConfig *config,
GimpImage *image, GimpImage *image,
GimpRunMode run_mode, GimpRunMode run_mode,
const GimpValueArray *args); const GimpValueArray *args);
void _gimp_procedure_config_end_run (GimpProcedureConfig *config, G_GNUC_INTERNAL void _gimp_procedure_config_end_run (GimpProcedureConfig *config,
GimpPDBStatusType status); GimpPDBStatusType status);
GimpMetadata * G_GNUC_INTERNAL GimpMetadata * _gimp_procedure_config_begin_export (GimpProcedureConfig *config,
_gimp_procedure_config_begin_export (GimpProcedureConfig *config, GimpImage *original_image,
GimpImage *original_image, GimpRunMode run_mode,
GimpRunMode run_mode, const GimpValueArray *args,
const GimpValueArray *args, const gchar *mime_type);
const gchar *mime_type); G_GNUC_INTERNAL void _gimp_procedure_config_end_export (GimpProcedureConfig *config,
void _gimp_procedure_config_end_export (GimpProcedureConfig *config, GimpImage *exported_image,
GimpImage *exported_image, GFile *file,
GFile *file, GimpPDBStatusType status);
GimpPDBStatusType status);
/* These 3 functions are not marked internal because they are used in libgimpui. /* These 3 functions are not marked internal because they are used in libgimpui.

View file

@ -367,16 +367,16 @@ gimp_procedure_config_set_parasite (GimpProcedureConfig *config,
* @exported_image: the image that was actually exported * @exported_image: the image that was actually exported
* @file: the file @exported_image was written to * @file: the file @exported_image was written to
* *
* Note: There is normally no need to call this function because it's * *Note: There is normally no need to call this function because it's
* already called by [class@ExportProcedure] at the end of the `run()` callback. * already called by [class@ExportProcedure] after the `run()` callback.*
* *
* Only use this function if the [class@Metadata] passed as argument of a * *Only use this function if the [class@Metadata] passed as argument of a
* [class@ExportProcedure]'s run() method needs to be written at a specific * [class@ExportProcedure]'s run() method needs to be written at a specific
* point of the export, other than its end. * point of the export, other than its end.*
* *
* This function syncs back @config's export properties to the * This function syncs back @config's export properties to the
* metadata's [flags@MetadataSaveFlags] and writes the metadata to @file * metadata's [flags@MetadataSaveFlags] and writes the metadata to
* using [method@Image.metadata_save_finish]. * @file.
* *
* The metadata is only ever written once. If this function has been * The metadata is only ever written once. If this function has been
* called explicitly, it will do nothing when called a second time at the end of * called explicitly, it will do nothing when called a second time at the end of
@ -426,11 +426,11 @@ gimp_procedure_config_save_metadata (GimpProcedureConfig *config,
} }
} }
if (! gimp_image_metadata_save_finish (exported_image, if (! _gimp_image_metadata_save_finish (exported_image,
priv->mime_type, priv->mime_type,
priv->metadata, priv->metadata,
priv->metadata_flags, priv->metadata_flags,
file, &error)) file, &error))
{ {
if (error) if (error)
{ {
@ -871,7 +871,7 @@ _gimp_procedure_config_begin_export (GimpProcedureConfig *config,
* and never enable them, so we don't override the user's * and never enable them, so we don't override the user's
* saved default values that are passed to us via "args" * saved default values that are passed to us via "args"
*/ */
if (! (metadata_flags & metadata_properties[i].flag)) if (! (metadata_flags & metadata_properties[i].flag))
{ {
const gchar *prop_name = metadata_properties[i].name; const gchar *prop_name = metadata_properties[i].name;
GParamSpec *pspec; GParamSpec *pspec;

View file

@ -454,7 +454,7 @@ gimp_vector_load_procedure_run (GimpProcedure *procedure,
} }
if (image != NULL && metadata != NULL && flags != GIMP_METADATA_LOAD_NONE) if (image != NULL && metadata != NULL && flags != GIMP_METADATA_LOAD_NONE)
gimp_image_metadata_load_finish (image, NULL, metadata, flags); _gimp_image_metadata_load_finish (image, NULL, metadata, flags);
/* This is debug printing to help plug-in developers figure out best /* This is debug printing to help plug-in developers figure out best
* practices. * practices.

View file

@ -43,10 +43,6 @@
* SECTION: gimpmetadata * SECTION: gimpmetadata
* @title: GimpMetadata * @title: GimpMetadata
* @short_description: Basic functions for handling #GimpMetadata objects. * @short_description: Basic functions for handling #GimpMetadata objects.
* @see_also: gimp_image_metadata_load_prepare(),
* gimp_image_metadata_load_finish(),
* gimp_image_metadata_save_prepare(),
* gimp_image_metadata_save_finish().
* *
* Basic functions for handling #GimpMetadata objects. * Basic functions for handling #GimpMetadata objects.
**/ **/