/* This file is part of GEGL * * GEGL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * GEGL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with GEGL; if not, see . * * Copyright 2020 Brian Stafford */ #ifndef __GEGL_METADATA_STORE_H__ #define __GEGL_METADATA_STORE_H__ #include #include "gegl-metadata.h" G_BEGIN_DECLS #define GEGL_TYPE_METADATA_STORE gegl_metadata_store_get_type () G_DECLARE_DERIVABLE_TYPE ( GeglMetadataStore, gegl_metadata_store, GEGL, METADATA_STORE, GObject ) /** * SECTION:gegl-metadatastore * @title: GeglMetadataStore * @short_description: A metadata store base class for use with file modules. * @see_also: #GeglMetadata #GeglMetadataHash * * #GeglMetadataStore is a non-instantiable base class implementing the * #GeglMetadata interface and provides methods for metadata access using * well-known names. For consistency with other #GObject features, the naming * convention for metadata variables is the same as for GObject properties. * * Methods are provided allowing the application to test whether a particular * metadata item has a value and to set or get the values. If a metadata value * does not exist, a GLib warning is printed. The * gegl_metadata_store_has_value() method can be used to test silently for * unset variables. * * Signals are provided to allow an application to intercept metadata values * from file modules, for example a Jpeg comment block might be parsed to set * multiple metadata values, or multiple values may be formatted into the * comment block. * * Image resolution and resolution units are accessible only as properties. * Well-known metatdata values are shadowed by properties to allow applications * to take advantage of features such as introspection and property binding. * * #GeglMetadataStore does not itself implement the storage mechanism, it must * be subclassed to provide this. #GeglMetadataHash implements a store using a * hash table. For convenience gegl_metadata_hash_new() casts its return value * to #GeglMetadataStore as it does not add any new methods or properties. */ /** * GeglMetadataStoreClass: * @_declare: The _declare virtual method creates a metadata variable in the * underlying data store. It implements gegl_metadata_store_declare(). A * #GParamSpec is used to describe the variable. If the metadata shadows an * object property, shadow should be %TRUE, otherwise %FALSE. It is acceptable * for a subclass to provide additional variables which are implicitly * declared, that is, they need not be declared using * gegl_metadata_store_declare(), however the @pspec method must still retrieve * a #GParamSpec describing such variables. This method MUST be provided by * the subclass. * @pspec: The pspec virtual method returns the #GParamSpec used to declare a * metadata variable. It is used to implement * gegl_metadata_store_typeof_value(). This method MUST be provided by the * subclass. * @has_value: The has_value virtual method implements * gegl_metadata_store_has_value() It should return %TRUE if the variable is * declared and contains a valid value of the correct type, otherwise %FALSE. * This method MUST be provided by the subclass. * @set_value: Set a metadata variable using a #GValue. Implements * gegl_metadata_store_set_value(). The metadata variable should be declared * and the #GValue must be of the correct type. Note that failure to set a * variable may be dependent of properties of the underlying storage mechanism. * This method MUST be provided by the subclass. * @_get_value: Return a pointer to a #GValue with the value of the metadata * variable or %NULL if not declared or the variable does not contain a valid * value. Implements gegl_metadata_store_get_value(). This method MUST be * provided by the subclass. * @register_hook: This method is called after a file loader or saver registers * a #GeglMetadataMap and before any further processing takes place. It is * intended to allow an application to create further application-specific * mappings using gegl_metadata_store_register(). #GeglMetadataStore provides * a default method which emits the `::mapped` signal. * @parse_value: This method is called to optionally parse image file metadata * prior to setting metadata variables in the #GeglMetadataStore. If no parser * is available it returns %FALSE and the registered mapping is used. If a * parser available it should set one or more metadata variables using * gegl_metadata_store_set_value() and return %TRUE. Note that the parser MUST * return %TRUE even if setting individual values fails. The default method * checks if a signal handler is registered for the parse-value signal with * the variable name as the detail parameter. If a handler is registered it * emits the signal with the file metadata provided as a #GValue and returns * %TRUE otherwise %FALSE. * @generate_value: This method is called to optionally generate a value to be * written to and image file. If no generator is available it returns %FALSE * and the registered mapping is used. If a generator is available it should * create a suitable value to be written to the image file and return %TRUE. * The default method checks if a signal handler is registered for the * generate-value signal with the variable name as the detail parameter. If a * handler is registered it emits the signal with an initialised #GValue to * receive the file metadata and returns %TRUE otherwise %FALSE. @parse_value * and @generate_value are provided to handle the case where some file formats * overload, for example, image comments. A typical case is formatting many * values into a TIFF file's ImageDescription field. * * The class structure for the #GeglMetadataStore */ struct _GeglMetadataStoreClass { /*< private >*/ GObjectClass parent_class; /*< public >*/ /* Subclass MUST provide the following */ void (*_declare) (GeglMetadataStore *self, GParamSpec *pspec, gboolean shadow); GParamSpec *(*pspec) (GeglMetadataStore *self, const gchar *name); void (*set_value) (GeglMetadataStore *self, const gchar *name, const GValue *value); const GValue *(*_get_value) (GeglMetadataStore *self, const gchar *name); gboolean (*has_value) (GeglMetadataStore *self, const gchar *name); /* Subclass MAY provide the following */ void (*register_hook) (GeglMetadataStore *self, const gchar *file_module_name, guint flags); gboolean (*parse_value) (GeglMetadataStore *self, GParamSpec *pspec, GValueTransform transform, const GValue *value); gboolean (*generate_value) (GeglMetadataStore *self, GParamSpec *pspec, GValueTransform transform, GValue *value); /*< private >*/ gpointer padding[4]; }; /** * GeglMetadataStore::changed: * @self: The #GeglMetadataStore emitting the signal * @pspec: A #GParamSpec declaring the metadata value * * `::changed` is emitted when a metadata value is changed. This is analogous * to the `GObject::notify` signal. */ /** * GeglMetadataStore::mapped: * @self: The #GeglMetadataStore emitting the signal * @file_module: The file module name * @exclude_unmapped: %TRUE if the file module cannot handle unmapped values * * `::mapped` is emitted after a file module registers a mapping and before * other processing takes place. An application may respond to the signal by * registering additional mappings or overriding existing values, for example * it might override the TIFF ImageDescription tag to format multiple metadata * values into the description. */ /** * GeglMetadataStore::unmapped: * @self: The #GeglMetadataStore emitting the signal * @file_module: The file module name * @local_name: The unmapped metadata name as used by the file module * * `::unmapped` is emitted when a file module tries to look up an unmapped * metadata name. When the handler returns a second attempt is made to look * up the metadata. */ /** * GeglMetadataStore::generate-value: * @self: The #GeglMetadataStore emitting the signal * @pspec: A #GParamSpec declaring the metadata value * @value: (inout): An initialised #GValue. * * If a signal handler is connected to `::generate-value` a signal is emitted * when the file module accesses a value using gegl_metadata_get_value(). * The signal handler must generate a value of the type specified in the pspec * argument. The signal handler's return value indicates the success of the * operation. * * If no handler is connected the mapped metadata value is accessed normally, * * Returns: %TRUE if a value is generated successfully. */ /** * GeglMetadataStore::parse-value: * @self: The #GeglMetadataStore emitting the signal * @pspec: A #GParamSpec declaring the metadata value * @value: (inout): A #GValue containing the value to parse. * * If a signal handler is connected to `::parse-value` a signal is emitted when * the file module accesses a value using gegl_metadata_set_value(). The * signal handler should parse the value supplied in the #GValue and may set * any number of metadata values using gegl_metadata_store_set_value(). * * If no handler is connected the mapped metadata value is set normally, * * Returns: %TRUE if parsing is successful. */ /** * GeglMetadataStore:resolution-unit: * * A #GeglResolutionUnit specifying units for the image resolution (density). */ /** * gegl_metadata_store_set_resolution_unit: * @self: A #GeglMetadataStore * @unit: Units as a #GeglResolutionUnit * * Set the units used for the resolution (density) values. */ void gegl_metadata_store_set_resolution_unit (GeglMetadataStore *self, GeglResolutionUnit unit); /** * gegl_metadata_store_get_resolution_unit: * @self: A #GeglMetadataStore * * Get the units used for resolution. * * Returns: a #GeglResolutionUnit. */ GeglResolutionUnit gegl_metadata_store_get_resolution_unit (GeglMetadataStore *self); /** * GeglMetadataStore:resolution-x: * * X resolution or density in dots per unit. */ /** * gegl_metadata_store_set_resolution_x: * @self: A #GeglMetadataStore * @resolution_x: X resolution or density * * Set the X resolution or density in dots per unit. */ void gegl_metadata_store_set_resolution_x (GeglMetadataStore *self, gdouble resolution_x); /** * gegl_metadata_store_get_resolution_x: * @self: A #GeglMetadataStore * * Get the X resolution or density in dots per unit. * * Returns: X resolution */ gdouble gegl_metadata_store_get_resolution_x (GeglMetadataStore *self); /** * GeglMetadataStore:resolution-y: * * Y resolution or density in dots per unit. */ /** * gegl_metadata_store_set_resolution_y: * @self: A #GeglMetadataStore * @resolution_y: Y resolution or density * * Set the Y resolution or density in dots per unit. */ void gegl_metadata_store_set_resolution_y (GeglMetadataStore *self, gdouble resolution_y); /** * gegl_metadata_store_get_resolution_y: * @self: A #GeglMetadataStore * * Get the Y resolution or density in dots per unit. * * Returns: Y resolution */ gdouble gegl_metadata_store_get_resolution_y (GeglMetadataStore *self); /** * GeglMetadataStore:file-module-name: * * Current file loader/saver module name. Valid only while a #GeglMetadata * mapping is registered. This property is mainly provided for use in signal * handlers. */ /** * gegl_metadata_store_get_file_module_name: * @self: A #GeglMetadataStore * * Return the name registered by the current file module. * * Returns: (transfer none): Current file module name or %NULL. */ const gchar * gegl_metadata_store_get_file_module_name (GeglMetadataStore *self); /** * GeglMetadataStore:title: * * Short (one line) title or caption for image. */ /** * gegl_metadata_store_set_title: * @self: A #GeglMetadataStore * @title: Title string * * Set title or caption for image. */ void gegl_metadata_store_set_title (GeglMetadataStore *self, const gchar *title); /** * gegl_metadata_store_get_title: * @self: A #GeglMetadataStore * * Get title or caption for image. * * Returns: (transfer none): Title or %NULL if not set */ const gchar * gegl_metadata_store_get_title (GeglMetadataStore *self); /** * GeglMetadataStore:artist: * * Name of image creator. */ /** * gegl_metadata_store_set_artist: * @self: A #GeglMetadataStore * @artist: Artist string * * Set name of image creator. */ void gegl_metadata_store_set_artist (GeglMetadataStore *self, const gchar *artist); /** * gegl_metadata_store_get_artist: * @self: A #GeglMetadataStore * * Get name of image creator. * * Returns: (transfer none): Artist or %NULL if not set */ const gchar * gegl_metadata_store_get_artist (GeglMetadataStore *self); /** * GeglMetadataStore:description: * * Description of image (possibly long). */ /** * gegl_metadata_store_set_description: * @self: A #GeglMetadataStore * @description: Description string * * Set description of image. */ void gegl_metadata_store_set_description (GeglMetadataStore *self, const gchar *description); /** * gegl_metadata_store_get_description: * @self: A #GeglMetadataStore * * Get description of image. * * Returns: (transfer none): Description or %NULL if not set */ const gchar * gegl_metadata_store_get_description (GeglMetadataStore *self); /** * GeglMetadataStore:copyright: * * Copyright notice. */ /** * gegl_metadata_store_set_copyright: * @self: A #GeglMetadataStore * @copyright: Copyright string * * Set the copyright notice. */ void gegl_metadata_store_set_copyright (GeglMetadataStore *self, const gchar *copyright); /** * gegl_metadata_store_get_copyright: * @self: A #GeglMetadataStore * * Get the copyright notice. * * Returns: (transfer none): Copyright or %NULL if not set */ const gchar * gegl_metadata_store_get_copyright (GeglMetadataStore *self); /** * GeglMetadataStore:disclaimer: * * Legal disclaimer. */ /** * gegl_metadata_store_set_disclaimer: * @self: A #GeglMetadataStore * @disclaimer: Disclaimer string * * Set the legal disclaimer. */ void gegl_metadata_store_set_disclaimer (GeglMetadataStore *self, const gchar *disclaimer); /** * gegl_metadata_store_get_disclaimer: * @self: A #GeglMetadataStore * * Get the legal disclaimer. * * Returns: (transfer none): Disclaimer or %NULL if not set */ const gchar * gegl_metadata_store_get_disclaimer (GeglMetadataStore *self); /** * GeglMetadataStore:warning: * * Warning of nature of content. */ /** * gegl_metadata_store_set_warning: * @self: A #GeglMetadataStore * @warning: Warning string * * Set the warning of nature of content. */ void gegl_metadata_store_set_warning (GeglMetadataStore *self, const gchar *warning); /** * gegl_metadata_store_get_warning: * @self: A #GeglMetadataStore * * Get warning. * * Returns: (transfer none): Warning or %NULL if not set */ const gchar * gegl_metadata_store_get_warning (GeglMetadataStore *self); /** * GeglMetadataStore:comment: * * Miscellaneous comment; conversion from GIF comment. */ /** * gegl_metadata_store_set_comment: * @self: A #GeglMetadataStore * @comment: Comment string * * Set the miscellaneous comment; conversion from GIF comment. */ void gegl_metadata_store_set_comment (GeglMetadataStore *self, const gchar *comment); /** * gegl_metadata_store_get_comment: * @self: A #GeglMetadataStore * * Get the comment. * * Returns: (transfer none): Comment or %NULL if not set */ const gchar * gegl_metadata_store_get_comment (GeglMetadataStore *self); /** * GeglMetadataStore:software: * * Software used to create the image. */ /** * gegl_metadata_store_set_software: * @self: A #GeglMetadataStore * @software: Software string * * Set software used to create the image. */ void gegl_metadata_store_set_software (GeglMetadataStore *self, const gchar *software); /** * gegl_metadata_store_get_software: * @self: A #GeglMetadataStore * * Get software used to create the image. * * Returns: (transfer none): Software or %NULL if not set */ const gchar * gegl_metadata_store_get_software (GeglMetadataStore *self); /** * GeglMetadataStore:source: * * Device used to create the image. */ /** * gegl_metadata_store_set_source: * @self: A #GeglMetadataStore * @source: Source string * * Set device used to create the image. */ void gegl_metadata_store_set_source (GeglMetadataStore *self, const gchar *source); /** * gegl_metadata_store_get_source: * @self: A #GeglMetadataStore * * Get device used to create the image. * * Returns: (transfer none): source or %NULL if not set */ const gchar * gegl_metadata_store_get_source (GeglMetadataStore *self); /** * GeglMetadataStore:timestamp: * * Time of original image creation. */ /** * gegl_metadata_store_set_timestamp: * @self: A #GeglMetadataStore * @timestamp: A #GDateTime * * Set time of original image creation. */ void gegl_metadata_store_set_timestamp (GeglMetadataStore *self, const GDateTime *timestamp); /** * gegl_metadata_store_get_timestamp: * @self: A #GeglMetadataStore * * Get time of original image creation. * * Returns: (transfer full): #GDateTime or %NULL if not set. Free with * g_date_time_unref() when done. */ GDateTime * gegl_metadata_store_get_timestamp (GeglMetadataStore *self); /** * gegl_metadata_store_declare: * @self: A #GeglMetadataStore * @pspec: (transfer none): A #GParamSpec * * Declare a metadata value using a #GParamSpec. */ void gegl_metadata_store_declare (GeglMetadataStore *self, GParamSpec *pspec); /** * gegl_metadata_store_has_value: * @self: A #GeglMetadataStore * @name: Metadata name * * Test whether the #GeglMetadataStore contains a value for the specified name. * * Returns: %TRUE if metadata is declared and contains a valid value. */ gboolean gegl_metadata_store_has_value (GeglMetadataStore *self, const gchar *name); /** * gegl_metadata_store_typeof_value: * @self: A #GeglMetadataStore * @name: Metadata name * * Get the declared type of the value in the #GeglMetadataStore. * * Returns: Declared #GType of metadata value or %G_TYPE_INVALID. */ GType gegl_metadata_store_typeof_value (GeglMetadataStore *self, const gchar *name); /** * gegl_metadata_store_set_value: * @self: A #GeglMetadataStore * @name: Metadata name * @value: (in): (nullable): A valid #GValue or %NULL * * Set the specified metadata value. If @value is %NULL the default value from * the associated #GParamSpec is used. This operation will fail if the value * has not been previously declared. A `changed::name` signal is emitted when * the value is set. If the value is shadowed by a property a `notify::name` * signal is also emitted. */ void gegl_metadata_store_set_value (GeglMetadataStore *self, const gchar *name, const GValue *value); /** * gegl_metadata_store_get_value: * @self: A #GeglMetadataStore * @name: Metadata name * @value: (inout): An initialised #GValue. * * Retrieve the metadata value. @value must be initialised with a compatible * type. If the value is unset or has not been previously declared @value is * unchanged and an error message is logged. */ void gegl_metadata_store_get_value (GeglMetadataStore *self, const gchar *name, GValue *value); /** * gegl_metadata_store_set_string: * @self: A #GeglMetadataStore * @name: Metadata name * @string: String value to set * * A slightly more efficient version of gegl_metadata_store_set_value() * for string values avoiding a duplication. Otherwise it behaves the same * gegl_metadata_store_set_value(). */ void gegl_metadata_store_set_string (GeglMetadataStore *self, const gchar *name, const gchar *string); /** * gegl_metadata_store_get_string: * @self: A #GeglMetadataStore * @name: Metadata name * * A slightly more efficient version of gegl_metadata_store_get_value() * for string values avoiding a duplication. Otherwise it behaves the same * gegl_metadata_store_get_value(). * Returns: (transfer none): String or %NULL. */ const gchar * gegl_metadata_store_get_string (GeglMetadataStore *self, const gchar *name); /** * gegl_metadata_store_register: * @self: A #GeglMetadataStore * @local_name: Metadata name known to file module * @name: Metadata name * @transform: (scope async): A #GValueTransform function or %NULL * */ void gegl_metadata_store_register (GeglMetadataStore *self, const gchar *local_name, const gchar *name, GValueTransform transform); /** * gegl_metadata_store_notify: * @self: A #GeglMetadataStore * @pspec: The #GParamSpec used to declare the variable. * @shadow: The metadata variable shadows a property. * * gegl_metadata_store_notify() is called by subclasses when the value of a * metadata variable changes. It emits the `::changed` signal with the variable * name as the detail parameter. Set @shadow = %TRUE if variable is shadowed * by a property so that a notify signal is emitted with the property name as * the detail parameter. */ void gegl_metadata_store_notify (GeglMetadataStore *self, GParamSpec *pspec, gboolean shadow); #define GEGL_TYPE_RESOLUTION_UNIT gegl_resolution_unit_get_type () GType gegl_resolution_unit_get_type (void) G_GNUC_CONST; G_END_DECLS #endif