1 /* This file is part of GEGL 2 * 3 * GEGL is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU Lesser General Public 5 * License as published by the Free Software Foundation; either 6 * version 3 of the License, or (at your option) any later version. 7 * 8 * GEGL is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with GEGL; if not, see <https://www.gnu.org/licenses/>. 15 * 16 * Copyright 2020 Brian Stafford 17 */ 18 19 #ifndef __GEGL_METADATA_H__ 20 #define __GEGL_METADATA_H__ 21 22 #include <glib-object.h> 23 24 G_BEGIN_DECLS 25 26 /** 27 * SECTION:gegl-metadata 28 * @title: GeglMetadata 29 * @short_description: A metadata interface for use with file modules. 30 * @see_also: #GeglMetadataStore #GeglMetadataHash 31 * 32 * Objects which need to store or retrieve image metadata when saving and 33 * loading image files should implement GeglMetadata. The object should be cast 34 * with GEGL_METADATA() and passed to the file load or save module via the 35 * `metadata` property. Image file modules should not implement the metadata 36 * property if either the module or file format does not support metadata. 37 * 38 * Gegl understands (but is not limited to) the following well-known metadata 39 * variables: 40 * 41 * - artist: Name of image creator. 42 * - comment: Miscellaneous comment; conversion from GIF comment. 43 * - copyright: Copyright notice. 44 * - description: Description of image (possibly long). 45 * - disclaimer: Legal disclaimer. 46 * - software: Software used to create the image. 47 * - source: Device used to create the image. 48 * - timestamp: Time of original image creation. 49 * - title: Short (one line) title or caption for image. 50 * - warning: Warning of nature of content. 51 * 52 * The Gegl Metadata subsystem can be used in one of three ways described 53 * below in order of increasing complexity: 54 * 55 * 1. Recommended: Create a #GeglMetadataHash and pass it to a file loader 56 * or saver via its `metadata` property. #GeglMetadataHash is a subclass of 57 * #GeglMetadataStore which saves metadata in a hash table but which adds no 58 * new properties or methods. Image file metadata to be retrieved or saved 59 * is accessed via #GeglMetadataStore properties or methods. Metadata values 60 * not directly supported by Gegl may be declared using a #GParamSpec. 61 * 2. Subclass #GeglMetadataStore. This may be useful if an application stores 62 * metadata in internal structures which may be accessed via the subclass. 63 * The subclass is used identically to #GeglMetadataHash. 64 * #GeglMetadataStore aims to be sufficiently flexible to cover the majority 65 * of application requirements. 66 * 3. Implement the #GeglMetadata interface. This option should only be used if 67 * #GeglMetadataStore cannot adequately satisfy application requirements. 68 * Particular attention should be paid to semantics of the interface methods 69 * as the file modules interact directly with these. 70 * 71 * For more complex requirements than provided by the metadata subsystem it is 72 * probably better to use a library such as `exiv2` or similar. 73 */ 74 75 /** 76 * GeglResolutionUnit: 77 * @GEGL_RESOLUTION_UNIT_NONE: Unknown or resolution not applicable. 78 * @GEGL_RESOLUTION_UNIT_DPI: Dots or pixels per inch. 79 * @GEGL_RESOLUTION_UNIT_DPM: Dots or pixels per metre. 80 * 81 * An enumerated type specifying resolution (density) units. If resolution 82 * units are unknown, X and Y resolution specify the pixel aspect ratio. 83 */ 84 typedef enum 85 { 86 GEGL_RESOLUTION_UNIT_NONE, 87 GEGL_RESOLUTION_UNIT_DPI, 88 GEGL_RESOLUTION_UNIT_DPM 89 } 90 GeglResolutionUnit; 91 92 /** 93 * GeglMapFlags: 94 * @GEGL_MAP_EXCLUDE_UNMAPPED: Prevent further mapping from being registered. 95 * 96 * Flags controlling the mapping strategy. 97 */ 98 typedef enum _GeglMapFlags 99 { 100 GEGL_MAP_EXCLUDE_UNMAPPED = 1 101 } 102 GeglMapFlags; 103 104 105 #define GEGL_TYPE_METADATA (gegl_metadata_get_type ()) 106 G_DECLARE_INTERFACE (GeglMetadata, gegl_metadata, GEGL, METADATA, GObject) 107 108 /** 109 * GeglMetadataMap: 110 * @local_name: Name of metadata variable used in the file module. 111 * @name: Standard metadata variable name used by Gegl. 112 * @transform: Optional #GValue transform function. 113 * 114 * Struct to describe how a metadata variable is mapped from the name used by 115 * the image file module to the name used by Gegl. An optional transform 116 * function may be specified, e.g. to transform from a #GDatetime to a string. 117 */ 118 typedef struct _GeglMetadataMap { 119 const gchar *local_name; 120 const gchar *name; 121 GValueTransform transform; 122 } GeglMetadataMap; 123 124 /** 125 * GeglMetadataIter: 126 * 127 * An opaque type representing a metadata iterator. 128 */ 129 typedef struct { 130 /*< private >*/ 131 guint stamp; 132 gpointer user_data; 133 gpointer user_data2; 134 gpointer user_data3; 135 } GeglMetadataIter; 136 137 /** 138 * GeglMetadataInterface: 139 * @register_map: See gegl_metadata_register_map(). If called with a NULL map, 140 * the registration is deleted. 141 * @set_resolution: See gegl_metadata_set_resolution(). 142 * @get_resolution: See gegl_metadata_get_resolution(). 143 * @iter_lookup: See gegl_metadata_iter_lookup(). 144 * @iter_init: See gegl_metadata_iter_init(). 145 * @iter_next: See gegl_metadata_iter_next(). 146 * @iter_set_value: See gegl_metadata_iter_set_value(). 147 * @iter_get_value: See gegl_metadata_iter_get_value(). 148 * 149 * The #GeglMetadata interface structure. 150 */ 151 struct _GeglMetadataInterface 152 { 153 /*< private >*/ 154 GTypeInterface base_iface; 155 156 void (*register_map) (GeglMetadata *metadata, 157 const gchar *file_module, 158 guint flags, 159 const GeglMetadataMap *map, 160 gsize n_map); 161 162 /*< public >*/ 163 gboolean (*set_resolution) (GeglMetadata *metadata, 164 GeglResolutionUnit unit, 165 gfloat x, gfloat y); 166 gboolean (*get_resolution) (GeglMetadata *metadata, 167 GeglResolutionUnit *unit, 168 gfloat *x, gfloat *y); 169 170 gboolean (*iter_lookup) (GeglMetadata *metadata, 171 GeglMetadataIter *iter, 172 const gchar *key); 173 void (*iter_init) (GeglMetadata *metadata, 174 GeglMetadataIter *iter); 175 const gchar *(*iter_next) (GeglMetadata *metadata, 176 GeglMetadataIter *iter); 177 gboolean (*iter_set_value) (GeglMetadata *metadata, 178 GeglMetadataIter *iter, 179 const GValue *value); 180 gboolean (*iter_get_value) (GeglMetadata *metadata, 181 GeglMetadataIter *iter, 182 GValue *value); 183 }; 184 185 /** 186 * gegl_metadata_register_map: 187 * @metadata: The #GeglMetadata interface 188 * @file_module: String identifying the file module, e.g, `"gegl:png-save"` 189 * @flags: Flags specifying capabilities of underlying file format 190 * @map: (array length=n_map): Array of mappings from file module metadata 191 * names to Gegl well-known names. 192 * @n_map: Number of entries in @map 193 * 194 * Set the name of the file module and pass an array of mappings from 195 * file-format specific metadata names to those used by Gegl. A GValue 196 * transformation function may be supplied, e.g. to parse or format timestamps. 197 */ 198 void gegl_metadata_register_map (GeglMetadata *metadata, 199 const gchar *file_module, 200 guint flags, 201 const GeglMetadataMap *map, 202 gsize n_map); 203 204 /** 205 * gegl_metadata_unregister_map: 206 * @metadata: The #GeglMetadata interface 207 * 208 * Unregister the file module mappings and any further mappings added or 209 * modified by the application. This should be called after the file module 210 * completes operations. 211 */ 212 void gegl_metadata_unregister_map (GeglMetadata *metadata); 213 214 /** 215 * gegl_metadata_set_resolution: 216 * @metadata: The #GeglMetadata interface 217 * @unit: Specify #GeglResolutionUnit 218 * @x: X resolution 219 * @y: Y resolution 220 * 221 * Set resolution retrieved from image file's metadata. Intended for use by 222 * the image file reader. If resolution is not supported by the application or 223 * if the operation fails %FALSE is returned and the values are ignored. 224 * 225 * Returns: %TRUE if successful. 226 */ 227 gboolean gegl_metadata_set_resolution (GeglMetadata *metadata, 228 GeglResolutionUnit unit, 229 gfloat x, gfloat y); 230 231 /** 232 * gegl_metadata_get_resolution: 233 * @metadata: The #GeglMetadata interface 234 * @unit: #GeglResolutionUnit return location 235 * @x: X resolution return location 236 * @y: Y resolution return location 237 * 238 * Retrieve resolution from the application image metadata. Intended for use 239 * by the image file writer. If resolution is not supported by the application 240 * or if the operation fails %FALSE is returned and the resolution values are 241 * not updated. 242 * 243 * Returns: %TRUE if successful. 244 */ 245 gboolean gegl_metadata_get_resolution (GeglMetadata *metadata, 246 GeglResolutionUnit *unit, 247 gfloat *x, gfloat *y); 248 249 /** 250 * gegl_metadata_iter_lookup: 251 * @metadata: The #GeglMetadata interface 252 * @iter: #GeglMetadataIter to be initialised 253 * @key: Name of the value look up 254 * 255 * Look up the specified key and initialise an iterator to reference the 256 * associated metadata. The iterator is used in conjunction with 257 * gegl_metadata_set_value() and gegl_metadata_get_value(). Note that this 258 * iterator is not valid for gegl_metadata_iter_next(). 259 * 260 * Returns: %TRUE if key is found. 261 */ 262 gboolean gegl_metadata_iter_lookup (GeglMetadata *metadata, 263 GeglMetadataIter *iter, 264 const gchar *key); 265 266 /** 267 * gegl_metadata_iter_init: 268 * @metadata: The #GeglMetadata interface 269 * @iter: #GeglMetadataIter to be initialised 270 * 271 * Initialise an iterator to find all supported metadata keys. 272 */ 273 void gegl_metadata_iter_init (GeglMetadata *metadata, 274 GeglMetadataIter *iter); 275 276 /** 277 * gegl_metadata_iter_next: 278 * @metadata: The #GeglMetadata interface 279 * @iter: #GeglMetadataIter to be updated 280 * 281 * Move the iterator to the next metadata item 282 * 283 * Returns: key name if found, else %NULL 284 */ 285 const gchar *gegl_metadata_iter_next (GeglMetadata *metadata, 286 GeglMetadataIter *iter); 287 288 /** 289 * gegl_metadata_iter_set_value: 290 * @metadata: The #GeglMetadata interface 291 * @iter: #GeglMetadataIter referencing the value to set 292 * @value: Value to set in the interface 293 * 294 * Set application data retrieved from image file's metadata. Intended for use 295 * by the image file reader. If the operation fails it returns %FALSE and 296 * @value is ignored. 297 * 298 * Returns: %TRUE if successful. 299 */ 300 gboolean gegl_metadata_iter_set_value (GeglMetadata *metadata, 301 GeglMetadataIter *iter, 302 const GValue *value); 303 304 /** 305 * gegl_metadata_iter_get_value: 306 * @metadata: The #GeglMetadata interface 307 * @iter: #GeglMetadataIter referencing the value to get 308 * @value: Value to set in the interface 309 * 310 * Retrieve image file metadata from the application. Intended for use by the 311 * image file writer. If the operation fails it returns %FALSE and @value is 312 * not updated. 313 * 314 * Returns: %TRUE if successful. 315 */ 316 gboolean gegl_metadata_iter_get_value (GeglMetadata *metadata, 317 GeglMetadataIter *iter, 318 GValue *value); 319 320 G_END_DECLS 321 322 #endif 323