From 66bc98d29909a3c63ada76e92fa6c6b7de487f16 Mon Sep 17 00:00:00 2001 From: Hartmut Kuhse Date: Tue, 3 Jan 2017 19:36:22 +0100 Subject: [PATCH] Revert "New GimpMetadata as subclass of GExiv2Metadata" This reverts commit 3ab08c8bfddb03ec4fc9a994084198228fb4f951. --- app/core/core-enums.c | 6 +- app/core/core-enums.h | 3 +- app/core/core-types.h | 1 - app/core/gimp.c | 2 - app/core/gimpimage-merge.c | 23 +- app/core/gimpimage-undo-push.c | 16 - app/core/gimpimage-undo-push.h | 4 +- app/core/gimpitem.c | 40 - app/core/gimpitem.h | 4 - app/core/gimpitemundo.c | 74 +- app/core/gimpitemundo.h | 2 - app/core/gimplayer.c | 12 +- app/pdb/internal-procs.c | 2 +- app/pdb/item-cmds.c | 121 - app/xcf/xcf-load.c | 142 +- app/xcf/xcf-save.c | 72 +- configure.ac | 2 +- icons/Color/16/gimp-image-metadata.png | Bin 569 -> 0 bytes icons/Color/24/gimp-image-metadata.png | Bin 850 -> 0 bytes icons/Color/24/gimp-image-metadata.svg | 275 -- icons/Color/48/gimp-image-metadata.png | Bin 1903 -> 0 bytes icons/Color/scalable/gimp-image-metadata.svg | 268 -- icons/Legacy/16/gimp-image-metadata.png | Bin 569 -> 0 bytes icons/Legacy/24/gimp-image-metadata.png | Bin 850 -> 0 bytes icons/Legacy/48/gimp-image-metadata.png | Bin 1903 -> 0 bytes .../24/gimp-image-metadata.svg | 189 - icons/Symbolic/16/gimp-image-metadata.png | Bin 461 -> 0 bytes icons/Symbolic/24/gimp-image-metadata.png | Bin 739 -> 0 bytes icons/Symbolic/24/gimp-image-metadata.svg | 189 - icons/Symbolic/48/gimp-image-metadata.png | Bin 1367 -> 0 bytes icons/Symbolic/64/gimp-image-metadata.png | Bin 1853 -> 0 bytes .../Symbolic/scalable/gimp-image-metadata.svg | 189 - icons/icon-list.mk | 5 - libgimp/Makefile.am | 3 - libgimp/gimp.def | 2 - libgimp/gimp.h | 1 - libgimp/gimpimagemetadata.c | 420 +- libgimp/gimpimagemetadata.h | 1 - libgimp/gimpitem.c | 86 - libgimp/gimpitem.h | 40 - libgimp/gimpitem_pdb.c | 62 - libgimp/gimpitem_pdb.h | 89 +- libgimpbase/Makefile.am | 6 - libgimpbase/gimpattribute.c | 2002 ---------- libgimpbase/gimpattribute.h | 97 - libgimpbase/gimpbase.def | 42 +- libgimpbase/gimpbase.h | 1 - libgimpbase/gimpbasetypes.h | 3 +- libgimpbase/gimpmetadata.c | 3530 ++++------------- libgimpbase/gimpmetadata.h | 144 +- libgimpbase/gimprational.c | 301 -- libgimpbase/gimprational.h | 68 - libgimpwidgets/gimpicons.c | 1 - libgimpwidgets/gimpicons.h | 1 - plug-ins/common/Makefile.am | 61 +- plug-ins/common/file-jp2-load.c | 8 +- plug-ins/common/file-png.c | 23 +- plug-ins/common/gimprc.common | 3 +- plug-ins/common/plugin-defs.pl | 3 +- plug-ins/file-jpeg/jpeg-load.c | 13 +- plug-ins/file-jpeg/jpeg-load.h | 1 - plug-ins/file-jpeg/jpeg-save.c | 3 +- plug-ins/file-jpeg/jpeg.c | 8 +- plug-ins/file-psd/psd.c | 6 +- plug-ins/file-tiff/file-tiff-load.c | 3 - plug-ins/file-tiff/file-tiff-load.h | 1 - plug-ins/file-tiff/file-tiff.c | 18 +- plug-ins/ui/Makefile.am | 4 +- plug-ins/ui/plug-in-metadata.ui | 908 +++++ po-plug-ins/POTFILES.in | 10 +- tools/pdbgen/pdb/item.pdb | 78 +- 71 files changed, 2025 insertions(+), 7667 deletions(-) delete mode 100644 icons/Color/16/gimp-image-metadata.png delete mode 100644 icons/Color/24/gimp-image-metadata.png delete mode 100644 icons/Color/24/gimp-image-metadata.svg delete mode 100644 icons/Color/48/gimp-image-metadata.png delete mode 100644 icons/Color/scalable/gimp-image-metadata.svg delete mode 100644 icons/Legacy/16/gimp-image-metadata.png delete mode 100644 icons/Legacy/24/gimp-image-metadata.png delete mode 100644 icons/Legacy/48/gimp-image-metadata.png delete mode 100644 icons/Symbolic-Inverted/24/gimp-image-metadata.svg delete mode 100644 icons/Symbolic/16/gimp-image-metadata.png delete mode 100644 icons/Symbolic/24/gimp-image-metadata.png delete mode 100644 icons/Symbolic/24/gimp-image-metadata.svg delete mode 100644 icons/Symbolic/48/gimp-image-metadata.png delete mode 100644 icons/Symbolic/64/gimp-image-metadata.png delete mode 100644 icons/Symbolic/scalable/gimp-image-metadata.svg delete mode 100644 libgimp/gimpitem.c delete mode 100644 libgimp/gimpitem.h delete mode 100644 libgimpbase/gimpattribute.c delete mode 100644 libgimpbase/gimpattribute.h delete mode 100644 libgimpbase/gimprational.c delete mode 100644 libgimpbase/gimprational.h create mode 100644 plug-ins/ui/plug-in-metadata.ui diff --git a/app/core/core-enums.c b/app/core/core-enums.c index ac60a0523a..cbdcf44c41 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -853,15 +853,14 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_IMAGE_SIZE, "GIMP_UNDO_IMAGE_SIZE", "image-size" }, { GIMP_UNDO_IMAGE_RESOLUTION, "GIMP_UNDO_IMAGE_RESOLUTION", "image-resolution" }, { GIMP_UNDO_IMAGE_GRID, "GIMP_UNDO_IMAGE_GRID", "image-grid" }, + { GIMP_UNDO_IMAGE_METADATA, "GIMP_UNDO_IMAGE_METADATA", "image-metadata" }, { GIMP_UNDO_IMAGE_COLORMAP, "GIMP_UNDO_IMAGE_COLORMAP", "image-colormap" }, { GIMP_UNDO_IMAGE_COLOR_MANAGED, "GIMP_UNDO_IMAGE_COLOR_MANAGED", "image-color-managed" }, - { GIMP_UNDO_IMAGE_METADATA, "GIMP_UNDO_IMAGE_METADATA", "image-metadata" }, { GIMP_UNDO_GUIDE, "GIMP_UNDO_GUIDE", "guide" }, { GIMP_UNDO_SAMPLE_POINT, "GIMP_UNDO_SAMPLE_POINT", "sample-point" }, { GIMP_UNDO_DRAWABLE, "GIMP_UNDO_DRAWABLE", "drawable" }, { GIMP_UNDO_DRAWABLE_MOD, "GIMP_UNDO_DRAWABLE_MOD", "drawable-mod" }, { GIMP_UNDO_MASK, "GIMP_UNDO_MASK", "mask" }, - { GIMP_UNDO_ITEM_METADATA, "GIMP_UNDO_ITEM_METADATA", "item-metadata" }, { GIMP_UNDO_ITEM_REORDER, "GIMP_UNDO_ITEM_REORDER", "item-reorder" }, { GIMP_UNDO_ITEM_RENAME, "GIMP_UNDO_ITEM_RENAME", "item-rename" }, { GIMP_UNDO_ITEM_DISPLACE, "GIMP_UNDO_ITEM_DISPLACE", "item-displace" }, @@ -947,15 +946,14 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_IMAGE_SIZE, NC_("undo-type", "Image size"), NULL }, { GIMP_UNDO_IMAGE_RESOLUTION, NC_("undo-type", "Image resolution change"), NULL }, { GIMP_UNDO_IMAGE_GRID, NC_("undo-type", "Grid"), NULL }, + { GIMP_UNDO_IMAGE_METADATA, NC_("undo-type", "Change metadata"), NULL }, { GIMP_UNDO_IMAGE_COLORMAP, NC_("undo-type", "Change indexed palette"), NULL }, { GIMP_UNDO_IMAGE_COLOR_MANAGED, NC_("undo-type", "Change color managed state"), NULL }, - { GIMP_UNDO_IMAGE_METADATA, "GIMP_UNDO_IMAGE_METADATA", NULL }, { GIMP_UNDO_GUIDE, NC_("undo-type", "Guide"), NULL }, { GIMP_UNDO_SAMPLE_POINT, NC_("undo-type", "Sample Point"), NULL }, { GIMP_UNDO_DRAWABLE, NC_("undo-type", "Layer/Channel"), NULL }, { GIMP_UNDO_DRAWABLE_MOD, NC_("undo-type", "Layer/Channel modification"), NULL }, { GIMP_UNDO_MASK, NC_("undo-type", "Selection mask"), NULL }, - { GIMP_UNDO_ITEM_METADATA, "GIMP_UNDO_ITEM_METADATA", NULL }, { GIMP_UNDO_ITEM_REORDER, NC_("undo-type", "Reorder item"), NULL }, { GIMP_UNDO_ITEM_RENAME, NC_("undo-type", "Rename item"), NULL }, { GIMP_UNDO_ITEM_DISPLACE, NC_("undo-type", "Move item"), NULL }, diff --git a/app/core/core-enums.h b/app/core/core-enums.h index 5b7e92286d..95616e6158 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -425,15 +425,14 @@ typedef enum /*< pdb-skip >*/ GIMP_UNDO_IMAGE_SIZE, /*< desc="Image size" >*/ GIMP_UNDO_IMAGE_RESOLUTION, /*< desc="Image resolution change" >*/ GIMP_UNDO_IMAGE_GRID, /*< desc="Grid" >*/ + GIMP_UNDO_IMAGE_METADATA, /*< desc="Change metadata" >*/ GIMP_UNDO_IMAGE_COLORMAP, /*< desc="Change indexed palette" >*/ GIMP_UNDO_IMAGE_COLOR_MANAGED, /*< desc="Change color managed state" >*/ - GIMP_UNDO_IMAGE_METADATA, /*< desc="Change metadata >*/ GIMP_UNDO_GUIDE, /*< desc="Guide" >*/ GIMP_UNDO_SAMPLE_POINT, /*< desc="Sample Point" >*/ GIMP_UNDO_DRAWABLE, /*< desc="Layer/Channel" >*/ GIMP_UNDO_DRAWABLE_MOD, /*< desc="Layer/Channel modification" >*/ GIMP_UNDO_MASK, /*< desc="Selection mask" >*/ - GIMP_UNDO_ITEM_METADATA, /*< desc="Change metadata >*/ GIMP_UNDO_ITEM_REORDER, /*< desc="Reorder item" >*/ GIMP_UNDO_ITEM_RENAME, /*< desc="Rename item" >*/ GIMP_UNDO_ITEM_DISPLACE, /*< desc="Move item" >*/ diff --git a/app/core/core-types.h b/app/core/core-types.h index 57921bb1d2..11eaa626fc 100644 --- a/app/core/core-types.h +++ b/app/core/core-types.h @@ -157,7 +157,6 @@ typedef struct _GimpGroupLayer GimpGroupLayer; typedef struct _GimpUndo GimpUndo; typedef struct _GimpUndoStack GimpUndoStack; typedef struct _GimpUndoAccumulator GimpUndoAccumulator; -typedef struct _GimpViewableUndo GimpViewableUndo; /* Symmetry transformations */ diff --git a/app/core/gimp.c b/app/core/gimp.c index ff02bbd27c..25ee2060c7 100644 --- a/app/core/gimp.c +++ b/app/core/gimp.c @@ -38,8 +38,6 @@ #include "plug-in/gimppluginmanager.h" #include "plug-in/gimppluginmanager-restore.h" -#include "gui/gimpdbusservice-generated.h" - #include "paint/gimp-paint.h" #include "text/gimp-fonts.h" diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c index 5e1e362d2d..3d97d13f54 100644 --- a/app/core/gimpimage-merge.c +++ b/app/core/gimpimage-merge.c @@ -40,9 +40,7 @@ #include "gimpgrouplayer.h" #include "gimpimage.h" #include "gimpimage-merge.h" -#include "gimpimage-metadata.h" #include "gimpimage-undo.h" -#include "gimpitem.h" #include "gimpitemstack.h" #include "gimplayer-floating-selection.h" #include "gimplayer-new.h" @@ -430,7 +428,6 @@ gimp_image_merge_layers (GimpImage *image, GimpLayer *layer; GimpLayer *bottom_layer; GimpParasiteList *parasites; - GimpMetadata *metadata; gint count; gint x1, y1, x2, y2; gint off_x, off_y; @@ -525,8 +522,8 @@ gimp_image_merge_layers (GimpImage *image, (gimp_drawable_is_indexed (GIMP_DRAWABLE (layer)) && ! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))) { - GeglColor *color; - GimpRGB bg; + GeglColor *color; + GimpRGB bg; merge_layer = gimp_layer_new (image, (x2 - x1), (y2 - y1), gimp_image_get_layer_format (image, FALSE), @@ -588,22 +585,6 @@ gimp_image_merge_layers (GimpImage *image, bottom_layer = layer; - /* Copy the metadata of the bottom layer to the new layer */ - - metadata = gimp_item_get_metadata (GIMP_ITEM (bottom_layer)); - - if (!metadata) - metadata = gimp_image_get_metadata (image); - - if (metadata) - { - GimpMetadata *new_metadata; - - new_metadata = gimp_metadata_duplicate (metadata); - gimp_item_set_metadata (GIMP_ITEM (merge_layer), new_metadata, TRUE); - g_object_unref (new_metadata); - } - /* Copy the tattoo and parasites of the bottom layer to the new layer */ gimp_item_set_tattoo (GIMP_ITEM (merge_layer), gimp_item_get_tattoo (GIMP_ITEM (bottom_layer))); diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c index c3b05e2f3e..670cc42d9d 100644 --- a/app/core/gimpimage-undo-push.c +++ b/app/core/gimpimage-undo-push.c @@ -49,7 +49,6 @@ #include "gimpsamplepoint.h" #include "gimpsamplepointundo.h" #include "gimpselection.h" -#include "gimpviewable.h" #include "text/gimptextlayer.h" #include "text/gimptextundo.h" @@ -173,21 +172,6 @@ gimp_image_undo_push_image_metadata (GimpImage *image, NULL); } - -GimpUndo * -gimp_image_undo_push_item_metadata (GimpImage *image, - const gchar *undo_desc, - GimpItem *item) -{ - g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); - - return gimp_image_undo_push (image, GIMP_TYPE_ITEM_UNDO, - GIMP_UNDO_ITEM_METADATA, undo_desc, - GIMP_DIRTY_IMAGE_META, - "item", item, - NULL); -} - GimpUndo * gimp_image_undo_push_image_parasite (GimpImage *image, const gchar *undo_desc, diff --git a/app/core/gimpimage-undo-push.h b/app/core/gimpimage-undo-push.h index 592954b852..57bc97089d 100644 --- a/app/core/gimpimage-undo-push.h +++ b/app/core/gimpimage-undo-push.h @@ -118,9 +118,6 @@ GimpUndo * gimp_image_undo_push_item_parasite_remove(GimpImage *image, const gchar *undo_desc, GimpItem *item, const gchar *name); -GimpUndo * gimp_image_undo_push_item_metadata (GimpImage *image, - const gchar *undo_desc, - GimpItem *item); /* layer undos */ @@ -237,4 +234,5 @@ GimpUndo * gimp_image_undo_push_fs_to_layer (GimpImage *image, GimpUndo * gimp_image_undo_push_cantundo (GimpImage *image, const gchar *undo_desc); + #endif /* __GIMP_IMAGE_UNDO_PUSH_H__ */ diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c index 91673198ce..ab36f52adf 100644 --- a/app/core/gimpitem.c +++ b/app/core/gimpitem.c @@ -99,7 +99,6 @@ struct _GimpItemPrivate GimpColorTag color_tag; /* color tag */ GList *offset_nodes; /* offset nodes to manage */ - GimpMetadata *metadata /* items metadata */ }; #define GET_PRIVATE(item) G_TYPE_INSTANCE_GET_PRIVATE (item, \ @@ -332,7 +331,6 @@ gimp_item_init (GimpItem *item) g_object_force_floating (G_OBJECT (item)); private->parasites = gimp_parasite_list_new (); - private->metadata = NULL; } static void @@ -2422,41 +2420,3 @@ gimp_item_is_in_set (GimpItem *item, return FALSE; } - -void -gimp_item_set_metadata (GimpItem *item, - GimpMetadata *metadata, - gboolean push_undo) -{ - GimpItemPrivate *private; - - g_return_val_if_fail (GIMP_IS_ITEM (item), NULL); - - private = GET_PRIVATE (item); - - if (metadata != private->metadata) - { - if (push_undo) - gimp_image_undo_push_item_metadata (gimp_item_get_image (item), - NULL, - item); - - if (private->metadata) - g_object_unref (private->metadata); - - private->metadata = metadata; - g_object_ref (private->metadata); - } -} - -GimpMetadata * -gimp_item_get_metadata (GimpItem *item) -{ - GimpItemPrivate *private; - - g_return_val_if_fail (GIMP_IS_ITEM (item), NULL); - - private = GET_PRIVATE (item); - - return private->metadata; -} diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h index 2be3b75699..da431e1319 100644 --- a/app/core/gimpitem.h +++ b/app/core/gimpitem.h @@ -364,9 +364,5 @@ gboolean gimp_item_mask_intersect (GimpItem *item, gboolean gimp_item_is_in_set (GimpItem *item, GimpItemSet set); -void gimp_item_set_metadata (GimpItem *item, - GimpMetadata *metadata, - gboolean push_undo); -GimpMetadata * gimp_item_get_metadata (GimpItem *item); #endif /* __GIMP_ITEM_H__ */ diff --git a/app/core/gimpitemundo.c b/app/core/gimpitemundo.c index 529f310be1..34c95393d1 100644 --- a/app/core/gimpitemundo.c +++ b/app/core/gimpitemundo.c @@ -22,8 +22,6 @@ #include "core-types.h" -#include "libgimpbase/gimpbase.h" - #include "gimpimage.h" #include "gimpitem.h" #include "gimpitemundo.h" @@ -36,21 +34,18 @@ enum }; -static void gimp_item_undo_constructed (GObject *object); -static void gimp_item_undo_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_item_undo_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); +static void gimp_item_undo_constructed (GObject *object); +static void gimp_item_undo_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_item_undo_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); -static void gimp_item_undo_free (GimpUndo *undo, - GimpUndoMode undo_mode); -static void gimp_item_undo_pop (GimpUndo *undo, - GimpUndoMode undo_mode, - GimpUndoAccumulator *accum); +static void gimp_item_undo_free (GimpUndo *undo, + GimpUndoMode undo_mode); G_DEFINE_TYPE (GimpItemUndo, gimp_item_undo, GIMP_TYPE_UNDO) @@ -68,7 +63,6 @@ gimp_item_undo_class_init (GimpItemUndoClass *klass) object_class->set_property = gimp_item_undo_set_property; object_class->get_property = gimp_item_undo_get_property; - undo_class->pop = gimp_item_undo_pop; undo_class->free = gimp_item_undo_free; g_object_class_install_property (object_class, PROP_ITEM, @@ -90,14 +84,7 @@ gimp_item_undo_constructed (GObject *object) G_OBJECT_CLASS (parent_class)->constructed (object); - switch (GIMP_UNDO (object)->undo_type) - { - case GIMP_UNDO_ITEM_METADATA: - item_undo->metadata = - gimp_metadata_duplicate (gimp_item_get_metadata (item_undo->item)); - break; - } - + g_assert (GIMP_IS_ITEM (item_undo->item)); } static void @@ -152,42 +139,5 @@ gimp_item_undo_free (GimpUndo *undo, item_undo->item = NULL; } - if (item_undo->metadata) - { - g_object_unref (item_undo->metadata); - item_undo->metadata = NULL; - } - GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode); } - -static void -gimp_item_undo_pop (GimpUndo *undo, - GimpUndoMode undo_mode, - GimpUndoAccumulator *accum) -{ - GimpItemUndo *item_undo = GIMP_ITEM_UNDO (undo); - GimpItem *item = GIMP_ITEM_UNDO (undo)->item; - - switch (undo->undo_type) - { - case GIMP_UNDO_ITEM_METADATA: - { - GimpMetadata *metadata; - - metadata = gimp_metadata_duplicate (gimp_item_get_metadata (item)); - - gimp_item_set_metadata (item, item_undo->metadata, FALSE); - - if (item_undo->metadata) - g_object_unref (item_undo->metadata); - item_undo->metadata = metadata; - } - break; - - default: -// g_assert_not_reached (); - break; - - } -} diff --git a/app/core/gimpitemundo.h b/app/core/gimpitemundo.h index 31e504ac00..1b95592afd 100644 --- a/app/core/gimpitemundo.h +++ b/app/core/gimpitemundo.h @@ -38,8 +38,6 @@ struct _GimpItemUndo GimpUndo parent_instance; GimpItem *item; /* the item this undo is for */ - GimpMetadata *metadata; - }; struct _GimpItemUndoClass diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index d8a3eb5f9e..d8284b815b 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -743,9 +743,7 @@ static GimpItem * gimp_layer_duplicate (GimpItem *item, GType new_type) { - GimpItem *new_item; - GimpMetadata *metadata; - GimpMetadata *new_metadata; + GimpItem *new_item; g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL); @@ -776,14 +774,6 @@ gimp_layer_duplicate (GimpItem *item, new_layer->edit_mask = layer->edit_mask; new_layer->show_mask = layer->show_mask; } - - metadata = gimp_item_get_metadata (item); - if (metadata) - { - new_metadata = gimp_metadata_duplicate (metadata); - gimp_item_set_metadata (new_item, new_metadata, FALSE); - g_object_unref (new_metadata); - } } return new_item; diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c index ff7552245e..5379699f06 100644 --- a/app/pdb/internal-procs.c +++ b/app/pdb/internal-procs.c @@ -28,7 +28,7 @@ #include "internal-procs.h" -/* 804 procedures registered total */ +/* 802 procedures registered total */ void internal_procs_init (GimpPDB *pdb) diff --git a/app/pdb/item-cmds.c b/app/pdb/item-cmds.c index 0ba96b816f..2a19e252d0 100644 --- a/app/pdb/item-cmds.c +++ b/app/pdb/item-cmds.c @@ -821,67 +821,6 @@ item_set_tattoo_invoker (GimpProcedure *procedure, error ? *error : NULL); } -static GimpValueArray * -item_get_metadata_invoker (GimpProcedure *procedure, - Gimp *gimp, - GimpContext *context, - GimpProgress *progress, - const GimpValueArray *args, - GError **error) -{ - gboolean success = TRUE; - GimpValueArray *return_vals; - GimpItem *item; - gchar *metadata_string = NULL; - - item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp); - - if (success) - { - GimpMetadata *metadata = gimp_item_get_metadata (item); - - if (metadata) - metadata_string = gimp_metadata_serialize (metadata); - } - - return_vals = gimp_procedure_get_return_values (procedure, success, - error ? *error : NULL); - - if (success) - g_value_take_string (gimp_value_array_index (return_vals, 1), metadata_string); - - return return_vals; -} - -static GimpValueArray * -item_set_metadata_invoker (GimpProcedure *procedure, - Gimp *gimp, - GimpContext *context, - GimpProgress *progress, - const GimpValueArray *args, - GError **error) -{ - gboolean success = TRUE; - GimpItem *item; - const gchar *metadata_string; - - item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp); - metadata_string = g_value_get_string (gimp_value_array_index (args, 1)); - - if (success) - { - GimpMetadata *metadata = gimp_metadata_deserialize (metadata_string); - - gimp_item_set_metadata (item, metadata, TRUE); - - if (metadata) - g_object_unref (metadata); - } - - return gimp_procedure_get_return_values (procedure, success, - error ? *error : NULL); -} - static GimpValueArray * item_attach_parasite_invoker (GimpProcedure *procedure, Gimp *gimp, @@ -1791,66 +1730,6 @@ register_item_procs (GimpPDB *pdb) gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); - /* - * gimp-item-get-metadata - */ - procedure = gimp_procedure_new (item_get_metadata_invoker); - gimp_object_set_static_name (GIMP_OBJECT (procedure), - "gimp-item-get-metadata"); - gimp_procedure_set_static_strings (procedure, - "gimp-item-get-metadata", - "Returns the item's metadata.", - "Returns metadata from the item.", - "Spencer Kimball & Peter Mattis", - "Spencer Kimball & Peter Mattis", - "1995-1996", - NULL); - gimp_procedure_add_argument (procedure, - gimp_param_spec_item_id ("item", - "item", - "The item", - pdb->gimp, FALSE, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_return_value (procedure, - gimp_param_spec_string ("metadata-string", - "metadata string", - "The metadata as a xml string", - FALSE, FALSE, FALSE, - NULL, - GIMP_PARAM_READWRITE)); - gimp_pdb_register_procedure (pdb, procedure); - g_object_unref (procedure); - - /* - * gimp-item-set-metadata - */ - procedure = gimp_procedure_new (item_set_metadata_invoker); - gimp_object_set_static_name (GIMP_OBJECT (procedure), - "gimp-item-set-metadata"); - gimp_procedure_set_static_strings (procedure, - "gimp-item-set-metadata", - "Set the item's metadata.", - "Sets metadata on the item.", - "Spencer Kimball & Peter Mattis", - "Spencer Kimball & Peter Mattis", - "1995-1996", - NULL); - gimp_procedure_add_argument (procedure, - gimp_param_spec_item_id ("item", - "item", - "The item", - pdb->gimp, FALSE, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_argument (procedure, - gimp_param_spec_string ("metadata-string", - "metadata string", - "The metadata as a xml string", - FALSE, FALSE, FALSE, - NULL, - GIMP_PARAM_READWRITE)); - gimp_pdb_register_procedure (pdb, procedure); - g_object_unref (procedure); - /* * gimp-item-attach-parasite */ diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index cf8128f02d..5be2a71ade 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -48,7 +48,6 @@ #include "core/gimpimage-undo.h" #include "core/gimpitemstack.h" #include "core/gimplayer-floating-selection.h" -#include "core/gimpitem.h" #include "core/gimplayer-new.h" #include "core/gimplayermask.h" #include "core/gimpparasitelist.h" @@ -269,31 +268,6 @@ xcf_load_image (Gimp *gimp, gimp_parasite_list_remove (private->parasites, gimp_parasite_name (parasite)); } - else - { - - /* check for an attributes parasite */ - parasite = gimp_image_parasite_find (GIMP_IMAGE (image), - "gimp-image-attributes"); - if (parasite) - { - GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image); - GimpMetadata *metadata; - const gchar *attributes_string; - - attributes_string = (gchar *) gimp_parasite_data (parasite); - metadata = gimp_metadata_deserialize (attributes_string); - - if (metadata) - { - gimp_image_set_metadata (image, metadata, FALSE); - g_object_unref (metadata); - } - - gimp_parasite_list_remove (private->parasites, - gimp_parasite_name (parasite)); - } - } /* migrate the old "exif-data" parasite */ parasite = gimp_image_parasite_find (GIMP_IMAGE (image), @@ -310,10 +284,13 @@ xcf_load_image (Gimp *gimp, } else { - GimpMetadata *metadata = NULL; - GError *my_error = NULL; + GimpMetadata *metadata = gimp_image_get_metadata (image); + GError *my_error = NULL; - metadata = gimp_metadata_new (); + if (metadata) + g_object_ref (metadata); + else + metadata = gimp_metadata_new (); if (! gimp_metadata_set_from_exif (metadata, gimp_parasite_data (parasite), @@ -364,10 +341,13 @@ xcf_load_image (Gimp *gimp, } else { - GimpMetadata *metadata = NULL; - GError *my_error = NULL; + GimpMetadata *metadata = gimp_image_get_metadata (image); + GError *my_error = NULL; - metadata = gimp_metadata_new (); + if (metadata) + g_object_ref (metadata); + else + metadata = gimp_metadata_new (); if (! gimp_metadata_set_from_xmp (metadata, (const guint8 *) xmp_data + 10, @@ -1463,26 +1443,25 @@ xcf_load_layer (XcfInfo *info, GimpImage *image, GList **item_path) { - GimpLayer *layer; - GimpLayerMask *layer_mask; - const GimpParasite *parasite; - guint32 hierarchy_offset; - guint32 layer_mask_offset; - gboolean apply_mask = TRUE; - gboolean edit_mask = FALSE; - gboolean show_mask = FALSE; - gboolean active; - gboolean floating; - guint32 group_layer_flags = 0; - guint32 text_layer_flags = 0; - gint width; - gint height; - gint type; - GimpImageBaseType base_type; - gboolean has_alpha; - const Babl *format; - gboolean is_fs_drawable; - gchar *name; + GimpLayer *layer; + GimpLayerMask *layer_mask; + guint32 hierarchy_offset; + guint32 layer_mask_offset; + gboolean apply_mask = TRUE; + gboolean edit_mask = FALSE; + gboolean show_mask = FALSE; + gboolean active; + gboolean floating; + guint32 group_layer_flags = 0; + guint32 text_layer_flags = 0; + gint width; + gint height; + gint type; + GimpImageBaseType base_type; + gboolean has_alpha; + const Babl *format; + gboolean is_fs_drawable; + gchar *name; /* check and see if this is the drawable the floating selection * is attached to. if it is then we'll do the attachment in our caller. @@ -1559,29 +1538,6 @@ xcf_load_layer (XcfInfo *info, GIMP_LOG (XCF, "layer props loaded"); - parasite = gimp_item_parasite_find (GIMP_ITEM (layer), - "gimp-item-metadata"); - if (parasite) - { - GimpMetadata *metadata; - const gchar *metadata_string; - - metadata_string = (gchar *) gimp_parasite_data (parasite); - metadata = gimp_metadata_deserialize (metadata_string); - - if (metadata) - { - gimp_item_set_metadata (GIMP_ITEM (layer), metadata, FALSE); - g_object_unref (metadata); - } - - gimp_item_parasite_detach (GIMP_ITEM (layer), - "gimp-item-metadata", - FALSE); - } - - GIMP_LOG (XCF, "layer metadata loaded"); - xcf_progress_update (info); /* call the evil text layer hack that might change our layer pointer */ @@ -1671,14 +1627,13 @@ static GimpChannel * xcf_load_channel (XcfInfo *info, GimpImage *image) { - GimpChannel *channel; - const GimpParasite *parasite; - guint32 hierarchy_offset; - gint width; - gint height; - gboolean is_fs_drawable; - gchar *name; - GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE }; + GimpChannel *channel; + guint32 hierarchy_offset; + gint width; + gint height; + gboolean is_fs_drawable; + gchar *name; + GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE }; /* check and see if this is the drawable the floating selection * is attached to. if it is then we'll do the attachment in our caller. @@ -1703,27 +1658,6 @@ xcf_load_channel (XcfInfo *info, if (!xcf_load_channel_props (info, image, &channel)) goto error; - parasite = gimp_item_parasite_find (GIMP_ITEM (channel), - "gimp-item-metadata"); - if (parasite) - { - GimpMetadata *metadata; - const gchar *metadata_string; - - metadata_string = (gchar *) gimp_parasite_data (parasite); - metadata = gimp_metadata_deserialize (metadata_string); - - if (metadata) - { - gimp_item_set_metadata (GIMP_ITEM (channel), metadata, FALSE); - g_object_unref (metadata); - } - - gimp_item_parasite_detach (GIMP_ITEM (channel), - "gimp-item-metadata", - FALSE); - } - xcf_progress_update (info); /* read the hierarchy and layer mask offsets */ diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c index 3d9cf4ae27..7930b0f7bc 100644 --- a/app/xcf/xcf-save.c +++ b/app/xcf/xcf-save.c @@ -45,7 +45,6 @@ #include "core/gimpimage-metadata.h" #include "core/gimpimage-private.h" #include "core/gimpimage-sample-points.h" -#include "core/gimpitem.h" #include "core/gimplayer.h" #include "core/gimplayermask.h" #include "core/gimpparasitelist.h" @@ -338,11 +337,11 @@ xcf_save_image_props (XcfInfo *info, GimpImage *image, GError **error) { - GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image); - GimpParasite *grid_parasite = NULL; - GimpParasite *meta_parasite = NULL; - GimpParasite *compat_parasite = NULL; - GimpUnit unit = gimp_image_get_unit (image); + GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image); + GimpParasite *grid_parasite = NULL; + GimpParasite *meta_parasite = NULL; + GimpParasite *compat_parasite = NULL; + GimpUnit unit = gimp_image_get_unit (image); gdouble xres; gdouble yres; @@ -394,27 +393,6 @@ xcf_save_image_props (XcfInfo *info, gimp_parasite_list_add (private->parasites, grid_parasite); } -#if 0 - if (gimp_image_get_attributes (image)) - { - GimpParasite *attributes_parasite = NULL; - GimpAttributes *attributes = gimp_image_get_attributes (image); - gchar *attributes_string; - - attributes_string = gimp_attributes_serialize (attributes); - - if (attributes_string) - { - attributes_parasite = gimp_parasite_new ("gimp-image-attributes", - GIMP_PARASITE_PERSISTENT, - strlen (attributes_string) + 1, - attributes_string); - gimp_parasite_list_add (private->parasites, attributes_parasite); - g_free (attributes_string); - } - } -#endif - if (gimp_image_get_metadata (image)) { GimpMetadata *metadata = gimp_image_get_metadata (image); @@ -490,25 +468,6 @@ xcf_save_layer_props (XcfInfo *info, GimpParasiteList *parasites; gint offset_x; gint offset_y; - GimpParasite *metadata_parasite = NULL; - - if (gimp_item_get_metadata (GIMP_ITEM (layer))) - { - GimpMetadata *metadata = gimp_item_get_metadata (GIMP_ITEM (layer)); - gchar *metadata_string; - - metadata_string = gimp_metadata_serialize (metadata); - - if (metadata_string) - { - metadata_parasite = gimp_parasite_new ("gimp-item-metadata", - GIMP_PARASITE_PERSISTENT, - strlen (metadata_string) + 1, - metadata_string); - gimp_item_parasite_attach (GIMP_ITEM (layer), metadata_parasite, FALSE); - g_free (metadata_string); - } - } if (gimp_viewable_get_children (GIMP_VIEWABLE (layer))) xcf_check_error (xcf_save_prop (info, image, PROP_GROUP_ITEM, error)); @@ -624,27 +583,6 @@ xcf_save_channel_props (XcfInfo *info, { GimpParasiteList *parasites; guchar col[3]; -#if 0 - GimpParasite *attributes_parasite = NULL; - - if (gimp_item_get_attributes (GIMP_ITEM (channel))) - { - GimpAttributes *attributes = gimp_item_get_attributes (GIMP_ITEM (channel)); - gchar *attributes_string; - - attributes_string = gimp_attributes_serialize (attributes); - - if (attributes_string) - { - attributes_parasite = gimp_parasite_new ("gimp-item-attributes", - GIMP_PARASITE_PERSISTENT, - strlen (attributes_string) + 1, - attributes_string); - gimp_item_parasite_attach (GIMP_ITEM (channel), attributes_parasite, FALSE); - g_free (attributes_string); - } - } -#endif if (channel == gimp_image_get_active_channel (image)) xcf_check_error (xcf_save_prop (info, image, PROP_ACTIVE_CHANNEL, error)); diff --git a/configure.ac b/configure.ac index 918b78bb45..e9bf40aa1c 100644 --- a/configure.ac +++ b/configure.ac @@ -66,7 +66,7 @@ m4_define([pycairo_required_version], [1.0.2]) m4_define([poppler_required_version], [0.44.0]) m4_define([poppler_data_required_version], [0.4.7]) m4_define([libgudev_required_version], [167]) -m4_define([gexiv2_required_version], [0.10.3]) +m4_define([gexiv2_required_version], [0.6.1]) m4_define([libmypaint_required_version], [1.3.0]) m4_define([lcms_required_version], [2.7]) m4_define([libpng_required_version], [1.6.25]) diff --git a/icons/Color/16/gimp-image-metadata.png b/icons/Color/16/gimp-image-metadata.png deleted file mode 100644 index dd0bafa2fea659f035f85e80d0e78795ed7d44cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 569 zcmV-90>=G`P)q$gGR5;6xlh11tQ4q&JyZbgxV%juOt62q)=Awt51f@suFHjU) z>e+)A4}xdGgCYnXl~VOmLGU6(Jb5sP9z;P%J*u-USi4$HlahVoVY5k^{?NG$?=kav zZ)U#Zh={U{)$6aL!LtrUMN!mgwOY3v5z!#1YypUbl*^?7fTC#PRq>6_!om|Vg9!jB zEC?!ygk-ZBVjE+v#ddvcWAga|mEhorVHZmwj~>tUe**Zv&-BF^930GG@XnA~u3x*{ zyQ?0XMAf2z%YRr9RJd{T9!0N7$*g0Xqz?dYqtRGN>;IRv)>fD(bjWyMRYAKyC>BTA z4I&cqX6_PMcY|uh;Cq??(0&QEXZN>-h=hE7I>XZPcg|1k=g?RO-&0g=QbHQ&yNXwz z-UJZ|d3pN`51ub_`gnoEMN2RiW8A)~OsX>DDtq@ixTCKSnF8QIc!jeki`3pNaipw3 zoIKWK7@++8-Q>ffWg_zycjP15v3&Zx&aY*Q@iV;tVtYwzaeEkG`4jJaI+yhaTMf{&_xxM<;4T6e2-X z&_yMEXhD=_LRp%g&7CyziwugQp_Sg~{LV#P7x}U2HupU@H>X9m&29cW?<W z{C1u_@4M%>_i*0x98q<3bu7nmpCuAWfMr>11*BFDSEJmo}?=wwU-IPFHJN_{+YZrArie&8(ko@g7C46=TEN+ z5lk91!h*FRbBivW5`+k}`ti*P%C4Ujga|Z~>g57*tVcrTNN=B56(X3>jYSH`t+&?o zZ!SGfd3Gl|6cZXsazil@s5PU}1!Pd@4yq|kK}EqaynUF1s;kL(SDp*`qa|u@rJ?1X zn8u`rYGPPe(8Xp)+*KbRi)sF5{vq7RJBW_TEc(5+@F>mI@n`vi44NY~M#p~$3%=B4 zQU2`*5)W}=NDJaA^0MU6oL&iob6NY)`6NA*BQ-|U--QLkO_>o4NmB5YOTz_m9NO+D zhVng?$!IEyUpAN4P<;~?7+*0ky=Gu-&4jI8j42+=`%IYLFz6~zz}fUzI!DPSL0)`> z#^DGGX53CXINQqLry?6ZZ83tg4G6mH`S>n=_2gi#jX~X&{kWX72aVSbU{;7>Uv5xfcUZwnDsVU#auNYhX+QJwA c#K*h;0s^O7N%8w;mjD0&07*qoM6N<$f{J5<1poj5 diff --git a/icons/Color/24/gimp-image-metadata.svg b/icons/Color/24/gimp-image-metadata.svg deleted file mode 100644 index f0526ba939..0000000000 --- a/icons/Color/24/gimp-image-metadata.svg +++ /dev/null @@ -1,275 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/icons/Color/48/gimp-image-metadata.png b/icons/Color/48/gimp-image-metadata.png deleted file mode 100644 index 14a539c1e18a1a768685cc7e479a5981de74501e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1903 zcmV-#2ax!QP)bP;|1K zEGJ7%@lA?al!}Htb<|AJ1%X%<3`{YU0UdK{nsFvGd9ys0$HMZ^3}g|O{ddmYJr@=h z*}H(?nfcGX_nhy${D1e}-Q}L|NF=7_@9*zIbS)qtpo(nK9cA*COtx}K(?&Ws5E;6w zaSJl|`T4D5=7$p1(t+scbEv2&M_pYVx?6kns1{mnDU`}62BGuy^&LV1B56lhSQs=K zjVN_RqZe19P%wya3Aq&-dQenU#G8^xV6|xcy?YfRRgTKaa&o83P+p-$S$QeS%1WRu z)1XwVK}l&b5%E$|h+<6viZp5z7OVOGM|F>Qh`jt<22e!rfSw-I*6Kt9*aFeie7Ru0 zq!sf-#C%~Qq{b9vF$ z(9j@!m<0gZYz24{5Y&8rL5}cQ=x_j*^TCHpI#djTn$J_KtOu}F^c+h+TGC-+0MvZ0 zI=k}$7{sR^FYXXE0%RjM{|Nywh*c}x+bsq_&FAE2JvjgdvHtT#?Ggi^=2dx_PZoed zc&=G!vlsw1ugcBn8h~Bv+-#NrK+I>i1<+ZK(VmS9Y!(Bc=Cg9r+XkRN_Z|6dbYSa( z_Q?c5&1dDLSqIP&5H$bb_WA8rBS0E5RjJkk&?H+SXx_1%^IGVr*IbMJj}rr+<}jS|LV_RZ$EXZE-t+Q+!>vuY|%?T{kGONzr=9E4crgPKpv`bRv#r314C zwFW`^FZ#Ne#VWs*;oX6+!hTFYaCQTr@NzU8KeEXlfgaP~I&~nnEgOeb3r50Y@o0Fj zm}C~md{FbLnGC>SJwRfhi-jx$uoP#QEpA25h#=_lU zki~H(0f3lK&A1~T;Krd@E!6Z~p=p1DpA_GJF+n(>6E622&^Vcys z7ET`k<<2Rs#xNh$yiEXUCpn8sKSdNuq~MTB_HQ4PnvHLEABvF!dt>+Vk*%J?!)*wn zc1&({oT}XbIbkw0j6)b@!j`kSlW07a2fUd2%|Xrg5(jpd-dC`VcRERXH=dgik0HuOC0`7 zbVY6IM%0%E!SLV|8Xkn8z9ay;)D3t*#_q>+xPL*0$`~o1o4nr+FZ6r{CpWx@oKrL5 zGO-Vo+s5)^)<`r!rD^JqC04~aqxu&q9wuvF@T1>aIAW{mfm5=(J7-pfkoM zfZ*W0&|f7cuFLojEH%eJHmv~AJHrEzSp5wOAQJ%ICf`OB;8xJ2&IO?6>2xo9@mrO}etFzf4t{X$~jF^df%O_&R8MqheRm7P0B|>guY-A|ETW z78Iz3I&3K^c{VrC09d6&Fi*tHv)MD=JW)rQr{`uDIa`%wR%Yc3-Jzih)Yo^v3VriN z%fTThPq4KUr_GicD9vy+CuYO^10m36r3rh_Mz+is81bK|sKW&RWh}N2| pSfNW;NN3Vhu-qnzTyT#0{vXNDH(NuB>v{kH002ovPDHLkV1m!$eO~|o diff --git a/icons/Color/scalable/gimp-image-metadata.svg b/icons/Color/scalable/gimp-image-metadata.svg deleted file mode 100644 index 444d76733e..0000000000 --- a/icons/Color/scalable/gimp-image-metadata.svg +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/icons/Legacy/16/gimp-image-metadata.png b/icons/Legacy/16/gimp-image-metadata.png deleted file mode 100644 index dd0bafa2fea659f035f85e80d0e78795ed7d44cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 569 zcmV-90>=G`P)q$gGR5;6xlh11tQ4q&JyZbgxV%juOt62q)=Awt51f@suFHjU) z>e+)A4}xdGgCYnXl~VOmLGU6(Jb5sP9z;P%J*u-USi4$HlahVoVY5k^{?NG$?=kav zZ)U#Zh={U{)$6aL!LtrUMN!mgwOY3v5z!#1YypUbl*^?7fTC#PRq>6_!om|Vg9!jB zEC?!ygk-ZBVjE+v#ddvcWAga|mEhorVHZmwj~>tUe**Zv&-BF^930GG@XnA~u3x*{ zyQ?0XMAf2z%YRr9RJd{T9!0N7$*g0Xqz?dYqtRGN>;IRv)>fD(bjWyMRYAKyC>BTA z4I&cqX6_PMcY|uh;Cq??(0&QEXZN>-h=hE7I>XZPcg|1k=g?RO-&0g=QbHQ&yNXwz z-UJZ|d3pN`51ub_`gnoEMN2RiW8A)~OsX>DDtq@ixTCKSnF8QIc!jeki`3pNaipw3 zoIKWK7@++8-Q>ffWg_zycjP15v3&Zx&aY*Q@iV;tVtYwzaeEkG`4jJaI+yhaTMf{&_xxM<;4T6e2-X z&_yMEXhD=_LRp%g&7CyziwugQp_Sg~{LV#P7x}U2HupU@H>X9m&29cW?<W z{C1u_@4M%>_i*0x98q<3bu7nmpCuAWfMr>11*BFDSEJmo}?=wwU-IPFHJN_{+YZrArie&8(ko@g7C46=TEN+ z5lk91!h*FRbBivW5`+k}`ti*P%C4Ujga|Z~>g57*tVcrTNN=B56(X3>jYSH`t+&?o zZ!SGfd3Gl|6cZXsazil@s5PU}1!Pd@4yq|kK}EqaynUF1s;kL(SDp*`qa|u@rJ?1X zn8u`rYGPPe(8Xp)+*KbRi)sF5{vq7RJBW_TEc(5+@F>mI@n`vi44NY~M#p~$3%=B4 zQU2`*5)W}=NDJaA^0MU6oL&iob6NY)`6NA*BQ-|U--QLkO_>o4NmB5YOTz_m9NO+D zhVng?$!IEyUpAN4P<;~?7+*0ky=Gu-&4jI8j42+=`%IYLFz6~zz}fUzI!DPSL0)`> z#^DGGX53CXINQqLry?6ZZ83tg4G6mH`S>n=_2gi#jX~X&{kWX72aVSbU{;7>Uv5xfcUZwnDsVU#auNYhX+QJwA c#K*h;0s^O7N%8w;mjD0&07*qoM6N<$f{J5<1poj5 diff --git a/icons/Legacy/48/gimp-image-metadata.png b/icons/Legacy/48/gimp-image-metadata.png deleted file mode 100644 index 14a539c1e18a1a768685cc7e479a5981de74501e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1903 zcmV-#2ax!QP)bP;|1K zEGJ7%@lA?al!}Htb<|AJ1%X%<3`{YU0UdK{nsFvGd9ys0$HMZ^3}g|O{ddmYJr@=h z*}H(?nfcGX_nhy${D1e}-Q}L|NF=7_@9*zIbS)qtpo(nK9cA*COtx}K(?&Ws5E;6w zaSJl|`T4D5=7$p1(t+scbEv2&M_pYVx?6kns1{mnDU`}62BGuy^&LV1B56lhSQs=K zjVN_RqZe19P%wya3Aq&-dQenU#G8^xV6|xcy?YfRRgTKaa&o83P+p-$S$QeS%1WRu z)1XwVK}l&b5%E$|h+<6viZp5z7OVOGM|F>Qh`jt<22e!rfSw-I*6Kt9*aFeie7Ru0 zq!sf-#C%~Qq{b9vF$ z(9j@!m<0gZYz24{5Y&8rL5}cQ=x_j*^TCHpI#djTn$J_KtOu}F^c+h+TGC-+0MvZ0 zI=k}$7{sR^FYXXE0%RjM{|Nywh*c}x+bsq_&FAE2JvjgdvHtT#?Ggi^=2dx_PZoed zc&=G!vlsw1ugcBn8h~Bv+-#NrK+I>i1<+ZK(VmS9Y!(Bc=Cg9r+XkRN_Z|6dbYSa( z_Q?c5&1dDLSqIP&5H$bb_WA8rBS0E5RjJkk&?H+SXx_1%^IGVr*IbMJj}rr+<}jS|LV_RZ$EXZE-t+Q+!>vuY|%?T{kGONzr=9E4crgPKpv`bRv#r314C zwFW`^FZ#Ne#VWs*;oX6+!hTFYaCQTr@NzU8KeEXlfgaP~I&~nnEgOeb3r50Y@o0Fj zm}C~md{FbLnGC>SJwRfhi-jx$uoP#QEpA25h#=_lU zki~H(0f3lK&A1~T;Krd@E!6Z~p=p1DpA_GJF+n(>6E622&^Vcys z7ET`k<<2Rs#xNh$yiEXUCpn8sKSdNuq~MTB_HQ4PnvHLEABvF!dt>+Vk*%J?!)*wn zc1&({oT}XbIbkw0j6)b@!j`kSlW07a2fUd2%|Xrg5(jpd-dC`VcRERXH=dgik0HuOC0`7 zbVY6IM%0%E!SLV|8Xkn8z9ay;)D3t*#_q>+xPL*0$`~o1o4nr+FZ6r{CpWx@oKrL5 zGO-Vo+s5)^)<`r!rD^JqC04~aqxu&q9wuvF@T1>aIAW{mfm5=(J7-pfkoM zfZ*W0&|f7cuFLojEH%eJHmv~AJHrEzSp5wOAQJ%ICf`OB;8xJ2&IO?6>2xo9@mrO}etFzf4t{X$~jF^df%O_&R8MqheRm7P0B|>guY-A|ETW z78Iz3I&3K^c{VrC09d6&Fi*tHv)MD=JW)rQr{`uDIa`%wR%Yc3-Jzih)Yo^v3VriN z%fTThPq4KUr_GicD9vy+CuYO^10m36r3rh_Mz+is81bK|sKW&RWh}N2| pSfNW;NN3Vhu-qnzTyT#0{vXNDH(NuB>v{kH002ovPDHLkV1m!$eO~|o diff --git a/icons/Symbolic-Inverted/24/gimp-image-metadata.svg b/icons/Symbolic-Inverted/24/gimp-image-metadata.svg deleted file mode 100644 index a615598f46..0000000000 --- a/icons/Symbolic-Inverted/24/gimp-image-metadata.svg +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/icons/Symbolic/16/gimp-image-metadata.png b/icons/Symbolic/16/gimp-image-metadata.png deleted file mode 100644 index e7fac8f1a2cb70d9ea2d0a8dcd3dae95c76d65ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 461 zcmV;;0W$uHP)YdZ<|KUrZ8J|R_~qn?#I2{BLJY;Z0=zLRVtNX2mq$D z*`p8wj^iMk&0S#Ff$H{ z#iMv4(f1$XhS5(N#9cA)?npE_VjNC88)ZPi@=22Y^&HL00000NkvXXu0mjf D6G0fppLcfGt)(Agw6xGJHe5V-!du}&vk8qC zZ(h85(D)yi7(Y*P@qh4!;YK(~LwfQe30@2h2D)u3Lgb@Or0h)R^-wUSv1u!E^Eu5v zGw<`8nau0}7c2sRLZR@W;rkEU%%6r3m2+kEq zQ%EEno|976h)8IyCk(^51^}+>{s4erFnFukY&xcC_P<4)QcC^4G( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/icons/Symbolic/48/gimp-image-metadata.png b/icons/Symbolic/48/gimp-image-metadata.png deleted file mode 100644 index d25b8e18b1351daffbe059869c7c0ee81ca3e186..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1367 zcmV-d1*rOoP)7N6Gt4!zcah*bpna4MnplSDKRlltb_(bP>}%1 zvLZ#Ukl;_~0rgB@hpGo3t5#|y+FmR5P(fRXR&7fDi&i1ON-4e!m}S$62+YMOe7-iv)-Wf8V%KaIf+E_Yn+*Am-;+Fq=Dg?uJqd z0O0fc(H)N?8jC^Gw1s{l1pc~y9lFP}x+#mWXapF0JTlF}AR0Gq0sxGRj4T?JjD&3O z==fyUjveo;R?w3tPpW+FJYVC;ty>sRCUN`jUECQPd#Yaup$%TTboh^ffsd9sr)%_l zjmZZO@cr@QMRycJXjd*@K797V1-2^^d3#0Dl|WvBQV~LEgBLHpdHU?xfSpQxv0S0D zM5EE4o>jAG3USV%>+YO{5bWyU-~sQtb+5b3w=66YaOUO^YHfvK7_JVIkvM2pSHH2W z=}O?KAMw0xV{1zb48xFa4kUzN*M^2(^HfzGBBF<->?5U|%GtanrM&9qoIrt9Xx_Hb z*3t1{ITFKHuI#U_sW~L26vb*8V~(b2k20H+MD&Pr-s&*cFMq7jAF=Sl4ye z61PW34{X}Jd7+Jn<^c@l))A2bV3vsHiRd53*efi1BXU7O0RVWlv-90;k;n%gkEdjb zn%dgwEuqj`EzQj*gb+8Sl%wf%dXO>pQf?h%j7ur!Ow$}@jI}Ywie@QG0026-Z+|}& z4u5AD20g2`*5{kv(%k&nR5E$DudmPF)zx*)G|e%O#}iRX`EqNC$Wlt#mSr_D#@wwM zZUg|pv8*q{?d{(b8wsD^KhqQld~VIoo(7;RrFJ9|3GO(K=gFx-MAH)!6Q>wsFB^tY zQ*QW@1pr`fcJ`~*wzhBcN!0p$(@lZEk-1dr_iP(utZMJxy&Ge(*tk+^CMUer*w}cc zp`oEp)3nB=gm)zXJeCNyv>Y={b3tN#P0e&uAaKOCte-jOH0ByxhKODu zq8Fu*E0I*Z3qfdnY@1UI5S5;N*9vB!Xc!B!*`qneXb_4L1n*msY zKnbj$oSY06>eMtXtZCYko`!*y6#(aaW1&7NrR({g_Z&;vSt&&T?969AmNY#|p)3I+ zvK+@b-{0SVA{veU+TY)QLesSKN~yWrx^kXv+~Qgw6aKgE?(TbuM1lYykx0HWxyQSCbeNcWJ_ms4ZmGb90 z%g&uU(*T}X@8+1rSkYy4HF)j?3QnOyuk!wHJoh6|5m;*~0&7i0V6CYLtTh#Z3KgDn Z{spZx`ys^({LcUY002ovPDHLkV1f?&iu?co diff --git a/icons/Symbolic/64/gimp-image-metadata.png b/icons/Symbolic/64/gimp-image-metadata.png deleted file mode 100644 index 02a2b12f2342dd451194ccc207d0cccfac4bbd44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1853 zcmV-D2g3M?P)diAwz+rb(@|zOK|4i!{-`+nY_5HuX)BroCjAXASsbsTWhjp)7jYorYLwYGlT5vYSm2pdwa3R zU3vPW>fQKuWni1)e>BzTN&jlPP=iTf}3rgEQ09pWll{e_pp* z3n+O43g3&jCnmrRV`B<@`)$=^@mTC2h(3QXKmWmz!-xNBrqE_lb_#4g0YV5&O-|O7 zFut(RE2aGGySX{zXkXve#w9kF9oK+*NyK8k1pI00&YjPemzKtxQKJ&NuK%r;__Aw& z8N_3;?&!mZ@4G#o)21YB5+w$#=W;lB_^>I-lZiynqxt#w-5$>=QxZ0T5(7BrkeuU~ z&u2=3cr50bk4AshwP(-IOi5@mB?bThHw;rvcoL6y&&|$$;OglKNhzPzkz%>03I)3g(cqL{XS*_8nR(ACxTLvMfoyWT)xx}HJ~r!(&# z9K4)bT>N_^66w@+-7pMeoH6#5qA2@0=O-Csu5x2lRdq%pk)+LLJ3>VEdg@nV*9HK< zLAU#<-Ddku;N;0WwTx@G+YPVZ|K)Nrd5JNm<@5Q|H*VapkBp4u0JL+?4^WhNr_FOJ^bo28X z5%F?krId@huHSaKTzgejHD`BLM9l^O8zv~gr`1ewIGu*q@4vi~N?j`MlTseIa^*^! zuIq*nVz#)Sh*G+)PhGuwRkPV_Z`Px8H`HYS0Aw-S%N z`sB&)q?9E`MMOkSr*kg=xLmGT&iVGj*N_? z0bq1=R1nd%;o;%2^XJb`B$LTmBI=S-zQq_jR_U!#3#PnJbGcmBp(vjWo;vlhqA1hL z$>g7lV;EzaVHn4+U%!4Jo6SyMxNzZnDdnTBej<_pCW^=Dx^4hKI2`WfocoB#)H4jz zlC7?;W|ds-*PQdREBY3SqPQIn$J>!euC9WXW+ko$5!v(k{A<H6+-t@pEHeNAG)>!AErv1H z(@YJP8X%=~T3H`3`BYd4!KIW-05Y3RP9oaF7^}2;HRV*g7EBSqIR|4b>UO(lLZMK; zuMNw922w$!q@@gsfBdM4E!x|bIYT72`RZ#7I zEZqnE7-$(_wE(NBx(}%K8=L=ke)3O1%K)ndSWU|Ss|8q1%K)ndSWU|Ss|8q1%K)nd rSWU|Ss|8q1%K)ndv}n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/icons/icon-list.mk b/icons/icon-list.mk index db71840ccf..5ed962b56f 100644 --- a/icons/icon-list.mk +++ b/icons/icon-list.mk @@ -142,7 +142,6 @@ scalable_images = \ scalable/gimp-histogram.svg \ scalable/gimp-images.svg \ scalable/gimp-image.svg \ - scalable/gimp-image-metadata.svg \ scalable/gimp-image-open.svg \ scalable/gimp-image-reload.svg \ scalable/gimp-info.svg \ @@ -354,7 +353,6 @@ vector24_images = \ 24/gimp-grid.svg \ 24/gimp-histogram.svg \ 24/gimp-image.svg \ - 24/gimp-image-metadata.svg \ 24/gimp-images.svg \ 24/gimp-info.svg \ 24/gimp-landscape.svg \ @@ -607,7 +605,6 @@ icons16_images = \ 16/gimp-histogram-logarithmic.png \ 16/gimp-histogram.png \ 16/gimp-image.png \ - 16/gimp-image-metadata.png \ 16/gimp-images.png \ 16/gimp-image-open.png \ 16/gimp-image-reload.png \ @@ -864,7 +861,6 @@ icons24_images = \ 24/gimp-hchain.png \ 24/gimp-hfill.png \ 24/gimp-image.png \ - 24/gimp-image-metadata.png \ 24/gimp-images.png \ 24/gimp-info.png \ 24/gimp-layer-mask.png \ @@ -974,7 +970,6 @@ icons48_images = \ 48/gimp-channel.png \ 48/gimp-floating-selection.png \ 48/gimp-image.png \ - 48/gimp-image-metadata.png \ 48/gimp-layer-mask.png \ 48/gimp-layer.png \ 48/gimp-prefs-color-management.png \ diff --git a/libgimp/Makefile.am b/libgimp/Makefile.am index dfb0169dee..72ce2b7093 100644 --- a/libgimp/Makefile.am +++ b/libgimp/Makefile.am @@ -222,8 +222,6 @@ libgimp_sources = \ gimpimage.h \ gimpimagecolorprofile.c \ gimpimagecolorprofile.h \ - gimpitem.c \ - gimpitem.h \ gimplayer.c \ gimplayer.h \ gimppalette.c \ @@ -347,7 +345,6 @@ gimpinclude_HEADERS = \ gimpgradientselect.h \ gimpimage.h \ gimpimagecolorprofile.h \ - gimpitem.h \ gimplayer.h \ gimppalette.h \ gimppalettes.h \ diff --git a/libgimp/gimp.def b/libgimp/gimp.def index 066c234ccf..ac546229f5 100644 --- a/libgimp/gimp.def +++ b/libgimp/gimp.def @@ -557,7 +557,6 @@ EXPORTS gimp_item_get_linked gimp_item_get_lock_content gimp_item_get_lock_position - gimp_item_get_metadata gimp_item_get_name gimp_item_get_parasite gimp_item_get_parasite_list @@ -577,7 +576,6 @@ EXPORTS gimp_item_set_linked gimp_item_set_lock_content gimp_item_set_lock_position - gimp_item_set_metadata gimp_item_set_name gimp_item_set_tattoo gimp_item_set_visible diff --git a/libgimp/gimp.h b/libgimp/gimp.h index bf23188f42..0b89b20c0e 100644 --- a/libgimp/gimp.h +++ b/libgimp/gimp.h @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/libgimp/gimpimagemetadata.c b/libgimp/gimpimagemetadata.c index 7115437e8b..559140354e 100644 --- a/libgimp/gimpimagemetadata.c +++ b/libgimp/gimpimagemetadata.c @@ -28,7 +28,6 @@ #include "gimp.h" #include "gimpui.h" #include "gimpimagemetadata.h" -#include "libgimpbase/gimpbase.h" #include "libgimp-intl.h" @@ -45,6 +44,7 @@ static gboolean gimp_image_metadata_rotate_dialog (gint32 image_I GExiv2Orientation orientation, const gchar *parasite_name); + /* public functions */ /** @@ -67,7 +67,7 @@ gimp_image_metadata_load_prepare (gint32 image_ID, GFile *file, GError **error) { - GimpMetadata *metadata; + GimpMetadata *metadata; g_return_val_if_fail (image_ID > 0, NULL); g_return_val_if_fail (mime_type != NULL, NULL); @@ -81,24 +81,18 @@ gimp_image_metadata_load_prepare (gint32 image_ID, #if 0 { gchar *xml = gimp_metadata_serialize (metadata); + GimpMetadata *new = gimp_metadata_deserialize (xml); + gchar *xml2 = gimp_metadata_serialize (new); -// FILE *f = fopen ("/tmp/gimp-test-xml1", "w"); - FILE *f = fopen ("e:\\gimp-test-xml1", "w"); + FILE *f = fopen ("/tmp/gimp-test-xml1", "w"); fprintf (f, "%s", xml); fclose (f); - GimpMetadata *new = gimp_metadata_deserialize (xml); - - gimp_metadata_print (new); - - gchar *xml2 = gimp_metadata_serialize (new); - -// f = fopen ("/tmp/gimp-test-xml2", "w"); - f = fopen ("e:\\gimp-test-xml2", "w"); + f = fopen ("/tmp/gimp-test-xml2", "w"); fprintf (f, "%s", xml2); fclose (f); -// system ("diff -u /tmp/gimp-test-xml1 /tmp/gimp-test-xml2"); + system ("diff -u /tmp/gimp-test-xml1 /tmp/gimp-test-xml2"); g_free (xml); g_free (xml2); @@ -106,7 +100,7 @@ gimp_image_metadata_load_prepare (gint32 image_ID, } #endif - gexiv2_metadata_erase_exif_thumbnail (GEXIV2_METADATA (metadata)); + gexiv2_metadata_erase_exif_thumbnail (metadata); } return metadata; @@ -128,7 +122,6 @@ gimp_image_metadata_load_prepare (gint32 image_ID, */ void gimp_image_metadata_load_finish (gint32 image_ID, - gint32 layer_ID, const gchar *mime_type, GimpMetadata *metadata, GimpMetadataLoadFlags flags, @@ -136,28 +129,17 @@ gimp_image_metadata_load_finish (gint32 image_ID, { g_return_if_fail (image_ID > 0); g_return_if_fail (mime_type != NULL); - g_return_if_fail (IS_GIMP_METADATA(metadata)); - - if (flags & GIMP_METADATA_LOAD_ORIENTATION) - { - gimp_image_metadata_rotate_query (image_ID, mime_type, - metadata, interactive); - } + g_return_if_fail (GEXIV2_IS_METADATA (metadata)); if (flags & GIMP_METADATA_LOAD_COMMENT) { - GimpAttribute *attribute = NULL; - gchar *comment = NULL; + gchar *comment; - attribute = gimp_metadata_get_attribute (metadata, "Exif.Photo.UserComment"); - if (attribute) - comment = gimp_attribute_get_string (attribute); - else - { - attribute = gimp_metadata_get_attribute (metadata, "Exif.Image.ImageDescription"); - if (attribute) - comment = gimp_attribute_get_string (attribute); - } + comment = gexiv2_metadata_get_tag_interpreted_string (metadata, + "Exif.Photo.UserComment"); + if (! comment) + comment = gexiv2_metadata_get_tag_interpreted_string (metadata, + "Exif.Image.ImageDescription"); if (comment) { @@ -173,6 +155,7 @@ gimp_image_metadata_load_finish (gint32 image_ID, gimp_parasite_free (parasite); } } + if (flags & GIMP_METADATA_LOAD_RESOLUTION) { gdouble xres; @@ -186,10 +169,19 @@ gimp_image_metadata_load_finish (gint32 image_ID, } } + if (flags & GIMP_METADATA_LOAD_ORIENTATION) + { + gimp_image_metadata_rotate_query (image_ID, mime_type, + metadata, interactive); + } + if (flags & GIMP_METADATA_LOAD_COLORSPACE) { GimpColorProfile *profile = gimp_image_get_color_profile (image_ID); + /* only look for colorspace information from metadata if the + * image didn't contain an embedded color profile + */ if (! profile) { GimpMetadataColorspace colorspace; @@ -217,11 +209,7 @@ gimp_image_metadata_load_finish (gint32 image_ID, g_object_unref (profile); } - gimp_image_set_metadata (image_ID, metadata); - if (layer_ID > 0) - { - gimp_item_set_metadata (layer_ID, metadata); - } + gimp_image_set_metadata (image_ID, metadata); } /** @@ -231,7 +219,7 @@ gimp_image_metadata_load_finish (gint32 image_ID, * @suggested_flags: Suggested default values for the @flags passed to * gimp_image_metadata_save_finish() * - * Gets the image attributes for saving using + * Gets the image metadata for saving it using * gimp_image_metadata_save_finish(). * * The @suggested_flags are determined from what kind of metadata @@ -239,7 +227,7 @@ gimp_image_metadata_load_finish (gint32 image_ID, * value for GIMP_METADATA_SAVE_THUMBNAIL is determined by whether * there was a thumbnail in the previously imported image. * - * Returns: The image's attributes, prepared for saving. + * Returns: The image's metadata, prepared for saving. * * Since: 2.10 */ @@ -248,7 +236,7 @@ gimp_image_metadata_save_prepare (gint32 image_ID, const gchar *mime_type, GimpMetadataSaveFlags *suggested_flags) { - GimpMetadata *metadata = NULL; + GimpMetadata *metadata; g_return_val_if_fail (image_ID > 0, NULL); g_return_val_if_fail (mime_type != NULL, NULL); @@ -256,36 +244,133 @@ gimp_image_metadata_save_prepare (gint32 image_ID, *suggested_flags = GIMP_METADATA_SAVE_ALL; - /* this is a GimpMetadata XML-Packet - * it is deserialized to a GimpMetadata object. - * Deserialization fills the GExiv2Metadata object of the GimpMetadata*/ metadata = gimp_image_get_metadata (image_ID); if (metadata) { + GDateTime *datetime; + const GimpParasite *comment_parasite; + const gchar *comment = NULL; + gint image_width; + gint image_height; + gdouble xres; + gdouble yres; + gchar buffer[32]; + + image_width = gimp_image_width (image_ID); + image_height = gimp_image_height (image_ID); + + datetime = g_date_time_new_now_local (); + + comment_parasite = gimp_image_get_parasite (image_ID, "gimp-comment"); + if (comment_parasite) + comment = gimp_parasite_data (comment_parasite); + /* Exif */ - if (! gimp_metadata_has_tag_type (metadata, TAG_EXIF)) + if (! gexiv2_metadata_has_exif (metadata)) *suggested_flags &= ~GIMP_METADATA_SAVE_EXIF; + if (comment) + { + gexiv2_metadata_set_tag_string (metadata, + "Exif.Photo.UserComment", + comment); + gexiv2_metadata_set_tag_string (metadata, + "Exif.Image.ImageDescription", + comment); + } + + g_snprintf (buffer, sizeof (buffer), + "%d:%02d:%02d %02d:%02d:%02d", + g_date_time_get_year (datetime), + g_date_time_get_month (datetime), + g_date_time_get_day_of_month (datetime), + g_date_time_get_hour (datetime), + g_date_time_get_minute (datetime), + g_date_time_get_second (datetime)); + gexiv2_metadata_set_tag_string (metadata, + "Exif.Image.DateTime", + buffer); + + gexiv2_metadata_set_tag_string (metadata, + "Exif.Image.Software", + PACKAGE_STRING); + + gimp_metadata_set_pixel_size (metadata, + image_width, image_height); + + gimp_image_get_resolution (image_ID, &xres, &yres); + gimp_metadata_set_resolution (metadata, xres, yres, + gimp_image_get_unit (image_ID)); /* XMP */ - if (! gimp_metadata_has_tag_type (metadata, TAG_XMP)) + if (! gexiv2_metadata_has_xmp (metadata)) *suggested_flags &= ~GIMP_METADATA_SAVE_XMP; + gexiv2_metadata_set_tag_string (metadata, + "Xmp.dc.Format", + mime_type); + + if (! g_strcmp0 (mime_type, "image/tiff")) + { + /* TIFF specific XMP data */ + + g_snprintf (buffer, sizeof (buffer), "%d", image_width); + gexiv2_metadata_set_tag_string (metadata, + "Xmp.tiff.ImageWidth", + buffer); + + g_snprintf (buffer, sizeof (buffer), "%d", image_height); + gexiv2_metadata_set_tag_string (metadata, + "Xmp.tiff.ImageLength", + buffer); + + g_snprintf (buffer, sizeof (buffer), + "%d:%02d:%02d %02d:%02d:%02d", + g_date_time_get_year (datetime), + g_date_time_get_month (datetime), + g_date_time_get_day_of_month (datetime), + g_date_time_get_hour (datetime), + g_date_time_get_minute (datetime), + g_date_time_get_second (datetime)); + gexiv2_metadata_set_tag_string (metadata, + "Xmp.tiff.DateTime", + buffer); + } /* IPTC */ - if (! gimp_metadata_has_tag_type (metadata, TAG_IPTC)) + if (! gexiv2_metadata_has_iptc (metadata)) *suggested_flags &= ~GIMP_METADATA_SAVE_IPTC; + g_snprintf (buffer, sizeof (buffer), + "%d-%d-%d", + g_date_time_get_year (datetime), + g_date_time_get_month (datetime), + g_date_time_get_day_of_month (datetime)); + gexiv2_metadata_set_tag_string (metadata, + "Iptc.Application2.DateCreated", + buffer); + + g_snprintf (buffer, sizeof (buffer), + "%02d:%02d:%02d-%02d:%02d", + g_date_time_get_hour (datetime), + g_date_time_get_minute (datetime), + g_date_time_get_second (datetime), + g_date_time_get_hour (datetime), + g_date_time_get_minute (datetime)); + gexiv2_metadata_set_tag_string (metadata, + "Iptc.Application2.TimeCreated", + buffer); + + g_date_time_unref (datetime); /* Thumbnail */ if (FALSE /* FIXME if (original image had a thumbnail) */) *suggested_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL; - } return metadata; @@ -316,26 +401,17 @@ gimp_image_metadata_save_finish (gint32 image_ID, GFile *file, GError **error) { - GExiv2Metadata *gimpmetadata; - GExiv2Metadata *filemetadata; - GimpMetadata *gexivdata; - gboolean success = FALSE; - gchar buffer[32]; - GDateTime *datetime; - const GimpParasite *comment_parasite; - const gchar *comment = NULL; - gint image_width; - gint image_height; - gdouble xres; - gdouble yres; - gchar *value; - + GExiv2Metadata *new_metadata; gboolean support_exif; gboolean support_xmp; gboolean support_iptc; + gchar *value; + gboolean success = FALSE; + gint i; g_return_val_if_fail (image_ID > 0, FALSE); g_return_val_if_fail (mime_type != NULL, FALSE); + g_return_val_if_fail (GEXIV2_IS_METADATA (metadata), FALSE); g_return_val_if_fail (G_IS_FILE (file), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -345,199 +421,74 @@ gimp_image_metadata_save_finish (gint32 image_ID, GIMP_METADATA_SAVE_THUMBNAIL))) return TRUE; - image_width = gimp_image_width (image_ID); - image_height = gimp_image_height (image_ID); - - datetime = g_date_time_new_now_local (); - - comment_parasite = gimp_image_get_parasite (image_ID, "gimp-comment"); - if (comment_parasite) - comment = gimp_parasite_data (comment_parasite); - /* read metadata from saved file */ - gexivdata = gimp_metadata_load_from_file (file, error); + new_metadata = gimp_metadata_load_from_file (file, error); - if (! gexivdata) + if (! new_metadata) return FALSE; - filemetadata = GEXIV2_METADATA (gexivdata); - gimpmetadata = GEXIV2_METADATA (metadata); + support_exif = gexiv2_metadata_get_supports_exif (new_metadata); + support_xmp = gexiv2_metadata_get_supports_xmp (new_metadata); + support_iptc = gexiv2_metadata_get_supports_iptc (new_metadata); - support_exif = gexiv2_metadata_get_supports_exif (filemetadata); - support_xmp = gexiv2_metadata_get_supports_xmp (filemetadata); - support_iptc = gexiv2_metadata_get_supports_iptc (filemetadata); - - /* Exif */ - - if (flags & GIMP_METADATA_SAVE_EXIF && support_exif) + if ((flags & GIMP_METADATA_SAVE_EXIF) && support_exif) { - gint i; - - gchar **exif_data = gexiv2_metadata_get_exif_tags (gimpmetadata); + gchar **exif_data = gexiv2_metadata_get_exif_tags (metadata); for (i = 0; exif_data[i] != NULL; i++) { - if (! gexiv2_metadata_has_tag (filemetadata, exif_data[i]) && + if (! gexiv2_metadata_has_tag (new_metadata, exif_data[i]) && gimp_metadata_is_tag_supported (exif_data[i], mime_type)) { - value = gexiv2_metadata_get_tag_string (gimpmetadata, exif_data[i]); - gexiv2_metadata_set_tag_string (filemetadata, exif_data[i], + value = gexiv2_metadata_get_tag_string (metadata, exif_data[i]); + gexiv2_metadata_set_tag_string (new_metadata, exif_data[i], value); g_free (value); } } g_strfreev (exif_data); - - if (comment) - { - gimp_metadata_new_attribute (gexivdata, - "Exif.Photo.UserComment", - (gchar *) comment, - TYPE_UNICODE); - gimp_metadata_new_attribute (gexivdata, - "Exif.Image.ImageDescription", - (gchar *) comment, - TYPE_ASCII); - } - - g_snprintf (buffer, sizeof (buffer), - "%d:%02d:%02d %02d:%02d:%02d", - g_date_time_get_year (datetime), - g_date_time_get_month (datetime), - g_date_time_get_day_of_month (datetime), - g_date_time_get_hour (datetime), - g_date_time_get_minute (datetime), - g_date_time_get_second (datetime)); - gimp_metadata_new_attribute (gexivdata, - "Exif.Image.DateTime", - buffer, - TYPE_ASCII); - - gimp_metadata_new_attribute (gexivdata, - "Exif.Image.Software", - PACKAGE_STRING, - TYPE_ASCII); - - gimp_metadata_set_pixel_size (gexivdata, - image_width, image_height); - - gimp_image_get_resolution (image_ID, &xres, &yres); - gimp_metadata_set_resolution (gexivdata, xres, yres, - gimp_image_get_unit (image_ID)); } - /* XMP */ - - if (flags & GIMP_METADATA_SAVE_XMP && support_xmp) + if ((flags & GIMP_METADATA_SAVE_XMP) && support_xmp) { - gint i; - - gchar **xmp_data = gexiv2_metadata_get_xmp_tags (gimpmetadata); + gchar **xmp_data = gexiv2_metadata_get_xmp_tags (metadata); for (i = 0; xmp_data[i] != NULL; i++) { - GimpAttribute *attribute; - - if (! gexiv2_metadata_has_tag (filemetadata, xmp_data[i]) && + if (! gexiv2_metadata_has_tag (new_metadata, xmp_data[i]) && gimp_metadata_is_tag_supported (xmp_data[i], mime_type)) { - /* we need the attribute-value here, because some xmp-tags cannot be read out and stored like exif tags: - * xmp-tags allow structures like lists. These structures need this special handling. */ - attribute = gimp_metadata_get_attribute (metadata, xmp_data[i]); - gimp_metadata_add_attribute (gexivdata, attribute); + value = gexiv2_metadata_get_tag_string (metadata, xmp_data[i]); + gexiv2_metadata_set_tag_string (new_metadata, xmp_data[i], + value); + g_free (value); } } g_strfreev (xmp_data); - - gimp_metadata_new_attribute (gexivdata, - "Xmp.dc.Format", - (gchar *) mime_type, - TYPE_ASCII); - - if (! g_strcmp0 (mime_type, "image/tiff")) - { - /* TIFF specific XMP data */ - - g_snprintf (buffer, sizeof (buffer), "%d", image_width); - gimp_metadata_new_attribute (gexivdata, - "Xmp.tiff.ImageWidth", - buffer, - TYPE_ASCII); - - g_snprintf (buffer, sizeof (buffer), "%d", image_height); - gimp_metadata_new_attribute (gexivdata, - "Xmp.tiff.ImageLength", - buffer, - TYPE_ASCII); - - g_snprintf (buffer, sizeof (buffer), - "%d:%02d:%02d %02d:%02d:%02d", - g_date_time_get_year (datetime), - g_date_time_get_month (datetime), - g_date_time_get_day_of_month (datetime), - g_date_time_get_hour (datetime), - g_date_time_get_minute (datetime), - g_date_time_get_second (datetime)); - gimp_metadata_new_attribute (gexivdata, - "Xmp.tiff.DateTime", - buffer, - TYPE_ASCII); - } } - /* IPTC */ - - if (flags & GIMP_METADATA_SAVE_IPTC && support_iptc) + if ((flags & GIMP_METADATA_SAVE_IPTC) && support_iptc) { - gint i; - - gchar **iptc_data = gexiv2_metadata_get_iptc_tags (gimpmetadata); + gchar **iptc_data = gexiv2_metadata_get_iptc_tags (metadata); for (i = 0; iptc_data[i] != NULL; i++) { - GimpAttribute *attribute; - - if (! gexiv2_metadata_has_tag (filemetadata, iptc_data[i]) && + if (! gexiv2_metadata_has_tag (new_metadata, iptc_data[i]) && gimp_metadata_is_tag_supported (iptc_data[i], mime_type)) { - /* we need the attribute-value here, because iptc-tags of TYPE_MULTIPLE cannot be read out and stored like exif tags: - * These tags need this special handling. */ - attribute = gimp_metadata_get_attribute (metadata, iptc_data[i]); - gimp_metadata_add_attribute (gexivdata, attribute); + value = gexiv2_metadata_get_tag_string (metadata, iptc_data[i]); + gexiv2_metadata_set_tag_string (new_metadata, iptc_data[i], + value); + g_free (value); } } g_strfreev (iptc_data); - - g_snprintf (buffer, sizeof (buffer), - "%d-%d-%d", - g_date_time_get_year (datetime), - g_date_time_get_month (datetime), - g_date_time_get_day_of_month (datetime)); - gimp_metadata_new_attribute (gexivdata, - "Iptc.Application2.DateCreated", - buffer, - TYPE_ASCII); - - g_snprintf (buffer, sizeof (buffer), - "%02d:%02d:%02d", - g_date_time_get_hour (datetime), - g_date_time_get_minute (datetime), - g_date_time_get_second (datetime)); - gimp_metadata_new_attribute (gexivdata, - "Iptc.Application2.TimeCreated", - buffer, - TYPE_ASCII); - - g_date_time_unref (datetime); - } - /* Thumbnail */ - - if ((flags & GIMP_METADATA_SAVE_THUMBNAIL) && g_strcmp0 (mime_type, "image/tiff")) + if (flags & GIMP_METADATA_SAVE_THUMBNAIL) { GdkPixbuf *thumb_pixbuf; gchar *thumb_buffer; @@ -573,27 +524,27 @@ gimp_image_metadata_save_finish (gint32 image_ID, { gchar buffer[32]; - gexiv2_metadata_set_exif_thumbnail_from_buffer (filemetadata, + gexiv2_metadata_set_exif_thumbnail_from_buffer (new_metadata, (guchar *) thumb_buffer, count); g_snprintf (buffer, sizeof (buffer), "%d", thumbw); - gexiv2_metadata_set_tag_string (filemetadata, + gexiv2_metadata_set_tag_string (new_metadata, "Exif.Thumbnail.ImageWidth", buffer); g_snprintf (buffer, sizeof (buffer), "%d", thumbh); - gexiv2_metadata_set_tag_string (filemetadata, + gexiv2_metadata_set_tag_string (new_metadata, "Exif.Thumbnail.ImageLength", buffer); - gexiv2_metadata_set_tag_string (filemetadata, + gexiv2_metadata_set_tag_string (new_metadata, "Exif.Thumbnail.BitsPerSample", "8 8 8"); - gexiv2_metadata_set_tag_string (filemetadata, + gexiv2_metadata_set_tag_string (new_metadata, "Exif.Thumbnail.SamplesPerPixel", "3"); - gexiv2_metadata_set_tag_string (filemetadata, + gexiv2_metadata_set_tag_string (new_metadata, "Exif.Thumbnail.PhotometricInterpretation", "6"); @@ -603,9 +554,9 @@ gimp_image_metadata_save_finish (gint32 image_ID, g_object_unref (thumb_pixbuf); } - success = gimp_metadata_save_to_file (gexivdata, file, error); + success = gimp_metadata_save_to_file (new_metadata, file, error); - g_object_unref (filemetadata); + g_object_unref (new_metadata); return success; } @@ -614,25 +565,21 @@ gint32 gimp_image_metadata_load_thumbnail (GFile *file, GError **error) { - GimpMetadata *metadata; - GExiv2Metadata *gexiv2metadata; - GInputStream *input_stream; - GdkPixbuf *pixbuf; - guint8 *thumbnail_buffer; - gint thumbnail_size; - gint32 image_ID = -1; + GimpMetadata *metadata; + GInputStream *input_stream; + GdkPixbuf *pixbuf; + guint8 *thumbnail_buffer; + gint thumbnail_size; + gint32 image_ID = -1; g_return_val_if_fail (G_IS_FILE (file), -1); g_return_val_if_fail (error == NULL || *error == NULL, -1); metadata = gimp_metadata_load_from_file (file, error); - - gexiv2metadata = GEXIV2_METADATA (metadata); - if (! metadata) return -1; - if (! gexiv2_metadata_get_exif_thumbnail (gexiv2metadata, + if (! gexiv2_metadata_get_exif_thumbnail (metadata, &thumbnail_buffer, &thumbnail_size)) { @@ -664,7 +611,7 @@ gimp_image_metadata_load_thumbnail (GFile *file, gimp_image_insert_layer (image_ID, layer_ID, -1, 0); gimp_image_metadata_rotate (image_ID, - gexiv2_metadata_get_orientation (gexiv2metadata)); + gexiv2_metadata_get_orientation (metadata)); } g_object_unref (metadata); @@ -779,15 +726,12 @@ gimp_image_metadata_rotate_query (gint32 image_ID, GimpMetadata *metadata, gboolean interactive) { - GExiv2Metadata *gexiv2metadata; GimpParasite *parasite; gchar *parasite_name; GExiv2Orientation orientation; gboolean query = interactive; - gexiv2metadata = GEXIV2_METADATA (metadata); - - orientation = gexiv2_metadata_get_orientation (gexiv2metadata); + orientation = gexiv2_metadata_get_orientation (metadata); if (orientation <= GEXIV2_ORIENTATION_NORMAL || orientation > GEXIV2_ORIENTATION_MAX) @@ -827,9 +771,9 @@ gimp_image_metadata_rotate_query (gint32 image_ID, gimp_image_metadata_rotate (image_ID, orientation); - gexiv2_metadata_set_tag_string (gexiv2metadata, + gexiv2_metadata_set_tag_string (metadata, "Exif.Image.Orientation", "1"); - gexiv2_metadata_set_tag_string (gexiv2metadata, + gexiv2_metadata_set_tag_string (metadata, "Xmp.tiff.Orientation", "1"); } diff --git a/libgimp/gimpimagemetadata.h b/libgimp/gimpimagemetadata.h index 1771ec29d5..26d0b71aa1 100644 --- a/libgimp/gimpimagemetadata.h +++ b/libgimp/gimpimagemetadata.h @@ -35,7 +35,6 @@ GimpMetadata * gimp_image_metadata_load_prepare (gint32 image_ID GFile *file, GError **error); void gimp_image_metadata_load_finish (gint32 image_ID, - gint32 layer_ID, const gchar *mime_type, GimpMetadata *metadata, GimpMetadataLoadFlags flags, diff --git a/libgimp/gimpitem.c b/libgimp/gimpitem.c deleted file mode 100644 index ae19d5ded6..0000000000 --- a/libgimp/gimpitem.c +++ /dev/null @@ -1,86 +0,0 @@ -/* LIBGIMP - The GIMP Library - * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball - * - * gimpitem.c - * - * This library 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. - * - * This library 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 this library. If not, see - * . - */ - -#include "config.h" - -#include "gimp.h" -#include "gimpitem.h" - - -/** - * gimp_item_get_metadata: - * @item_ID: The item. - * - * Returns the item's metadata. - * - * Returns metadata from the item. - * - * Returns: The metadata, or %NULL if there is none. - * - * Since: GIMP 2.10 - **/ -GimpMetadata * -gimp_item_get_metadata (gint32 item_ID) -{ - GimpMetadata *metadata = NULL; - gchar *metadata_string; - - metadata_string = _gimp_item_get_metadata (item_ID); - if (metadata_string) - { - metadata = gimp_metadata_deserialize (metadata_string); - g_free (metadata_string); - } - - return metadata; -} - -/** - * gimp_item_set_metadata: - * @item_ID: The item. - * @metadata: The GimpMetadata object. - * - * Set the item's metadata. - * - * Sets metadata on the item, or deletes it if - * @metadata is %NULL. - * - * Returns: TRUE on success. - * - * Since: GIMP 2.10 - **/ -gboolean -gimp_item_set_metadata (gint32 item_ID, - GimpMetadata *metadata) -{ - gchar *metadata_string = NULL; - gboolean success; - - if (metadata) - metadata_string = gimp_metadata_serialize (metadata); - - success = _gimp_item_set_metadata (item_ID, metadata_string); - - if (metadata_string) - g_free (metadata_string); - - return success; -} - diff --git a/libgimp/gimpitem.h b/libgimp/gimpitem.h deleted file mode 100644 index 2b7ecf72d7..0000000000 --- a/libgimp/gimpitem.h +++ /dev/null @@ -1,40 +0,0 @@ -/* LIBGIMP - The GIMP Library - * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball - * - * gimpitem.h - * - * This library 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. - * - * This library 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 this library. If not, see - * . - */ - -#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __GIMP_ITEM_H__ -#define __GIMP_ITEM_H__ - -G_BEGIN_DECLS - -/* For information look into the C source or the html documentation */ - - -gboolean gimp_item_set_metadata (gint32 item_ID, - GimpMetadata *metadata); -GimpMetadata * gimp_item_get_metadata (gint32 item_ID); - - -G_END_DECLS - -#endif /* __GIMP_ITEM_H__ */ diff --git a/libgimp/gimpitem_pdb.c b/libgimp/gimpitem_pdb.c index 2f6803879b..c1a004f551 100644 --- a/libgimp/gimpitem_pdb.c +++ b/libgimp/gimpitem_pdb.c @@ -934,68 +934,6 @@ gimp_item_set_tattoo (gint32 item_ID, return success; } -/** - * _gimp_item_get_metadata: - * @item_ID: The item. - * - * Returns the item's metadata. - * - * Returns metadata from the item. - * - * Returns: The metadata as a xml string. - **/ -gchar * -_gimp_item_get_metadata (gint32 item_ID) -{ - GimpParam *return_vals; - gint nreturn_vals; - gchar *metadata_string = NULL; - - return_vals = gimp_run_procedure ("gimp-item-get-metadata", - &nreturn_vals, - GIMP_PDB_ITEM, item_ID, - GIMP_PDB_END); - - if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS) - metadata_string = g_strdup (return_vals[1].data.d_string); - - gimp_destroy_params (return_vals, nreturn_vals); - - return metadata_string; -} - -/** - * _gimp_item_set_metadata: - * @item_ID: The item. - * @metadata_string: The metadata as a xml string. - * - * Set the item's metadata. - * - * Sets metadata on the item. - * - * Returns: TRUE on success. - **/ -gboolean -_gimp_item_set_metadata (gint32 item_ID, - const gchar *metadata_string) -{ - GimpParam *return_vals; - gint nreturn_vals; - gboolean success = TRUE; - - return_vals = gimp_run_procedure ("gimp-item-set-metadata", - &nreturn_vals, - GIMP_PDB_ITEM, item_ID, - GIMP_PDB_STRING, metadata_string, - GIMP_PDB_END); - - success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS; - - gimp_destroy_params (return_vals, nreturn_vals); - - return success; -} - /** * gimp_item_attach_parasite: * @item_ID: The item. diff --git a/libgimp/gimpitem_pdb.h b/libgimp/gimpitem_pdb.h index a16d0e4563..6b81f0456c 100644 --- a/libgimp/gimpitem_pdb.h +++ b/libgimp/gimpitem_pdb.h @@ -32,52 +32,49 @@ G_BEGIN_DECLS /* For information look into the C source or the html documentation */ -gboolean gimp_item_is_valid (gint32 item_ID); -gint32 gimp_item_get_image (gint32 item_ID); -gboolean gimp_item_delete (gint32 item_ID); -gboolean gimp_item_is_drawable (gint32 item_ID); -gboolean gimp_item_is_layer (gint32 item_ID); -gboolean gimp_item_is_text_layer (gint32 item_ID); -gboolean gimp_item_is_channel (gint32 item_ID); -gboolean gimp_item_is_layer_mask (gint32 item_ID); -gboolean gimp_item_is_selection (gint32 item_ID); -gboolean gimp_item_is_vectors (gint32 item_ID); -gboolean gimp_item_is_group (gint32 item_ID); -gint32 gimp_item_get_parent (gint32 item_ID); -gint* gimp_item_get_children (gint32 item_ID, - gint *num_children); -gchar* gimp_item_get_name (gint32 item_ID); -gboolean gimp_item_set_name (gint32 item_ID, - const gchar *name); -gboolean gimp_item_get_visible (gint32 item_ID); -gboolean gimp_item_set_visible (gint32 item_ID, - gboolean visible); -gboolean gimp_item_get_linked (gint32 item_ID); -gboolean gimp_item_set_linked (gint32 item_ID, - gboolean linked); -gboolean gimp_item_get_lock_content (gint32 item_ID); -gboolean gimp_item_set_lock_content (gint32 item_ID, - gboolean lock_content); -gboolean gimp_item_get_lock_position (gint32 item_ID); -gboolean gimp_item_set_lock_position (gint32 item_ID, - gboolean lock_position); -GimpColorTag gimp_item_get_color_tag (gint32 item_ID); -gboolean gimp_item_set_color_tag (gint32 item_ID, - GimpColorTag color_tag); -gint gimp_item_get_tattoo (gint32 item_ID); -gboolean gimp_item_set_tattoo (gint32 item_ID, - gint tattoo); -G_GNUC_INTERNAL gchar* _gimp_item_get_metadata (gint32 item_ID); -G_GNUC_INTERNAL gboolean _gimp_item_set_metadata (gint32 item_ID, - const gchar *metadata_string); -gboolean gimp_item_attach_parasite (gint32 item_ID, - const GimpParasite *parasite); -gboolean gimp_item_detach_parasite (gint32 item_ID, - const gchar *name); -GimpParasite* gimp_item_get_parasite (gint32 item_ID, - const gchar *name); -gchar** gimp_item_get_parasite_list (gint32 item_ID, - gint *num_parasites); +gboolean gimp_item_is_valid (gint32 item_ID); +gint32 gimp_item_get_image (gint32 item_ID); +gboolean gimp_item_delete (gint32 item_ID); +gboolean gimp_item_is_drawable (gint32 item_ID); +gboolean gimp_item_is_layer (gint32 item_ID); +gboolean gimp_item_is_text_layer (gint32 item_ID); +gboolean gimp_item_is_channel (gint32 item_ID); +gboolean gimp_item_is_layer_mask (gint32 item_ID); +gboolean gimp_item_is_selection (gint32 item_ID); +gboolean gimp_item_is_vectors (gint32 item_ID); +gboolean gimp_item_is_group (gint32 item_ID); +gint32 gimp_item_get_parent (gint32 item_ID); +gint* gimp_item_get_children (gint32 item_ID, + gint *num_children); +gchar* gimp_item_get_name (gint32 item_ID); +gboolean gimp_item_set_name (gint32 item_ID, + const gchar *name); +gboolean gimp_item_get_visible (gint32 item_ID); +gboolean gimp_item_set_visible (gint32 item_ID, + gboolean visible); +gboolean gimp_item_get_linked (gint32 item_ID); +gboolean gimp_item_set_linked (gint32 item_ID, + gboolean linked); +gboolean gimp_item_get_lock_content (gint32 item_ID); +gboolean gimp_item_set_lock_content (gint32 item_ID, + gboolean lock_content); +gboolean gimp_item_get_lock_position (gint32 item_ID); +gboolean gimp_item_set_lock_position (gint32 item_ID, + gboolean lock_position); +GimpColorTag gimp_item_get_color_tag (gint32 item_ID); +gboolean gimp_item_set_color_tag (gint32 item_ID, + GimpColorTag color_tag); +gint gimp_item_get_tattoo (gint32 item_ID); +gboolean gimp_item_set_tattoo (gint32 item_ID, + gint tattoo); +gboolean gimp_item_attach_parasite (gint32 item_ID, + const GimpParasite *parasite); +gboolean gimp_item_detach_parasite (gint32 item_ID, + const gchar *name); +GimpParasite* gimp_item_get_parasite (gint32 item_ID, + const gchar *name); +gchar** gimp_item_get_parasite_list (gint32 item_ID, + gint *num_parasites); G_END_DECLS diff --git a/libgimpbase/Makefile.am b/libgimpbase/Makefile.am index d35c9c031d..c97e68f08d 100644 --- a/libgimpbase/Makefile.am +++ b/libgimpbase/Makefile.am @@ -90,8 +90,6 @@ libgimpbase_sources = \ gimpparam.h \ gimpversion.h \ \ - gimpattribute.c \ - gimpattribute.h \ gimpbase-private.c \ gimpbase-private.h \ gimpchecks.c \ @@ -112,8 +110,6 @@ libgimpbase_sources = \ gimpparasiteio.h \ gimpprotocol.c \ gimpprotocol.h \ - gimprational.c \ - gimprational.h \ gimprectangle.c \ gimprectangle.h \ gimpreloc.c \ @@ -147,7 +143,6 @@ libgimpbaseinclude_HEADERS = \ gimpparam.h \ gimpversion.h \ \ - gimpattribute.h \ gimpchecks.h \ gimpdatafiles.h \ gimpenv.h \ @@ -155,7 +150,6 @@ libgimpbaseinclude_HEADERS = \ gimpmetadata.h \ gimpparasite.h \ gimpparasiteio.h \ - gimprational.h \ gimprectangle.h \ gimpsignal.h \ gimpunit.h \ diff --git a/libgimpbase/gimpattribute.c b/libgimpbase/gimpattribute.c deleted file mode 100644 index 0450b4d2ef..0000000000 --- a/libgimpbase/gimpattribute.c +++ /dev/null @@ -1,2002 +0,0 @@ -/* LIBGIMP - The GIMP Library - * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis - * - * gimpattribute.c - * Copyright (C) 2014 Hartmut Kuhse - * - * This library 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. - * - * This library 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 this library. If not, see - * . - */ - -#include "config.h" - -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include - -#include - -#ifdef G_OS_WIN32 -#endif - -#include "gimpbasetypes.h" -#include "gimpattribute.h" -#include "gimprational.h" - -#define _g_free0(var) (var = (g_free (var), NULL)) -#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL))) -#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) - -typedef struct _TagTime TagTime; -typedef struct _TagDate TagDate; - -struct _TagTime { - int tag_time_sec; - int tag_time_min; - int tag_time_hour; - int tag_tz_hour; - int tag_tz_min; - }; - -struct _TagDate { - int tag_year; - int tag_month; - int tag_day; - }; - - -typedef struct _GimpAttributeClass GimpAttributeClass; -typedef struct _GimpAttributePrivate GimpAttributePrivate; - -struct _GimpAttribute { - GObject parent_instance; - GimpAttributePrivate *priv; -}; - -struct _GimpAttributeClass { - GObjectClass parent_class; -}; - -struct _GimpAttributePrivate { - gchar *name; - gchar *sorted_name; - - gchar *tag_value; - gchar *interpreted_value; - - gchar *exif_type; - - GimpAttributeValueType value_type; - GimpAttributeTagType tag_type; - - gchar *attribute_type; - gchar *attribute_ifd; - gchar *attribute_tag; - gboolean is_new_name_space; - - gboolean has_structure; - GimpAttributeStructureType structure_type; - GSList *attribute_structure; -}; - -enum { - PROP_0, - PROP_NAME, - PROP_LONG_VALUE, - PROP_SLONG_VALUE, - PROP_SHORT_VALUE, - PROP_SSHORT_VALUE, - PROP_DATE_VALUE, - PROP_TIME_VALUE, - PROP_ASCII_VALUE, - PROP_BYTE_VALUE, - PROP_MULTIPLE_VALUE, - PROP_RATIONAL_VALUE, - PROP_SRATIONAL_VALUE -}; - -static const gchar *xmp_namespaces[] = -{ - "dc", - "xmp", - "xmpRights", - "xmpMM", - "xmpBJ", - "xmpTPg", - "xmpDM", - "pdf", - "photoshop", - "crs", - "tiff", - "exif", - "aux", - "plus", - "digiKam", - "iptc", - "iptcExt", - "Iptc4xmpCore", - "Iptc4xmpExt", - "MicrosoftPhoto", - "kipi", - "mediapro", - "expressionmedia", - "MP", - "MPRI", - "MPReg", - "mwg-rs" -}; - - -static gpointer gimp_attribute_parent_class = NULL; -static gint counter = 0; - - -static GimpAttribute* gimp_attribute_construct (GType object_type, - const gchar *name); -static void gimp_attribute_finalize (GObject *obj); -static void gimp_attribute_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void gimp_attribute_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_attribute_set_name (GimpAttribute *attribute, - const gchar *value); -static gboolean get_tag_time (gchar *input, - TagTime *tm); -static gboolean get_tag_date (gchar *input, - TagDate *dt); -static gchar * gimp_attribute_escape_value (gchar *name, - gchar *value, - gboolean *encoded); -static gchar * gimp_attribute_get_structure_number (gchar *cptag, - gint start, - gint *struct_number); - -static gchar* string_replace_str (const gchar *original, - const gchar *old_pattern, - const gchar *replacement); -static gint string_index_of (gchar *haystack, - gchar *needle, - gint start_index); -static glong string_strnlen (gchar *str, - glong maxlen); -static gchar* string_substring (gchar *attribute, - glong offset, - glong len); - - -/** - * gimp_attribute_new_string: - * - * @name: a constant #gchar that describes the name of the attribute - * @value: a #gchar value, representing a time - * @type: a #GimpAttributeTagType - * - * Creates a new #GimpAttribute object with @name as name and a #gchar @value - * as value of type @type. - * @value is converted to the correct type. - * - * Return value: a new @GimpAttribute - * - * Since: 2.10 - */ -GimpAttribute* -gimp_attribute_new_string (const gchar *name, - gchar *value, - GimpAttributeValueType type) -{ - GimpAttribute *attribute = NULL; - GimpAttributePrivate *private; - - attribute = gimp_attribute_construct (GIMP_TYPE_ATTRIBUTE, name); - if (attribute) - { - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - private->tag_value = g_strdup (value); - private->value_type = type; - } - - return attribute; -} - -/** - * gimp_attribute_get_name: - * - * @attribute: a @GimpAttribute - * - * Return value: full name of the #GimpAttribute object - * e.g. "Exif.Image.XResolution" - * - * Since: 2.10 - */ -const gchar* -gimp_attribute_get_name (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, NULL); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - return (const gchar *) private->name; -} - -/** - * gimp_attribute_get_sortable_name: - * - * @attribute: a @GimpAttribute - * - * Return value: name of the #GimpAttribute object for sorting - * e.g. from tag: - * "xmp.xmpMM.History[2]..." - * it returns: - * "xmp.xmpMM.History[000002]..." - * - * Since: 2.10 - */ -const gchar* -gimp_attribute_get_sortable_name (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, NULL); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - if (private->sorted_name) - return (const gchar *) private->sorted_name; - else - return (const gchar *) private->name; -} - -/** - * gimp_attribute_get_attribute_type: - * - * @attribute: a @GimpAttribute - * - * Return value: attribute type of the #GimpAttribute object - * e.g. "exif", "iptc", ... - * - * Since: 2.10 - */ -const gchar* -gimp_attribute_get_attribute_type (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, NULL); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - return (const gchar *) private->attribute_type; -} - -/** - * gimp_attribute_get_attribute_ifd: - * - * @attribute: a @GimpAttribute - * - * Return value: ifd of the #GimpAttribute object - * - * Since: 2.10 - */ -const gchar* -gimp_attribute_get_attribute_ifd (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, NULL); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - return (const gchar *) private->attribute_ifd; -} - -/** - * gimp_attribute_get_attribute_tag: - * - * @attribute: a @GimpAttribute - * - * Return value: tag of the #GimpAttribute object - * - * Since: 2.10 - */ -const gchar* -gimp_attribute_get_attribute_tag (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, NULL); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - return (const gchar *) private->attribute_tag; -} - -/** - * gimp_attribute_set_value_type: - * - * @attribute: a @GimpAttribute - * @value_type: a @GimpAttributeValueType - * - * sets value type of the #GimpAttribute object - * - * Since: 2.10 - */ -void -gimp_attribute_set_value_type (GimpAttribute* attribute, - GimpAttributeValueType value_type) -{ - GimpAttributePrivate *private; - g_return_if_fail (attribute != NULL); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - private->value_type = value_type; -} - -/** - * gimp_attribute_get_value_type: - * - * @attribute: a @GimpAttribute - * - * Return value: value type of the #GimpAttribute object - * - * Since: 2.10 - */ -GimpAttributeValueType -gimp_attribute_get_value_type (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, TYPE_INVALID); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - return private->value_type; -} - -/** - * gimp_attribute_get_attribute_structure: - * - * @attribute: a @GimpAttribute - * - * Return value: attribute_structure of the #GimpAttribute object - * This is the start value of a xmpBag sequence. - * - * Since: 2.10 - */ -GSList * -gimp_attribute_get_attribute_structure (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, NULL); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - return private->attribute_structure; -} -/** - * gimp_attribute_is_new_namespace: - * - * @attribute: a @GimpAttribute - * - * Return value: if namespace must be defined or not - * - * Since: 2.10 - */ -const gboolean -gimp_attribute_is_new_namespace (GimpAttribute* attribute) -{ - GimpAttributePrivate *private; - g_return_val_if_fail (attribute != NULL, FALSE); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - return (const gboolean) private->is_new_name_space; -} - -/** - * gimp_attribute_get_value: - * - * @attribute: a @GimpAttribute - * - * Return value: #GValue of the #GimpAttribute object - * The type of value is represented by glib-types - * - * Since: 2.10 - */ -GValue -gimp_attribute_get_value (GimpAttribute *attribute) -{ - GimpAttributePrivate *private; - GValue val = G_VALUE_INIT; - gchar *value_string; - - g_return_val_if_fail(GIMP_IS_ATTRIBUTE (attribute), val); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - value_string = private->tag_value; - - switch (private->value_type) - { - case TYPE_LONG: - { - g_value_init (&val, G_TYPE_ULONG); - g_value_set_ulong (&val, (gulong) atol (value_string)); - } - break; - case TYPE_SLONG: - { - g_value_init (&val, G_TYPE_LONG); - g_value_set_long (&val, (glong) atol (value_string)); - } - break; - case TYPE_SHORT: - { - g_value_init (&val, G_TYPE_UINT); - g_value_set_uint (&val, (guint) atoi (value_string)); - } - break; - case TYPE_SSHORT: - { - g_value_init (&val, G_TYPE_INT); - g_value_set_int (&val, (gint) atoi (value_string)); - } - break; - case TYPE_DATE: - { - g_value_init (&val, G_TYPE_STRING); - g_value_set_string (&val, value_string); - } - break; - case TYPE_TIME: - { - g_value_init (&val, G_TYPE_STRING); - g_value_set_string (&val, value_string); - } - break; - case TYPE_ASCII: - { - g_value_init (&val, G_TYPE_STRING); - g_value_set_string (&val, value_string); - } - break; - case TYPE_UNICODE: - { - g_value_init (&val, G_TYPE_STRING); - g_value_set_string (&val, value_string); - } - break; - case TYPE_BYTE: - { - g_value_init (&val, G_TYPE_UCHAR); - g_value_set_uchar (&val, value_string[0]); - } - break; - case TYPE_MULTIPLE: - { - gchar **result; - - g_value_init (&val, G_TYPE_STRV); - result = g_strsplit (value_string, "\n", 0); - g_value_set_boxed (&val, result); - } - break; - case TYPE_RATIONAL: - { - gchar **nom; - gchar **rats; - gint count; - gint i; - Rational *rval; - GArray *rational_array; - - rats = g_strsplit (value_string, " ", -1); - - count = 0; - while (rats[count]) - count++; - - rational_array = g_array_new (TRUE, TRUE, sizeof (RationalValue)); - - for (i = 0; i < count; i++) - { - RationalValue or; - - nom = g_strsplit (rats[i], "/", 2); - - if (nom[0] && nom[1]) - { - or.nom = (guint) atoi (nom [0]); - or.denom = (guint) atoi (nom [1]); - } - else - count--; - - rational_array = g_array_append_val (rational_array, or); - - g_strfreev (nom); - } - - rval = g_slice_new (Rational); - - rval->rational_array = rational_array; - rval->length = count; - - g_value_init (&val, GIMP_TYPE_RATIONAL); - g_value_set_boxed (&val, rval); - - g_strfreev (rats); - } - break; - case TYPE_SRATIONAL: - { - gchar **nom; - gchar **srats; - gint count; - gint i; - SRational *srval; - GArray *srational_array; - - srats = g_strsplit (value_string, " ", -1); - - count = 0; - while (srats[count]) - count++; - - srational_array = g_array_new (TRUE, TRUE, sizeof (SRationalValue)); - - for (i = 0; i < count; i++) - { - SRationalValue or; - - nom = g_strsplit (srats[i], "/", 2); - - if (nom[0] && nom[1]) - { - or.nom = (gint) atoi (nom [0]); - or.denom = (guint) atoi (nom [1]); - } - else - count--; - - srational_array = g_array_append_val (srational_array, or); - - g_strfreev (nom); - } - - srval = g_slice_new (SRational); - - srval->srational_array = srational_array; - srval->length = count; - - g_value_init (&val, GIMP_TYPE_SRATIONAL); - g_value_set_boxed (&val, srval); - - g_strfreev (srats); - } - break; - case TYPE_UNKNOWN: - default: - break; - } - - return val; -} - -/** - * gimp_attribute_get_string: - * - * @attribute: a @GimpAttribute - * - * Return value: newly allocated #gchar string representation of the #GimpAttribute object. - * The return is always a valid value according to the #GimpAttributeValueType - * - * Since: 2.10 - */ -gchar* -gimp_attribute_get_string (GimpAttribute *attribute) -{ - GimpAttributePrivate *private; - gchar *val = NULL; - TagDate dt = {0}; - TagTime tm = {0}; - - g_return_val_if_fail(GIMP_IS_ATTRIBUTE (attribute), NULL); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - switch (private->value_type) - { - case TYPE_INVALID: - break; - case TYPE_LONG: - { - val = g_strdup_printf ("%lu", (gulong) atol (private->tag_value)); - } - break; - case TYPE_SLONG: - { - val = g_strdup_printf ("%ld", (glong) atol (private->tag_value)); - } - break; - case TYPE_FLOAT: - { - val = g_strdup_printf ("%.5f", (gfloat) atof (private->tag_value)); - } - break; - case TYPE_DOUBLE: - { - val = g_strdup_printf ("%.6f", (gdouble) atof (private->tag_value)); - } - break; - case TYPE_SHORT: - { - val = g_strdup_printf ("%u", (gushort) atoi (private->tag_value)); - } - break; - case TYPE_SSHORT: - { - val = g_strdup_printf ("%d", (gshort) atoi (private->tag_value)); - } - break; - case TYPE_DATE: - { - get_tag_date (private->tag_value, &dt); - - val = g_strdup_printf ("%4d-%02d-%02d", dt.tag_year, - dt.tag_month, - dt.tag_day); - } - break; - case TYPE_TIME: - { - gchar *tz_h = NULL; - get_tag_time (private->tag_value, &tm); - - tz_h = tm.tag_tz_hour < 0 ? - g_strdup_printf ("-%02d", tm.tag_tz_hour) : - g_strdup_printf ("+%02d", tm.tag_tz_hour); - - val = g_strdup_printf ("%02d:%02d:%02d%s:%02d", tm.tag_time_hour, - tm.tag_time_min, - tm.tag_time_sec, - tz_h, - tm.tag_tz_min); - g_free (tz_h); - } - break; - case TYPE_ASCII: - { - val = g_strdup (private->tag_value); - } - break; - case TYPE_UNICODE: - { - val = g_strdup (private->tag_value); - } - break; - case TYPE_BYTE: - { - val = g_strdup_printf ("%c", private->tag_value[0]); - } - break; - case TYPE_MULTIPLE: - { - val = g_strdup (private->tag_value); - } - break; - case TYPE_RATIONAL: - { - gint i; - GString *string; - Rational *rational; - - string_to_rational (private->tag_value, &rational); - - string = g_string_new (NULL); - - for (i = 0; i < rational->length; i++) - { - RationalValue or; - - or = g_array_index (rational->rational_array, RationalValue, i); - - g_string_append_printf (string, "%u/%u ", - or.nom, - or.denom); - } - g_string_truncate (string, string->len-1); - val = g_string_free (string, FALSE); - } - break; - case TYPE_SRATIONAL: - { - gint i; - GString *string; - SRational *srational; - - string_to_srational (private->tag_value, &srational); - - string = g_string_new (NULL); - - for (i = 0; i < srational->length; i++) - { - SRationalValue or; - - or = g_array_index (srational->srational_array, SRationalValue, i); - - g_string_append_printf (string, "%u/%u ", - or.nom, - or.denom); - } - - g_string_truncate (string, string->len-1); - val = g_string_free (string, FALSE); - } - break; - case TYPE_UNKNOWN: - default: - break; - } - return val; -} - -/** - * gimp_attribute_get_interpreted_string: - * - * @attribute: a #GimpAttribute - * - * returns the interpreted value or the pure string, if no - * interpreted value is found - * - * Since: 2.10 - */ -const gchar * -gimp_attribute_get_interpreted_string (GimpAttribute *attribute) -{ - GimpAttributePrivate *private; - - g_return_val_if_fail(GIMP_IS_ATTRIBUTE (attribute), NULL); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - if (private->interpreted_value) - return (const gchar *) private->interpreted_value; - else - return (const gchar *) private->tag_value; -} - -/** - * gimp_attribute_set_interpreted_string: - * - * @attribute: a #GimpAttribute - * @value: a constant #gchar - * - * sets the interpreted string of the #GimpAttribute object to - * a @value - * - * @value can be freed after - * - * Since: 2.10 - */ -void -gimp_attribute_set_interpreted_string (GimpAttribute* attribute, const gchar* value) -{ - GimpAttributePrivate *private; - - g_return_if_fail(GIMP_IS_ATTRIBUTE (attribute)); - g_return_if_fail (value != NULL); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - private->interpreted_value = g_strdup (value); -} - -/** - * gimp_attribute_get_tag_type: - * - * @attribute: a @GimpAttribute - * - * - * Return value: #GimpAttributeTagType - * The tag type of the Attribute - * - * Since: 2.10 - */ -GimpAttributeTagType -gimp_attribute_get_tag_type (GimpAttribute *attribute) -{ - GimpAttributePrivate *private; - - g_return_val_if_fail (attribute != NULL, TAG_INVALID); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - return private->tag_type; -} - -void -gimp_attribute_print (GimpAttribute *attribute) -{ - const gchar *tag; - const gchar *interpreted; - gchar *value; - - g_return_if_fail(GIMP_IS_ATTRIBUTE (attribute)); - - tag = gimp_attribute_get_name (attribute); - value = gimp_attribute_get_string (attribute); - interpreted = gimp_attribute_get_interpreted_string (attribute); - - g_print ("---\n%p\nTag: %s\n\tValue:%s\n\tInterpreted value:%s\n", attribute, tag, value, interpreted); - -} - -/** - * gimp_attribute_get_gps_degree: - * - * @attribute: a @GimpAttribute - * - * returns the degree representation of the #GimpAttribute GPS value, - * -999.9 otherwise. - * - * Return value: #gdouble degree representation of the #GimpAttributes GPS value - * - * Since: 2.10 - */ -gdouble -gimp_attribute_get_gps_degree (GimpAttribute *attribute) -{ - gdouble return_val; - GimpAttributePrivate *private; - - g_return_val_if_fail (attribute != NULL, TAG_INVALID); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - if (private->value_type == TYPE_RATIONAL) - { - gint i; - gdouble r_val = 0.0; - Rational *rational; - - string_to_rational (private->tag_value, &rational); - - for (i = 0; i < rational->length; i++) - { - RationalValue or; - - or = g_array_index (rational->rational_array, RationalValue, i); - - r_val = (gfloat)or.nom / (gfloat)or.denom; - - if (i == 0) - return_val = r_val; - else if (i == 1) - return_val = return_val + (r_val / 60); - else if (i == 2) - return_val = return_val + (r_val / 3600); - else return -999.9; - } - - return return_val; - } - else - return -999.9; - -} - -/** - * gimp_attribute_get_xml: - * - * @attribute: a @GimpAttribute - * - * returns the xml representation of the #GimpAttribute - * in form: - * - * - * value - * [interpreted value] - * - * - * Return value: #gchar xml representation of the #GimpAttribute object - * - * Since: 2.10 - */ -gchar* -gimp_attribute_get_xml (GimpAttribute *attribute) -{ - gchar *v_escaped = NULL; - gchar *i_escaped = NULL; - gchar *interpreted_tag_elem = NULL; - gboolean is_interpreted = FALSE; - gboolean encoded; - gchar *start_tag_elem; - gchar *end_tag_elem; - gchar *value_tag_elem; - gchar *struct_tag_elem = NULL; - gboolean utf = TRUE; - GimpAttributePrivate *private; - GString *xml; - - g_return_val_if_fail (GIMP_IS_ATTRIBUTE (attribute), NULL); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - xml = g_string_new (NULL); - - if(private->interpreted_value && g_strcmp0 (private->tag_value, private->interpreted_value)) - { - is_interpreted = TRUE; - } - - v_escaped = gimp_attribute_escape_value (private->name, private->tag_value, &encoded); - - start_tag_elem = g_strdup_printf (" \n", private->name, private->value_type); - end_tag_elem = g_strdup_printf (" "); - - g_string_append (xml, start_tag_elem); - - if (encoded) - { - value_tag_elem = g_strdup_printf (" %s\n", v_escaped); - } - else - { - value_tag_elem = g_strdup_printf (" %s\n", v_escaped); - } - - g_string_append (xml, value_tag_elem); - - if (private->has_structure) - { - struct_tag_elem = g_strdup_printf (" %d\n", private->structure_type); - g_string_append (xml, struct_tag_elem); - } - - if (is_interpreted && utf) - { - i_escaped = gimp_attribute_escape_value (private->name, private->interpreted_value, &encoded); - - if (encoded) - { - interpreted_tag_elem = g_strdup_printf (" %s\n", i_escaped); - } - else - { - interpreted_tag_elem = g_strdup_printf (" %s\n", i_escaped); - } - - g_string_append (xml, interpreted_tag_elem); - } - - g_string_append (xml, end_tag_elem); - - g_free (v_escaped); - g_free (start_tag_elem); - g_free (end_tag_elem); - g_free (value_tag_elem); - if (i_escaped) - g_free (i_escaped); - if (interpreted_tag_elem) - g_free (interpreted_tag_elem); - if (struct_tag_elem) - g_free (interpreted_tag_elem); - - return g_string_free (xml, FALSE); -} - -/** - * gimp_attribute_get_value_type_from_string: - * - * @exiv_tag_type_string: a @gchar - * - * converts a string representation tag type from gexiv2/exiv2 - * to a #GimpAttributeValueType - * - * Return value: #GimpAttributeValueType - * - * Since: 2.10 - */ -GimpAttributeValueType -gimp_attribute_get_value_type_from_string (const gchar* string) -{ - GimpAttributeValueType type; - gchar *lowchar; - - if (! string) - return TYPE_INVALID; - - lowchar = g_ascii_strdown (string, -1); - - if (!g_strcmp0 (lowchar, "invalid")) - type = TYPE_INVALID; - else if (!g_strcmp0 (lowchar, "byte")) - type = TYPE_BYTE; - else if (!g_strcmp0 (lowchar, "ascii")) - type = TYPE_ASCII; - else if (!g_strcmp0 (lowchar, "short")) - type = TYPE_SHORT; - else if (!g_strcmp0 (lowchar, "long")) - type = TYPE_LONG; - else if (!g_strcmp0 (lowchar, "rational")) - type = TYPE_RATIONAL; - else if (!g_strcmp0 (lowchar, "sbyte")) - type = TYPE_BYTE; - else if (!g_strcmp0 (lowchar, "undefined")) - type = TYPE_ASCII; - else if (!g_strcmp0 (lowchar, "sshort")) - type = TYPE_SSHORT; - else if (!g_strcmp0 (lowchar, "slong")) - type = TYPE_SLONG; - else if (!g_strcmp0 (lowchar, "srational")) - type = TYPE_SRATIONAL; - else if (!g_strcmp0 (lowchar, "float")) - type = TYPE_FLOAT; - else if (!g_strcmp0 (lowchar, "double")) - type = TYPE_DOUBLE; - else if (!g_strcmp0 (lowchar, "ifd")) - type = TYPE_ASCII; - else if (!g_strcmp0 (lowchar, "string")) - type = TYPE_UNICODE; - else if (!g_strcmp0 (lowchar, "date")) - type = TYPE_DATE; - else if (!g_strcmp0 (lowchar, "time")) - type = TYPE_TIME; - else if (!g_strcmp0 (lowchar, "comment")) - type = TYPE_UNICODE; - else if (!g_strcmp0 (lowchar, "directory")) - type = TYPE_UNICODE; - else if (!g_strcmp0 (lowchar, "xmptext")) - type = TYPE_ASCII; - else if (!g_strcmp0 (lowchar, "xmpalt")) - type = TYPE_MULTIPLE; - else if (!g_strcmp0 (lowchar, "xmpbag")) - type = TYPE_MULTIPLE; - else if (!g_strcmp0 (lowchar, "xmpseq")) - type = TYPE_MULTIPLE; - else if (!g_strcmp0 (lowchar, "langalt")) - type = TYPE_MULTIPLE; - else - type = TYPE_INVALID; - - g_free (lowchar); - - return type; -} - -/** - * gimp_attribute_is_valid: - * - * @attribute: a @GimpAttribute - * - * checks, if @attribute is valid. - * A @GimpAttribute is valid, if the @GimpAttributeValueType - * has a valid entry. - * - * Return value: @gboolean: TRUE if valid, FALSE otherwise - * - * Since: 2.10 - */ -gboolean -gimp_attribute_is_valid (GimpAttribute *attribute) -{ - GimpAttributePrivate *private; - - g_return_val_if_fail (attribute != NULL, FALSE); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - if (private->value_type == TYPE_INVALID) - return FALSE; - else - return TRUE; -} - -/* - * internal functions - */ - -/** - * gimp_attribute_set_name: - * - * @attribute: a #GimpAttribute - * @value: a constant #gchar - * - * sets the name of the #GimpAttribute object to - * a @value - * - * @value can be freed after - * - * Since: 2.10 - */ -static void -gimp_attribute_set_name (GimpAttribute* attribute, const gchar* value) -{ - gchar **split_name; - gchar *lowchar; - GimpAttributePrivate *private; - - g_return_if_fail (attribute != NULL); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - _g_free0 (private->name); - - private->name = g_strdup (value); - - private->name = string_replace_str (private->name, "Iptc4xmpExt", "iptcExt"); - private->name = string_replace_str (private->name, "Iptc4xmpCore", "iptc"); - -// if (! g_strcmp0 (private->name, "Exif.Image.ResolutionUnit")) -// { -// g_print ("found: %s\n", private->name); -// } - - split_name = g_strsplit (private->name, ".", 3); - - if (split_name [0]) - private->attribute_type = split_name [0]; - if (split_name [1]) - private->attribute_ifd = split_name [1]; - if (split_name [2]) - private->attribute_tag = split_name [2]; - - attribute->priv->is_new_name_space = FALSE; - - lowchar = g_ascii_strdown (private->attribute_type, -1); - - if (!g_strcmp0 (lowchar, "exif")) - { - private->tag_type = TAG_EXIF; - } - else if (!g_strcmp0 (lowchar, "xmp")) - { - gint j; - gint p1 = 0; - gint p2 = 0; - gboolean is_known = FALSE; - gchar *structure_tag_name = NULL; - - structure_tag_name = g_strdup (private->name); - - private->tag_type = TAG_XMP; - - while (p2 != -1) - { - p2 = string_index_of (structure_tag_name, "[", p1); - - if (p2 > -1) - { - gchar *struct_string = NULL; - gint struct_number; - - private->has_structure = TRUE; - private->structure_type = STRUCTURE_TYPE_BAG; /* there's no way to get the real type from gexiv2 */ - - struct_string = string_substring (structure_tag_name, 0, p2); - private->attribute_structure = g_slist_prepend (private->attribute_structure, struct_string); - structure_tag_name = gimp_attribute_get_structure_number (structure_tag_name, p2, &struct_number); - - p1 = p2 + 1; - } - } - - if (g_strcmp0 (private->name, structure_tag_name)) - private->sorted_name = structure_tag_name; - else - private->sorted_name = NULL; - - for (j = 0; j < G_N_ELEMENTS (xmp_namespaces); j++) - { - if (! g_strcmp0 (private->attribute_ifd, xmp_namespaces[j])) - { - is_known = TRUE; - break; - } - } - if (! is_known) - { - private->is_new_name_space = TRUE; - } - } - else if (!g_strcmp0 (lowchar, "iptc")) - { - private->tag_type = TAG_IPTC; - } - else if (!g_strcmp0 (lowchar, "gimp")) - { - private->tag_type = TAG_GIMP; - } - else - { - private->tag_type = TAG_MISC; - } - - g_free (lowchar); -} - -/** - * gimp_attribute_set_structure_type: - * - * @attribute: a #GimpAttribute - * @value: a GimpAttributeStructureType - * - * Sets the structure type, Bag, Seq, None, etc. - * The structure is not checked. - * The structure type is only relevant for - * GimpAttribute, that are part of a structure. - * - * Since : 2.10 - */ -void -gimp_attribute_set_structure_type (GimpAttribute *attribute, - GimpAttributeStructureType value) -{ - GimpAttributePrivate *private; - - g_return_if_fail (attribute != NULL); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - private->structure_type = value; -} - -/** - * gimp_attribute_get_structure_type: - * - * @attribute: a #GimpAttribute - * - * The structure type, Bag, Seq, None, etc. - * Return value: a #GimpAttributeStructureType - * - * Since : 2.10 - */ -GimpAttributeStructureType -gimp_attribute_get_structure_type (GimpAttribute *attribute) -{ - GimpAttributePrivate *private; - - g_return_val_if_fail (attribute != NULL, STRUCTURE_TYPE_NONE); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - return private->structure_type; - -} - -/** - * gimp_attribute_has_structure: - * - * @attribute: a #GimpAttribute - * - * Return value: TRUE, if @attribute is part - * of a structure. - * - * Since : 2.10 - */ -gboolean -gimp_attribute_has_structure (GimpAttribute *attribute) -{ - GimpAttributePrivate *private; - - g_return_val_if_fail (attribute != NULL, FALSE); - - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - return private->has_structure; -} - -/** - * gimp_attribute_escape_value: - * - * @name: a gchar * - * @value: a gchar* - * @encoded: a pointer to a gboolean - * - * converts @value into an escaped string for GMarkup. - * If @value is not valid UTF-8, it is converted - * into a base64 coded string and @encoded is set to TRUE, - * otherwise FALSE - * - * Return value: a new allocated @gchar * - * - * Since : 2.10 - */ -static gchar * -gimp_attribute_escape_value (gchar *name, - gchar *value, - gboolean *encoded) -{ - - if (!g_utf8_validate (value, -1, NULL)) - { - gchar *enc_val = NULL; - - *encoded = TRUE; - enc_val = g_base64_encode ((const guchar *) value, - strlen (value) + 1); - - return enc_val; - } - *encoded = FALSE; - - return g_markup_escape_text (value, -1); -} - -/** - * gimp_attribute_copy: - * - * @attribute: a #GimpAttribute - * - * duplicates a #GimpAttribute object - * - * Return value: a new @GimpAttribute or %NULL - * - * Since : 2.10 - */ -GimpAttribute* -gimp_attribute_copy (GimpAttribute *attribute) -{ - GimpAttribute *new_attribute = NULL; - GimpAttributePrivate *private; - GimpAttributePrivate *new_private; - - g_return_val_if_fail (GIMP_IS_ATTRIBUTE (attribute), NULL); - - new_attribute = (GimpAttribute*) g_object_new (GIMP_TYPE_ATTRIBUTE, NULL); - - if (new_attribute) - { - private = GIMP_ATTRIBUTE_GET_PRIVATE(attribute); - new_private = GIMP_ATTRIBUTE_GET_PRIVATE(new_attribute); - if (private->name) - new_private->name = g_strdup (private->name); - - if (private->tag_value) - new_private->tag_value = g_strdup (private->tag_value); - - if (private->interpreted_value) - new_private->interpreted_value = g_strdup (private->interpreted_value); - - if (private->exif_type) - new_private->exif_type = g_strdup (private->exif_type); - - if (private->attribute_type) - new_private->attribute_type = g_strdup (private->attribute_type); - - if (private->attribute_ifd) - new_private->attribute_ifd = g_strdup (private->attribute_ifd); - - if (private->attribute_tag) - new_private->attribute_tag = g_strdup (private->attribute_tag); - - new_private->is_new_name_space = private->is_new_name_space; - new_private->value_type = private->value_type; - new_private->tag_type = private->tag_type; - - return new_attribute; - } - - return NULL; -} - -/** - * gimp_attribute_construct: - * - * @object_type: a #GType - * @name: a constant #gchar that describes the name of the attribute - * - * constructs a new #GimpAttribute object - * - * Return value: a new @GimpAttribute or %NULL if no @name is set - * - * Since : 2.10 - */ -static GimpAttribute* -gimp_attribute_construct (GType object_type, - const gchar *name) -{ - GimpAttribute * attribute = NULL; - - g_return_val_if_fail (name != NULL, NULL); - - attribute = (GimpAttribute*) g_object_new (object_type, NULL); - if (attribute) - { - gimp_attribute_set_name (attribute, name); - } - return attribute; -} - -/** - * gimp_attribute_class_init: - * - * class initializer - */ -static void -gimp_attribute_class_init (GimpAttributeClass * klass) -{ - gimp_attribute_parent_class = g_type_class_peek_parent (klass); - g_type_class_add_private (klass, sizeof(GimpAttributePrivate)); - - G_OBJECT_CLASS (klass)->get_property = gimp_attribute_get_property; - G_OBJECT_CLASS (klass)->set_property = gimp_attribute_set_property; - G_OBJECT_CLASS (klass)->finalize = gimp_attribute_finalize; -} - -/** - * gimp_attribute_instance_init: - * - * instance initializer - */ -static void -gimp_attribute_instance_init (GimpAttribute * attribute) -{ - GimpAttributePrivate *private; - attribute->priv = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - private->name = NULL; - private->sorted_name = NULL; - private->tag_value = NULL; - private->interpreted_value = NULL; - private->exif_type = NULL; - private->value_type = TYPE_INVALID; - private->attribute_type = NULL; - private->attribute_ifd = NULL; - private->attribute_tag = NULL; - private->attribute_structure = NULL; - private->is_new_name_space = FALSE; - private->has_structure = FALSE; - private->structure_type = STRUCTURE_TYPE_NONE; -} - -/** - * gimp_attribute_finalize: - * - * instance finalizer - */ -static void -gimp_attribute_finalize (GObject* obj) -{ - GimpAttribute *attribute; - GimpAttributePrivate *private; - - g_return_if_fail (GIMP_IS_ATTRIBUTE (obj)); - - attribute = GIMP_ATTRIBUTE (obj); - private = GIMP_ATTRIBUTE_GET_PRIVATE (attribute); - - counter++; - - if(private->name) - _g_free0 (private->name); - - if(private->sorted_name) - _g_free0 (private->sorted_name); - - if(private->tag_value) - _g_free0 (private->tag_value); - - if(private->interpreted_value) - _g_free0 (private->interpreted_value); - - if(private->exif_type) - _g_free0 (private->exif_type); - - if(private->attribute_type) - _g_free0 (private->attribute_type); - - if(private->attribute_ifd) - _g_free0 (private->attribute_ifd); - - if(private->attribute_tag) - _g_free0 (private->attribute_tag); - - if(private->attribute_structure) - g_slist_free_full (private->attribute_structure, g_free); - - G_OBJECT_CLASS (gimp_attribute_parent_class)->finalize (obj); - obj = NULL; -} - -/** - * gimp_attribute_get_property - * - * instance get property - */ -static void -gimp_attribute_get_property (GObject * object, - guint property_id, - GValue * value, - GParamSpec * pspec) -{ -} - -/** - * gimp_attribute_set_property - * - * instance set property - */ -static void -gimp_attribute_set_property (GObject * object, - guint property_id, - const GValue * value, - GParamSpec * pspec) -{ -} - -static gchar * -gimp_attribute_get_structure_number (gchar *cptag, gint start, gint *number) -{ - gint p1; - gchar *tag; - gchar *new_tag; - gchar *oldnr; - gchar *newnr; - - start++; - - tag = g_strdup (cptag); - - p1 = string_index_of (tag, "]", start); - - if (p1 > -1) - { - gchar *number_string = NULL; - gint len; - - len = p1-start; - - number_string = string_substring (tag, start, len); - - *number = atoi (number_string); - - oldnr = g_strdup_printf ("[%d]", *number); - newnr = g_strdup_printf ("[%06d]", *number); - new_tag = string_replace_str (tag, oldnr, newnr); - - g_free (oldnr); - g_free (newnr); - g_free (tag); - g_free (number_string); - - return new_tag; - } - else - { - *number = -1; - return NULL; - } - -} - -/** - * gimp_attribute_get_type - * - * Return value: #GimpAttribute type - */ -GType -gimp_attribute_get_type (void) -{ - static volatile gsize gimp_attribute_type_id__volatile = 0; - if (g_once_init_enter(&gimp_attribute_type_id__volatile)) - { - static const GTypeInfo g_define_type_info = - { sizeof(GimpAttributeClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gimp_attribute_class_init, - (GClassFinalizeFunc) NULL, - NULL, - sizeof(GimpAttribute), - 0, - (GInstanceInitFunc) gimp_attribute_instance_init, - NULL - }; - - GType gimp_attribute_type_id; - gimp_attribute_type_id = g_type_register_static (G_TYPE_OBJECT, - "GimpAttribute", - &g_define_type_info, - 0); - - g_once_init_leave(&gimp_attribute_type_id__volatile, - gimp_attribute_type_id); - } - return gimp_attribute_type_id__volatile; -} - - -/* - * Helper functions - */ - -/** - * get_tag_time: - * - * @input: a #gchar array - * @tm: a pointer to a #TagTime struct - * - * converts a ISO 8601 IPTC Time to a TagTime structure - * Input is: - * HHMMSS - * HHMMSS:HHMM - * - * Return value: #gboolean for success - * - * Since: 2.10 - */ -static gboolean -get_tag_time (gchar *input, TagTime *tm) -{ - long val; - GString *string = NULL; - gchar *tmpdate; - gboolean flong; - - g_return_val_if_fail (input != NULL, FALSE); - - input = g_strstrip (input); - - if (*input == '\0' || !g_ascii_isdigit (*input)) - return FALSE; - - string = g_string_new (NULL); - - val = strtoul (input, (char **)&input, 10); - - if (val < 25) /* HH:MM:SS+/-HH:MM */ - { - flong = FALSE; - g_string_append_printf (string, "%02ld", val); - } - else - { - flong = TRUE; - g_string_append_printf (string, "%06ld", val); - } - - - if (! flong) /* exactly 2 times */ - { - input++; - val = strtoul (input, (char **)&input, 10); - g_string_append_printf (string, "%02ld", val); - input++; - val = strtoul (input, (char **)&input, 10); - g_string_append_printf (string, "%02ld", val); - } - - tmpdate = g_string_free (string, FALSE); - - val = strtoul (tmpdate, (char **)&tmpdate, 10); - - /* hhmmss */ - - tm->tag_time_sec = val % 100; - tm->tag_time_min = (val % 10000) / 100; - tm->tag_time_hour = val / 10000; - - string = g_string_new (NULL); - - if (flong) /* :HHSS for time zone */ - { - val = 0L; - - if (*input == ':') - { - input++; - val = strtoul (input, (char **)&input, 10); - } - g_string_append_printf (string, "%05ld", val); - } - else - { - val = 0L; - - if (*input == '+' || *input == '-') /* +/- HH:MM for time zone */ - { - val = strtoul (input, (char **)&input, 10); - g_string_append_printf (string, "%02ld", val); - input++; - val = strtoul (input, (char **)&input, 10); - g_string_append_printf (string, "%02ld", val); - } - else - { - g_string_append_printf (string, "%04ld", val); - } - } - - tmpdate = g_string_free (string, FALSE); - - val = strtoul (tmpdate, (char **)&tmpdate, 10); - - tm->tag_tz_min = (val % 100) / 100; - tm->tag_tz_hour = val / 100; - - return *input == '\0'; -} - -/** - * get_tag_date: - * - * @input: a #gchar array - * @dt: a pointer to a #TagDate struct - * - * converts a ISO 8601 IPTC Date to a TagDate structure - * Input is: - * CCYYMMDD - * - * Return value: #gboolean for success - * - * Since: 2.10 - */ -static gboolean -get_tag_date (gchar *input, TagDate *dt) -{ - long val; - GString *string = NULL; - gchar *tmpdate; - gboolean eod; - - g_return_val_if_fail (input != NULL, FALSE); - - input = g_strstrip (input); - - if (*input == '\0' || !g_ascii_isdigit (*input)) - return FALSE; - - string = g_string_new (NULL); - eod = FALSE; - - while (! eod) - { - val = strtoul (input, (char **)&input, 10); - - if (*input == '-' || - *input == ':') - { - input++; - } - else - { - eod = TRUE; - } - - if (val < 10) - g_string_append_printf (string, "%02ld", val); - else - g_string_append_printf (string, "%ld", val); - } - tmpdate = g_string_free (string, FALSE); - - val = strtoul (tmpdate, (char **)&tmpdate, 10); - - /* YYYYMMDD */ - dt->tag_day = val % 100; - dt->tag_month = (val % 10000) / 100; - dt->tag_year = val / 10000; - - return *input == '\0'; -} - -/** - * string_replace_str: - * - * @original: the original string - * @old_pattern: the pattern to replace - * @replacement: the replacement - * - * replaces @old_pattern by @replacement in @original - * This routine is copied from VALA. - * - * Return value: the new string. - * - * Since: 2.10 - */ -static gchar* -string_replace_str (const gchar* original, const gchar* old_pattern, const gchar* replacement) { - gchar *result = NULL; - GError *_inner_error_ = NULL; - - g_return_val_if_fail (original != NULL, NULL); - g_return_val_if_fail (old_pattern != NULL, NULL); - g_return_val_if_fail (replacement != NULL, NULL); - - { - GRegex *regex = NULL; - const gchar *_tmp0_ = NULL; - gchar *_tmp1_ = NULL; - gchar *_tmp2_ = NULL; - GRegex *_tmp3_ = NULL; - GRegex *_tmp4_ = NULL; - gchar *_tmp5_ = NULL; - GRegex *_tmp6_ = NULL; - const gchar *_tmp7_ = NULL; - gchar *_tmp8_ = NULL; - gchar *_tmp9_ = NULL; - - _tmp0_ = old_pattern; - _tmp1_ = g_regex_escape_string (_tmp0_, -1); - _tmp2_ = _tmp1_; - _tmp3_ = g_regex_new (_tmp2_, 0, 0, &_inner_error_); - _tmp4_ = _tmp3_; - _g_free0 (_tmp2_); - regex = _tmp4_; - - if (_inner_error_ != NULL) - { - if (_inner_error_->domain == G_REGEX_ERROR) - { - goto __catch0_g_regex_error; - } - g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); - g_clear_error (&_inner_error_); - return NULL; - } - - _tmp6_ = regex; - _tmp7_ = replacement; - _tmp8_ = g_regex_replace_literal (_tmp6_, original, (gssize) (-1), 0, _tmp7_, 0, &_inner_error_); - _tmp5_ = _tmp8_; - - if (_inner_error_ != NULL) - { - _g_regex_unref0 (regex); - if (_inner_error_->domain == G_REGEX_ERROR) - { - goto __catch0_g_regex_error; - } - _g_regex_unref0 (regex); - g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); - g_clear_error (&_inner_error_); - return NULL; - } - - _tmp9_ = _tmp5_; - _tmp5_ = NULL; - result = _tmp9_; - _g_free0 (_tmp5_); - _g_regex_unref0 (regex); - return result; - } - - goto __finally0; - __catch0_g_regex_error: - { - GError* e = NULL; - e = _inner_error_; - _inner_error_ = NULL; - g_assert_not_reached (); - _g_error_free0 (e); - } - - __finally0: - if (_inner_error_ != NULL) - { - g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); - g_clear_error (&_inner_error_); - return NULL; - } -} - -/** - * string_index_of: - * - * @haystack: a #gchar - * @needle: a #gchar - * @start_index: a #gint - * - * - * Return value: #gint that points to the position - * of @needle in @haystack, starting at @start_index, - * or -1, if @needle is not found - * - * Since: 2.10 - */ -static gint -string_index_of (gchar* haystack, gchar* needle, gint start_index) -{ - gint result = 0; - gchar* temp1_ = NULL; - g_return_val_if_fail (haystack != NULL, -1); - g_return_val_if_fail (needle != NULL, -1); - temp1_ = strstr (((gchar*) haystack) + start_index, needle); - if (temp1_ != NULL) - { - result = (gint) (temp1_ - ((gchar*) haystack)); - return result; - } - else - { - result = -1; - return result; - } -} - -/** - * string_strnlen: - * - * @str: a #gchar - * @maxlen: a #glong - * - * Returns the length of @str or @maxlen, if @str - * is longer that @maxlen - * - * Return value: #glong - * - * Since: 2.10 - */ -static glong -string_strnlen (gchar* str, glong maxlen) -{ - glong result = 0L; - gchar* temp1_ = NULL; - temp1_ = memchr (str, 0, (gsize) maxlen); - if (temp1_ == NULL) - { - return maxlen; - } - else - { - result = (glong) (temp1_ - str); - return result; - } -} - -/** - * string_substring: - * - * @string: a #gchar - * @offset: a #glong - * @len: a #glong - * - * Returns a substring of @string, starting at @offset - * with a legth of @len - * - * Return value: #gchar to be freed if no longer use - * - * Since: 2.10 - */ -static gchar* -string_substring (gchar* string, glong offset, glong len) -{ - gchar* result = NULL; - glong string_length = 0L; - gboolean _tmp0_ = FALSE; - g_return_val_if_fail(string != NULL, NULL); - if (offset >= ((glong) 0)) - { - _tmp0_ = len >= ((glong) 0); - } - else - { - _tmp0_ = FALSE; - } - - if (_tmp0_) - { - string_length = string_strnlen ((gchar*) string, offset + len); - } - else - { - string_length = (glong) strlen (string); - } - - if (offset < ((glong) 0)) - { - offset = string_length + offset; - g_return_val_if_fail (offset >= ((glong ) 0), NULL); - } - else - { - g_return_val_if_fail (offset <= string_length, NULL); - } - if (len < ((glong) 0)) - { - len = string_length - offset; - } - - g_return_val_if_fail ((offset + len) <= string_length, NULL); - result = g_strndup (((gchar*) string) + offset, (gsize) len); - return result; -} diff --git a/libgimpbase/gimpattribute.h b/libgimpbase/gimpattribute.h deleted file mode 100644 index c4b3a15f3e..0000000000 --- a/libgimpbase/gimpattribute.h +++ /dev/null @@ -1,97 +0,0 @@ -/* gimpattribute.h generated by valac 0.24.0, the Vala compiler, do not modify */ - - -#ifndef __GIMPATTRIBUTE_H__ -#define __GIMPATTRIBUTE_H__ - -#include - -G_BEGIN_DECLS - -#define GIMP_TYPE_ATTRIBUTE (gimp_attribute_get_type ()) -#define GIMP_ATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ATTRIBUTE, GimpAttribute)) -#define GIMP_ATTRIBUTE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ATTRIBUTE, GimpAttributeClass)) -#define GIMP_IS_ATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ATTRIBUTE)) -#define GIMP_IS_ATTRIBUTE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_ATTRIBUTE)) -#define GIMP_ATTRIBUTE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_ATTRIBUTE, GimpAttributeClass)) -#define GIMP_ATTRIBUTE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GIMP_TYPE_ATTRIBUTE, GimpAttributePrivate)) - -#define GIMP_TYPE_ATTRIBUTE_TAG_TYPE (gimp_attribute_tag_type_get_type ()) - -GType gimp_attribute_tag_type_get_type (void) G_GNUC_CONST; - -typedef enum { - TYPE_INVALID, - TYPE_LONG, - TYPE_SLONG, - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_SHORT, - TYPE_SSHORT, - TYPE_DATE, - TYPE_TIME, - TYPE_ASCII, - TYPE_UNICODE, - TYPE_BYTE, - TYPE_MULTIPLE, - TYPE_RATIONAL, - TYPE_SRATIONAL, - TYPE_UNKNOWN, - NUM_VALUE_TYPES -} GimpAttributeValueType; - -typedef enum { - STRUCTURE_TYPE_BAG, - STRUCTURE_TYPE_SEQ, - STRUCTURE_TYPE_ALT, - STRUCTURE_TYPE_LANG, - STRUCTURE_TYPE_NONE, - STRUCTURE_TYPE_STRUCT, - NUM_STRUCTURE_TYPES -} GimpAttributeStructureType; - -typedef enum { - TAG_INVALID, - TAG_EXIF, - TAG_XMP, - TAG_IPTC, - TAG_GIMP, - TAG_MISC, - NUM_TAG_TYPES -} GimpAttributeTagType; - -GType gimp_attribute_get_type (void) G_GNUC_CONST; - -GimpAttribute* gimp_attribute_new_string (const gchar *name, - gchar *value, - GimpAttributeValueType type); -const gchar* gimp_attribute_get_interpreted_string (GimpAttribute *attribute); -void gimp_attribute_set_interpreted_string (GimpAttribute *attribute, - const gchar *value); -GimpAttribute* gimp_attribute_copy (GimpAttribute *attribute); -gboolean gimp_attribute_is_valid (GimpAttribute *attribute); -const gchar* gimp_attribute_get_attribute_type (GimpAttribute *attribute); -const gchar* gimp_attribute_get_attribute_ifd (GimpAttribute *attribute); -const gchar* gimp_attribute_get_attribute_tag (GimpAttribute *attribute); -const gboolean gimp_attribute_is_new_namespace (GimpAttribute *attribute); -const gchar* gimp_attribute_get_name (GimpAttribute *attribute); -const gchar* gimp_attribute_get_sortable_name (GimpAttribute *attribute); -GValue gimp_attribute_get_value (GimpAttribute *attribute); -gchar* gimp_attribute_get_string (GimpAttribute *attribute); -GimpAttributeTagType gimp_attribute_get_tag_type (GimpAttribute *attribute); -GimpAttributeValueType gimp_attribute_get_value_type_from_string (const gchar *string); -GimpAttributeValueType gimp_attribute_get_value_type (GimpAttribute *attribute); -void gimp_attribute_set_value_type (GimpAttribute *attribute, - GimpAttributeValueType value_type); -gboolean gimp_attribute_has_structure (GimpAttribute *attribute); -GSList* gimp_attribute_get_attribute_structure (GimpAttribute *attribute); -void gimp_attribute_set_structure_type (GimpAttribute *attribute, - GimpAttributeStructureType value); -GimpAttributeStructureType gimp_attribute_get_structure_type (GimpAttribute *attribute); -gdouble gimp_attribute_get_gps_degree (GimpAttribute *attribute); -gchar* gimp_attribute_get_xml (GimpAttribute *attribute); -void gimp_attribute_print (GimpAttribute *attribute); - -G_END_DECLS - -#endif diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def index f3395f9157..5897ed882b 100644 --- a/libgimpbase/gimpbase.def +++ b/libgimpbase/gimpbase.def @@ -1,29 +1,6 @@ EXPORTS gimp_add_mask_type_get_type gimp_any_to_utf8 - gimp_attribute_copy - gimp_attribute_get_attribute_type - gimp_attribute_get_attribute_ifd - gimp_attribute_get_attribute_structure - gimp_attribute_get_attribute_tag - gimp_attribute_get_interpreted_string - gimp_attribute_get_name - gimp_attribute_get_sortable_name - gimp_attribute_get_string - gimp_attribute_get_structure_type - gimp_attribute_get_tag_type - gimp_attribute_get_value - gimp_attribute_get_value_type - gimp_attribute_get_value_type_from_string - gimp_attribute_get_gps_degree - gimp_attribute_get_xml - gimp_attribute_has_structure - gimp_attribute_is_valid - gimp_attribute_new_string - gimp_attribute_print - gimp_attribute_set_interpreted_string - gimp_attribute_set_structure_type - gimp_attribute_set_value_type gimp_base_init gimp_blend_mode_get_type gimp_brush_generated_shape_get_type @@ -93,36 +70,21 @@ EXPORTS gimp_memsize_to_string gimp_merge_type_get_type gimp_message_handler_type_get_type - gimp_metadata_add_attribute gimp_metadata_deserialize gimp_metadata_duplicate - gimp_metadata_get_attribute gimp_metadata_get_colorspace gimp_metadata_get_resolution - gimp_metadata_get_table - gimp_metadata_get_type - gimp_metadata_has_attribute - gimp_metadata_has_tag_type gimp_metadata_is_tag_supported - gimp_metadata_iter_init - gimp_metadata_iter_next gimp_metadata_load_from_file gimp_metadata_new - gimp_metadata_new_attribute - gimp_metadata_new_gexiv2metadata - gimp_metadata_print - gimp_metadata_remove_attribute - gimp_metadata_has_attribute + gimp_metadata_save_to_file gimp_metadata_serialize gimp_metadata_set_bits_per_sample gimp_metadata_set_colorspace - gimp_metadata_save_to_file gimp_metadata_set_from_exif gimp_metadata_set_from_xmp gimp_metadata_set_pixel_size gimp_metadata_set_resolution - gimp_metadata_size - gimp_metadata_to_xmp_packet gimp_micro_version gimp_minor_version gimp_offset_type_get_type @@ -248,5 +210,3 @@ EXPORTS gp_tile_ack_write gp_tile_data_write gp_tile_req_write - rational_free - srational_free diff --git a/libgimpbase/gimpbase.h b/libgimpbase/gimpbase.h index f60bef7bb6..a5682e7e98 100644 --- a/libgimpbase/gimpbase.h +++ b/libgimpbase/gimpbase.h @@ -23,7 +23,6 @@ #include -#include #include #include #include diff --git a/libgimpbase/gimpbasetypes.h b/libgimpbase/gimpbasetypes.h index d05d80c2f2..bef9904842 100644 --- a/libgimpbase/gimpbasetypes.h +++ b/libgimpbase/gimpbasetypes.h @@ -45,8 +45,6 @@ G_BEGIN_DECLS #endif -typedef struct _GimpAttribute GimpAttribute; -typedef struct _GimpMetadata GimpMetadata; typedef struct _GimpParasite GimpParasite; typedef struct _GimpDatafileData GimpDatafileData; typedef struct _GimpEnumDesc GimpEnumDesc; @@ -57,6 +55,7 @@ typedef struct _GimpValueArray GimpValueArray; typedef void (* GimpDatafileLoaderFunc) (const GimpDatafileData *file_data, gpointer user_data); +typedef struct _GExiv2Metadata GimpMetadata; /** diff --git a/libgimpbase/gimpmetadata.c b/libgimpbase/gimpmetadata.c index d1f360f285..8da75a7145 100644 --- a/libgimpbase/gimpmetadata.c +++ b/libgimpbase/gimpmetadata.c @@ -22,10 +22,6 @@ #include "config.h" -#include -#ifdef HAVE_UNISTD_H -#include -#endif #include #include @@ -34,8 +30,6 @@ #include "libgimpmath/gimpmath.h" -#include "gimprational.h" -#include "gimpattribute.h" #include "gimpbasetypes.h" #include "gimplimits.h" @@ -44,78 +38,24 @@ #include "libgimp/libgimp-intl.h" -typedef struct _GimpMetadataClass GimpMetadataClass; -typedef struct _GimpMetadataPrivate GimpMetadataPrivate; -struct _GimpMetadataPrivate { - GHashTable *attribute_table; - GHashTable *sorted_to_attribute; - GList *sorted_key_list; - GSList *xmp_structure_list; +/** + * SECTION: gimpmetadata + * @title: gimpmetadata + * @short_description: Basic functions for handling #GimpMetadata objects. + * @see_also: gimp_image_metadata_load_prepare(), + * gimp_image_metadata_load_finish(), + * gimp_image_metadata_load_prepare(), + * gimp_image_metadata_load_finish(). + * + * Basic functions for handling #GimpMetadata objects. + **/ -}; -struct _GimpMetadata { - GExiv2Metadata parent_instance; - GimpMetadataPrivate *priv; -}; +static GQuark gimp_metadata_error_quark (void); +static void gimp_metadata_add (GimpMetadata *src, + GimpMetadata *dest); -struct _GimpMetadataClass { - GExiv2MetadataClass parent_class; -}; - -static gpointer gimpmetadata_parent_class = NULL; -static GimpAttribute *current_attribute = NULL; -static gboolean iter_initialized = FALSE; - -static void gimp_metadata_finalize (GObject *obj); -static void gimp_metadata_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void gimp_metadata_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static GimpAttribute * gimp_metadata_get_attribute_sorted (GimpMetadata *metadata, - const gchar *sorted_name); -static void gimp_metadata_deserialize_error (GMarkupParseContext *context, - GError *error, - gpointer user_data); -static GQuark gimp_metadata_error_quark (void); -static void gimp_metadata_deserialize_start_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error); -static void gimp_metadata_deserialize_text (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error); -static void gimp_metadata_deserialize_end_element (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error); -static const gchar* gimp_metadata_name_to_value (const gchar **attribute_names, - const gchar **attribute_values, - const gchar *name); -static gboolean has_xmp_structure (GSList *xmp_list, - const gchar *entry); -GExiv2Metadata * gimp_metadata_new_gexiv2metadata (void); -GimpAttribute * gimp_metadata_from_parent (GimpMetadata *metadata, - const gchar *name); -void gimp_metadata_to_parent (GimpMetadata *metadata, - GimpAttribute *attribute); -void gimp_metadata_add_attribute_to_list (GimpMetadata *metadata, - GimpAttribute *attribute); -void gimp_metadata_from_gexiv2 (GimpMetadata *metadata); -void gimp_metadata_to_gexiv2 (GimpMetadata *metadata); - -G_DEFINE_TYPE (GimpMetadata, gimp_metadata, GEXIV2_TYPE_METADATA) - -#define parent_class gimp_metadata_parent_class static const gchar *tiff_tags[] = { @@ -152,6 +92,7 @@ static const gchar *unsupported_tags[] = "Exif.Image.ClipPath", "Exif.Image.XClipPathUnits", "Exif.Image.YClipPathUnits", + "Xmp.xmpMM.History", "Exif.Image.XPTitle", "Exif.Image.XPComment", "Exif.Image.XPAuthor", @@ -159,7 +100,8 @@ static const gchar *unsupported_tags[] = "Exif.Image.XPSubject", "Exif.Image.DNGVersion", "Exif.Image.DNGBackwardVersion", - "Exif.Iop"}; + "Exif.Iop" +}; static const guint8 minimal_exif[] = { @@ -200,170 +142,53 @@ static const guint8 wilber_jpg[] = static const guint wilber_jpg_len = G_N_ELEMENTS (wilber_jpg); -typedef struct -{ - gchar name[1024]; - gboolean base64; - GimpAttributeValueType type; - GimpMetadata *metadata; -} GimpMetadataParseData; - -struct Namespaces{ - const gchar *namespace_name; - const gchar *namespace_URI; -}; - -struct Namespaces namespaces_table[] = { - {"gimp", "http://www.gimp.org/ns/2.10/" }, - {"dwc", "http://rs.tdwg.org/dwc/terms/" }, - {"lr", "http://ns.adobe.com/lr/1.0/" }, - {"gpano", "http://ns.google.com/photos/1.0/panorama/" }, - {"panorama", "http://ns.adobe.com/photoshop/1.0/panorama-profile/" } - -}; - - -static void gimp_metadata_class_init (GimpMetadataClass * klass) -{ - gimpmetadata_parent_class = g_type_class_peek_parent (klass); - g_type_class_add_private (klass, sizeof(GimpMetadataPrivate)); - - G_OBJECT_CLASS (klass)->get_property = gimp_metadata_get_property; - G_OBJECT_CLASS (klass)->set_property = gimp_metadata_set_property; - G_OBJECT_CLASS (klass)->finalize = gimp_metadata_finalize; -} - -static void gimp_metadata_init (GimpMetadata * self) -{ - self->priv = GIMP_METADATA_GET_PRIVATE (self); - self->priv->attribute_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - self->priv->sorted_to_attribute = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - self->priv->sorted_key_list = NULL; - self->priv->xmp_structure_list = NULL; -} - -/** - * gimp_metadata_finalize: - * - * instance finalizer - */ -static void -gimp_metadata_finalize (GObject* obj) -{ - GimpMetadata * metadata; - - metadata = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_GIMP_METADATA, GimpMetadata); - - g_hash_table_unref (metadata->priv->attribute_table); - g_hash_table_unref (metadata->priv->sorted_to_attribute); - g_list_free_full (metadata->priv->sorted_key_list, (GDestroyNotify) g_free); - g_slist_free (metadata->priv->xmp_structure_list); - - G_OBJECT_CLASS (gimpmetadata_parent_class)->finalize (obj); -} - -/** - * gimp_metadata_get_property - * - * instance get property - */ -static void -gimp_metadata_get_property (GObject * object, - guint property_id, - GValue * value, - GParamSpec * pspec) -{ -} - -/** - * gimp_metadata_set_property - * - * instance set property - */ -static void -gimp_metadata_set_property (GObject * object, - guint property_id, - const GValue * value, - GParamSpec * pspec) -{ -} /** * gimp_metadata_new: * - * returns a new #GimpMetadata object + * Creates a new #GimpMetadata instance. * - * Return value: a new @GimpMetadata object + * Return value: The new #GimpMetadata. * - * Since : 2.10 + * Since: 2.10 */ GimpMetadata * gimp_metadata_new (void) { - GimpMetadata *new_metadata = NULL; - gint i; + GExiv2Metadata *metadata = NULL; if (gexiv2_initialize ()) { - new_metadata = g_object_new (TYPE_GIMP_METADATA, NULL); + metadata = gexiv2_metadata_new (); - if (gexiv2_initialize ()) + if (! gexiv2_metadata_open_buf (metadata, wilber_jpg, wilber_jpg_len, + NULL)) { - if (gexiv2_metadata_open_buf (GEXIV2_METADATA (new_metadata), wilber_jpg, wilber_jpg_len, - NULL)) - { - for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) - { - struct Namespaces n_space = namespaces_table[i]; - gexiv2_metadata_register_xmp_namespace (n_space.namespace_URI, n_space.namespace_name); - } - } + g_object_unref (metadata); + return NULL; } - - return new_metadata; - } - else - { - return NULL; - } -} -/** - * gimp_metadata_size: ToDo handle size - * - * @metadata: a #GimpMetadata - * - * Return value: a #gint: amount of #GimpAttribute objects in - * the #GimpMetadata container - * - * Since : 2.10 - */ -gint -gimp_metadata_size (GimpMetadata *metadata) -{ - GimpMetadataPrivate *private = GIMP_METADATA_GET_PRIVATE (metadata); - - return g_hash_table_size (private->attribute_table); + return metadata; } /** * gimp_metadata_duplicate: + * @metadata: The object to duplicate, or %NULL. * - * @metadata: a #GimpMetadata + * Duplicates a #GimpMetadata instance. * - * Duplicates the #GimpMetadata object with all the #GimpAttribute objects - * Return value: a copy of the @metadata object + * Return value: The new #GimpMetadata, or %NULL if @metadata is %NULL. * - * Since : 2.10 + * Since: 2.10 */ GimpMetadata * gimp_metadata_duplicate (GimpMetadata *metadata) { - GimpMetadata * new_metadata = NULL; + GimpMetadata *new_metadata = NULL; - g_return_val_if_fail (IS_GIMP_METADATA (metadata), NULL); + g_return_val_if_fail (metadata == NULL || GEXIV2_IS_METADATA (metadata), NULL); if (metadata) { @@ -371,1948 +196,23 @@ gimp_metadata_duplicate (GimpMetadata *metadata) xml = gimp_metadata_serialize (metadata); new_metadata = gimp_metadata_deserialize (xml); + g_free (xml); } return new_metadata; } -/** - * gimp_metadata_get_table: - * - * @metadata: a #GimpMetadata - * - * Return value: the #GHashTable - * - * Since : 2.10 - */ -GHashTable * -gimp_metadata_get_table (GimpMetadata *metadata) +typedef struct { - return metadata->priv->attribute_table; -} + gchar name[1024]; + gboolean base64; + GimpMetadata *metadata; +} GimpMetadataParseData; -/** - * gimp_metadata_add_attribute: - * - * @metadata : a #GimpMetadata - * @attribute : a #GimpAttribute - * - * stores the @attribute in the @metadata container - * - * Since : 2.10 - */ -void -gimp_metadata_add_attribute (GimpMetadata *metadata, - GimpAttribute *attribute) -{ - const gchar *name; - gchar *lowchar; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - g_return_if_fail (GIMP_IS_ATTRIBUTE (attribute)); - - name = gimp_attribute_get_name (attribute); - - if (name) - { - lowchar = g_ascii_strdown (name, -1); - - /* FIXME: really simply add? That means, that an older value is overwritten */ - - if (g_hash_table_insert (metadata->priv->attribute_table, (gpointer) g_strdup (lowchar), (gpointer) attribute)) - { - gchar *sortable_tag; - - sortable_tag = g_ascii_strdown (gimp_attribute_get_sortable_name (attribute), -1); - - if (g_hash_table_insert (metadata->priv->sorted_to_attribute, (gpointer) g_strdup (sortable_tag), (gpointer) g_strdup (lowchar))) - { - metadata->priv->sorted_key_list = g_list_insert_sorted (metadata->priv->sorted_key_list, - (gpointer) g_strdup (sortable_tag), - (GCompareFunc) g_strcmp0); - gimp_metadata_to_parent (metadata, attribute); - } - else - { - g_hash_table_remove (metadata->priv->attribute_table, (gpointer) g_strdup (lowchar)); - } - - g_free (sortable_tag); - } - g_free (lowchar); - } -} - -/** - * gimp_metadata_get_attribute: - * - * @metadata : a #GimpMetadata - * @name : a #gchar array - * - * gets the #GimpAttribute object with @name - * - * Return value: the #GimpAttribute object if found, NULL otherwise. - * - * Since : 2.10 - */ -GimpAttribute * -gimp_metadata_get_attribute (GimpMetadata *metadata, - const gchar *name) -{ - GimpAttribute *attribute_data = NULL; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), NULL); - - attribute_data = gimp_metadata_from_parent (metadata, name); - - return attribute_data; -} - -/** - * gimp_metadata_get_attribute_sorted: - * - * @metadata: a #GimpMetadata - * @name : a #gchar array - * - * gets the #GimpAttribute object with @sorted_name as - * sortable_name - * see GimpAttribute::get_sortable_name - * - * Return value: the #GimpAttribute object if found, NULL otherwise. - * - * Since : 2.10 - */ -static GimpAttribute * -gimp_metadata_get_attribute_sorted (GimpMetadata *metadata, - const gchar *sorted_name) -{ - gchar *lowchar; - GimpAttribute *attribute_data = NULL; - gpointer *data; - gchar *name_of_tag; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), NULL); - g_return_val_if_fail (sorted_name != NULL, NULL); - - lowchar = g_ascii_strdown (sorted_name, -1); - - data = g_hash_table_lookup (metadata->priv->sorted_to_attribute, (gpointer) lowchar); - - if (data) - { - name_of_tag = (gchar *) data; - - data = g_hash_table_lookup (metadata->priv->attribute_table, (gpointer) name_of_tag); - if (data) - { - attribute_data = (GimpAttribute *) data; - } - } - - g_free (lowchar); - - return attribute_data; -} - -/** - * gimp_metadata_remove_attribute: ToDo remove from gexiv2 ToDo rewrite - * - * @metadata : a #GimpMetadata - * @name : a #gchar array - * - * removes the #GimpAttribute object with @name from the @metadata container - * - * Return value: TRUE, if removing was successful, FALSE otherwise. - * - * Since : 2.10 - */ -gboolean -gimp_metadata_remove_attribute (GimpMetadata *metadata, - const gchar *name) -{ - gchar *lowchar; - gboolean success = FALSE; - GHashTableIter iter_remove; - gpointer key, value; - gchar *tag_to_remove = NULL; - gchar *name_of_tag = NULL; - - lowchar = g_ascii_strdown (name, -1); - - if (g_hash_table_remove (metadata->priv->attribute_table, (gpointer) lowchar)) - { - gchar *tag_list_remove = NULL; - - g_hash_table_iter_init (&iter_remove, metadata->priv->sorted_to_attribute); - while (g_hash_table_iter_next (&iter_remove, &key, &value)) - { - tag_to_remove = (gchar *) key; - name_of_tag = (gchar *) value; - - if (! g_strcmp0 (lowchar, name_of_tag)) - break; - } - - tag_list_remove = g_strdup (tag_to_remove); /* because removing from hashtable frees tag_to_remove */ - - if (g_hash_table_remove (metadata->priv->sorted_to_attribute, (gpointer) tag_to_remove)) - { - GList *list = NULL; - - for (list = metadata->priv->sorted_key_list; list; list = list->next) - { - gchar *s_tag = (gchar *) list->data; - - if (! g_strcmp0 (s_tag, tag_list_remove)) - { - metadata->priv->sorted_key_list = g_list_remove (metadata->priv->sorted_key_list, - (gconstpointer) s_tag); - g_free (s_tag); - break; - } - } - g_free (tag_list_remove); - success = TRUE; - } - else - { - if (name_of_tag) - g_free (name_of_tag); - if (tag_to_remove) - g_free (tag_to_remove); - success = FALSE; - } - } - g_free (lowchar); - - gexiv2_metadata_clear_tag (GEXIV2_METADATA (metadata), name); - - return success; -} - -/** - * gimp_metadata_has_attribute: - * - * @metadata : a #GimpMetadata - * @name : a #gchar array - * - * tests, if a #GimpAttribute object with @name is in the @metadata container - * - * Return value: TRUE if yes, FALSE otherwise. - * - * Since : 2.10 - */ -gboolean -gimp_metadata_has_attribute (GimpMetadata *metadata, - const gchar *name) -{ - gchar *lowchar; - gboolean success; - - lowchar = g_ascii_strdown (name, -1); - - success = gexiv2_metadata_has_tag (GEXIV2_METADATA(metadata), name); - - g_free (lowchar); - - return success; -} - -/** - * gimp_metadata_new_attribute: - * - * @metadata: a #GimpMetadata - * @name : a #gchar array - * @value : a #gchar array - * @type : a #GimpAttributeValueType - * - * adds a #GimpAttribute object to @metadata container. - * The #GimpAttribute object is created from the - * @name, - * @value and - * @type parameters. - * - * Return value: TRUE if successful, FALSE otherwise. - * - * Since : 2.10 - */ -gboolean -gimp_metadata_new_attribute (GimpMetadata *metadata, - const gchar *name, - gchar *value, - GimpAttributeValueType type) -{ - GimpAttribute *attribute; - - attribute = gimp_attribute_new_string (name, value, type); - if (attribute) - { - gimp_metadata_add_attribute (metadata, attribute); - return TRUE; - } - - return FALSE; -} - -/** - * gimp_metadata_serialize: ToDo handle old metadata and get data from sorted list -> attributes.c - * - * @metadata: a #GimpMetadata - * - * creates a xml representation of all #GimpAttribute objects in the #GimpMetadata container. - * see #GimpAttribute:gimp_attribute_get_xml - * - * Return value: a new #gchar array, the xml representation of the #GimpMetadata object. - * - * Since : 2.10 - */ -gchar * -gimp_metadata_serialize (GimpMetadata *metadata) -{ - GString *string; - GList *key_list; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), NULL); - - gimp_metadata_from_gexiv2 (metadata); - - string = g_string_new (NULL); - - g_string_append (string, "\n"); - g_string_append (string, "\n"); - - for (key_list = metadata->priv->sorted_key_list; key_list; key_list = key_list->next) - { - gchar *xml = NULL; - GimpAttribute *attribute = NULL; - gchar *p_key = (gchar *) key_list->data; - - attribute = gimp_metadata_get_attribute_sorted (metadata, p_key); - - xml = gimp_attribute_get_xml (attribute); - - g_string_append_printf (string, "%s\n", xml); - - g_free (xml); - } - - g_string_append (string, "\n"); - - return g_string_free (string, FALSE); -} - -/** - * gimp_metadata_deserialize: - * - * @xml: a #gchar array - * - * parses a xml representation of a #GimpMetadata container. - * see - * #GimpMetadata:gimp_metadata_deserialize_start_element - * #GimpMetadata:gimp_metadata_deserialize_end_element - * #GimpMetadata:gimp_metadata_deserialize_text - * #GimpMetadata:gimp_metadata_deserialize_error - * - * Return value: a new #GimpMetadata object. - * - * Since : 2.10 - */ -GimpMetadata * -gimp_metadata_deserialize (const gchar *xml) -{ - GMarkupParser *markup_parser = g_slice_new (GMarkupParser); - GimpMetadataParseData *parse_data = g_slice_new (GimpMetadataParseData); - GMarkupParseContext *context; - GimpMetadata *metadata; - - g_return_val_if_fail (xml != NULL, NULL); - - metadata = gimp_metadata_new (); - - parse_data->metadata = metadata; - - markup_parser->start_element = gimp_metadata_deserialize_start_element; - markup_parser->end_element = gimp_metadata_deserialize_end_element; - markup_parser->text = gimp_metadata_deserialize_text; - markup_parser->passthrough = NULL; - markup_parser->error = gimp_metadata_deserialize_error; - - context = g_markup_parse_context_new (markup_parser, 0, parse_data, NULL); - - g_markup_parse_context_parse (context, - xml, strlen (xml), - NULL); - - g_markup_parse_context_unref (context); - - g_slice_free (GMarkupParser, markup_parser); - g_slice_free (GimpMetadataParseData, parse_data); - - return metadata; -} - -/** - * gimp_metadata_from_gexiv2metadata: - * @metadata: The metadata the gexiv2metadata will be added to, may be %NULL - * @gexiv2metadata: The metadata in gexiv2 format - * - * Converts the @gexiv2metadata retrieved from a file into - * a #GimpMetadata object - * - * Return value: The #GimpMetadata object - * - * Since: GIMP 2.10 - */ -//GimpMetadata * -//gimp_metadata_from_gexiv2metadata (GimpMetadata *metadata, -// GimpMetadata *gexivdata) -//{ -// const gchar *tag_type; -// GimpAttribute *attribute; -// GimpAttributeValueType attrib_type; -// gint i; -// GimpMetadata *new_metadata = NULL; -// GExiv2Metadata *gexiv2metadata = NULL; -// -// gexiv2metadata = GEXIV2_METADATA(gexivdata); -// -// if (!metadata) -// { -// new_metadata = gimp_metadata_new (); -// } -// else -// { -// new_metadata = gimp_metadata_duplicate (metadata); -// g_object_unref (metadata); -// } -// -// if (new_metadata) -// { -// gchar **exif_data; -// gchar **xmp_data; -// gchar **iptc_data; -// gboolean no_interpreted = TRUE; /*FIXME: No interpreted String possible */ -// -// exif_data = gexiv2_metadata_get_exif_tags (gexiv2metadata); -// -// for (i = 0; exif_data[i] != NULL; i++) -// { -// gchar *interpreted_value = NULL; -// gchar *value = NULL; -// gboolean interpreted = FALSE; -// -// value = gexiv2_metadata_get_tag_string (gexiv2metadata, exif_data[i]); -// interpreted_value = gexiv2_metadata_get_tag_interpreted_string (gexiv2metadata, exif_data[i]); -// tag_type = gexiv2_metadata_get_tag_type (exif_data[i]); -// attrib_type = gimp_attribute_get_value_type_from_string (tag_type); -// -// interpreted = g_strcmp0 (value, interpreted_value); -// -// if (!interpreted) -// { -// gint length; -// -// length = strlen (interpreted_value); -// if (length > 2048) -// { -// g_free (interpreted_value); -// interpreted_value = g_strdup_printf ("(Size of value: %d)", length); -// interpreted = TRUE; -// } -// } -// -// attribute = gimp_attribute_new_string (exif_data[i], value, attrib_type); -// if (gimp_attribute_is_valid (attribute)) -// { -// if (no_interpreted) -// { -// if (interpreted) -// { -// gimp_attribute_set_interpreted_string (attribute, interpreted_value); -// } -// } -// gimp_metadata_add_attribute (new_metadata, attribute); -// } -// else -// { -// g_object_unref (attribute); -// } -// -// g_free (interpreted_value); -// g_free (value); -// } -// -// g_strfreev (exif_data); -// -// xmp_data = gexiv2_metadata_get_xmp_tags (gexiv2metadata); -// -// for (i = 0; xmp_data[i] != NULL; i++) -// { -// gchar *interpreted_value = NULL; -// gchar *value = NULL; -// gboolean interpreted = FALSE; -// -// value = gexiv2_metadata_get_tag_string (gexiv2metadata, xmp_data[i]); -// interpreted_value = gexiv2_metadata_get_tag_interpreted_string (gexiv2metadata, xmp_data[i]); -// tag_type = gexiv2_metadata_get_tag_type (xmp_data[i]); -// attrib_type = gimp_attribute_get_value_type_from_string (tag_type); -// -// interpreted = g_strcmp0 (value, interpreted_value); -// -// attribute = gimp_attribute_new_string (xmp_data[i], value, attrib_type); -// -// if (gimp_attribute_is_valid (attribute)) -// { -// if (no_interpreted) -// { -// if (interpreted) -// gimp_attribute_set_interpreted_string (attribute, interpreted_value); -// } -// gimp_metadata_add_attribute (new_metadata, attribute); -// } -// else -// { -// g_object_unref (attribute); -// } -// -// g_free (value); -// } -// -// g_strfreev (xmp_data); -// -// iptc_data = gexiv2_metadata_get_iptc_tags (gexiv2metadata); -// -// for (i = 0; iptc_data[i] != NULL; i++) -// { -// gchar *interpreted_value = NULL; -// gchar *value = NULL; -// gboolean interpreted = FALSE; -// -// value = gexiv2_metadata_get_tag_string (gexiv2metadata, iptc_data[i]); -// interpreted_value = gexiv2_metadata_get_tag_interpreted_string (gexiv2metadata, iptc_data[i]); -// tag_type = gexiv2_metadata_get_tag_type (iptc_data[i]); -// attrib_type = gimp_attribute_get_value_type_from_string (tag_type); -// -// interpreted = g_strcmp0 (value, interpreted_value); -// -// attribute = gimp_attribute_new_string (iptc_data[i], value, attrib_type); -// if (gimp_attribute_is_valid (attribute)) -// { -// if (no_interpreted) -// { -// if (interpreted) -// gimp_attribute_set_interpreted_string (attribute, interpreted_value); -// } -// gimp_metadata_add_attribute (new_metadata, attribute); -// } -// else -// { -// g_object_unref (attribute); -// } -// -// g_free (value); -// } -// -// g_strfreev (iptc_data); -// } -// return new_metadata; -//} - -/** - * gimp_metadata_from_gexiv2: - * @metadata: The metadata - * - * Constructs the @metadata retrieved from the gexiv2 package. - * - * - * Since: GIMP 2.10 - */ -void -gimp_metadata_from_gexiv2 (GimpMetadata *metadata) -{ - const gchar *tag_type; - GimpAttribute *attribute; - GimpAttributeValueType attrib_type; - gint i; - GExiv2Metadata *gexiv2metadata = NULL; - GimpMetadataPrivate *priv; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - - priv = GIMP_METADATA_GET_PRIVATE (metadata); - - if (priv->attribute_table) - g_hash_table_unref (priv->attribute_table); - if (priv->sorted_to_attribute) - g_hash_table_unref (priv->sorted_to_attribute); - if (priv->sorted_key_list) - g_list_free_full (priv->sorted_key_list, (GDestroyNotify) g_free); - if (priv->xmp_structure_list) - g_slist_free (priv->xmp_structure_list); - - - priv->attribute_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - priv->sorted_to_attribute = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->sorted_key_list = NULL; - priv->xmp_structure_list = NULL; - - gexiv2metadata = GEXIV2_METADATA(metadata); - - { - gchar **exif_data; - gchar **xmp_data; - gchar **iptc_data; - gboolean no_interpreted = TRUE; /*FIXME: No interpreted String possible */ - - exif_data = gexiv2_metadata_get_exif_tags (gexiv2metadata); - - for (i = 0; exif_data[i] != NULL; i++) - { - gchar *interpreted_value = NULL; - gchar *value = NULL; - gboolean interpreted = FALSE; - - value = gexiv2_metadata_get_tag_string (gexiv2metadata, exif_data[i]); - interpreted_value = gexiv2_metadata_get_tag_interpreted_string (gexiv2metadata, exif_data[i]); - tag_type = gexiv2_metadata_get_tag_type (exif_data[i]); - attrib_type = gimp_attribute_get_value_type_from_string (tag_type); - - interpreted = g_strcmp0 (value, interpreted_value); - - if (!interpreted) - { - gint length; - - length = strlen (interpreted_value); - if (length > 2048) - { - g_free (interpreted_value); - interpreted_value = g_strdup_printf ("(Size of value: %d)", length); - interpreted = TRUE; - } - } - - attribute = gimp_attribute_new_string (exif_data[i], value, attrib_type); - if (gimp_attribute_is_valid (attribute)) - { - if (no_interpreted) - { - if (interpreted) - { - gimp_attribute_set_interpreted_string (attribute, interpreted_value); - } - } - gimp_metadata_add_attribute_to_list (metadata, attribute); - } - else - { - g_object_unref (attribute); - } - - g_free (interpreted_value); - g_free (value); - } - - g_strfreev (exif_data); - - xmp_data = gexiv2_metadata_get_xmp_tags (gexiv2metadata); - - for (i = 0; xmp_data[i] != NULL; i++) - { - gchar *interpreted_value = NULL; - gchar *value = NULL; - gboolean interpreted = FALSE; - - value = gexiv2_metadata_get_tag_string (gexiv2metadata, xmp_data[i]); - interpreted_value = gexiv2_metadata_get_tag_interpreted_string (gexiv2metadata, xmp_data[i]); - tag_type = gexiv2_metadata_get_tag_type (xmp_data[i]); - attrib_type = gimp_attribute_get_value_type_from_string (tag_type); - - interpreted = g_strcmp0 (value, interpreted_value); - - attribute = gimp_attribute_new_string (xmp_data[i], value, attrib_type); - - if (gimp_attribute_is_valid (attribute)) - { - if (no_interpreted) - { - if (interpreted) - gimp_attribute_set_interpreted_string (attribute, interpreted_value); - } - gimp_metadata_add_attribute_to_list (metadata, attribute); - } - else - { - g_object_unref (attribute); - } - - g_free (value); - } - - g_strfreev (xmp_data); - - iptc_data = gexiv2_metadata_get_iptc_tags (gexiv2metadata); - - for (i = 0; iptc_data[i] != NULL; i++) - { - gchar *interpreted_value = NULL; - gchar *value = NULL; - gboolean interpreted = FALSE; - - value = gexiv2_metadata_get_tag_string (gexiv2metadata, iptc_data[i]); - interpreted_value = gexiv2_metadata_get_tag_interpreted_string (gexiv2metadata, iptc_data[i]); - tag_type = gexiv2_metadata_get_tag_type (iptc_data[i]); - attrib_type = gimp_attribute_get_value_type_from_string (tag_type); - - interpreted = g_strcmp0 (value, interpreted_value); - - attribute = gimp_attribute_new_string (iptc_data[i], value, attrib_type); - if (gimp_attribute_is_valid (attribute)) - { - if (no_interpreted) - { - if (interpreted) - gimp_attribute_set_interpreted_string (attribute, interpreted_value); - } - gimp_metadata_add_attribute (metadata, attribute); - } - else - { - g_object_unref (attribute); - } - - g_free (value); - } - - g_strfreev (iptc_data); - } -} - -/** - * gimp_metadata_add_list: - * - * @metadata : a #GimpMetadata - * @attribute : a #GimpAttribute - * - * stores the @attribute in the @metadata container - * - * Since : 2.10 - */ -void -gimp_metadata_add_attribute_to_list (GimpMetadata *metadata, - GimpAttribute *attribute) -{ - const gchar *name; - gchar *lowchar; - GimpMetadataPrivate *priv; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - g_return_if_fail (GIMP_IS_ATTRIBUTE (attribute)); - - priv = GIMP_METADATA_GET_PRIVATE (metadata); - - name = gimp_attribute_get_name (attribute); - - if (name) - { - lowchar = g_ascii_strdown (name, -1); - - /* FIXME: really simply add? That means, that an older value is overwritten */ - - if (g_hash_table_insert (priv->attribute_table, (gpointer) g_strdup (lowchar), (gpointer) attribute)) - { - gchar *sortable_tag; - - sortable_tag = g_ascii_strdown (gimp_attribute_get_sortable_name (attribute), -1); - - if (g_hash_table_insert (priv->sorted_to_attribute, (gpointer) g_strdup (sortable_tag), (gpointer) g_strdup (lowchar))) - { - priv->sorted_key_list = g_list_insert_sorted (priv->sorted_key_list, - (gpointer) g_strdup (sortable_tag), - (GCompareFunc) g_strcmp0); - } - else - { - g_hash_table_remove (priv->attribute_table, (gpointer) g_strdup (lowchar)); - } - - g_free (sortable_tag); - } - g_free (lowchar); - } -} - -/** - * gimp_metadata_from_parent: - * @metadata: The metadata the gexiv2metadata will be added to, may be %NULL - * @gexiv2metadata: The metadata in gexiv2 format - * - * Converts the @gexiv2metadata retrieved from a file into - * a #GimpMetadata object - * - * Return value: The #GimpMetadata object - * - * Since: GIMP 2.10 - */ -GimpAttribute * -gimp_metadata_from_parent (GimpMetadata *metadata, - const gchar *name) -{ - const gchar *tag_type; - gboolean no_interpreted = TRUE; /*FIXME: No interpreted String possible */ - gchar *interpreted_value = NULL; - gchar *value = NULL; - gboolean interpreted = FALSE; - GimpAttribute *attribute = NULL; - GimpAttributeValueType attrib_type; - GExiv2Metadata *gexiv2metadata; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), NULL); - - gexiv2metadata = GEXIV2_METADATA (metadata); - - if (gexiv2_metadata_has_tag (gexiv2metadata, name)) - { - value = gexiv2_metadata_get_tag_string (gexiv2metadata, name); - interpreted_value = gexiv2_metadata_get_tag_interpreted_string (gexiv2metadata, name); - tag_type = gexiv2_metadata_get_tag_type (name); - attrib_type = gimp_attribute_get_value_type_from_string (tag_type); - - interpreted = g_strcmp0 (value, interpreted_value); - - if (!interpreted) - { - gint length; - - length = strlen (interpreted_value); - if (length > 2048) - { - g_free (interpreted_value); - interpreted_value = g_strdup_printf ("(Size of value: %d)", length); - interpreted = TRUE; - } - } - - attribute = gimp_attribute_new_string (name, value, attrib_type); - if (gimp_attribute_is_valid (attribute)) - { - if (no_interpreted) - { - if (interpreted) - { - gimp_attribute_set_interpreted_string (attribute, interpreted_value); - } - } - } - else - { - g_object_unref (attribute); - } - - g_free (interpreted_value); - g_free (value); - } - return attribute; -} - -/** - * gimp_metadata_print: - * @metadata: The #GimpMetadata - * - * prints out information of metadata - * - * Since: GIMP 2.10 - */ -void -gimp_metadata_print (GimpMetadata *metadata) -{ - gint i; - GList *key_list = NULL; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - - gimp_metadata_from_gexiv2 (metadata); - - i = 0; - - for (key_list = metadata->priv->sorted_key_list; key_list; key_list = key_list->next) - { - const gchar *tag; - const gchar *interpreted; - gchar *value; - GimpAttribute *attribute; - gchar *p_key = (gchar *) key_list->data; - - attribute = gimp_metadata_get_attribute_sorted (metadata, p_key); - - if (! attribute) - continue; - - i++; - - tag = gimp_attribute_get_name (attribute); - value = gimp_attribute_get_string (attribute); - interpreted = gimp_attribute_get_interpreted_string (attribute); - - g_print ("%p: %s\n%04d. Tag: %s\n\tValue:%s\n\tInterpreted value:%s\n", attribute, p_key, i, tag, value, interpreted); - - if (value) - g_free (value); - } -} - -/** - * gimp_metadata_to_gexiv2metadata: - * @metadata: The #GimpMetadata - * @gexiv2metadata: The #GimpMetadata - * @mime_type: the mime type of the image - * - * Converts @metadata to @gexiv2metadata in gexiv2 format - * - * Since: GIMP 2.10 - */ -//void -//gimp_metadata_to_gexiv2metadata (GimpMetadata *metadata, -// GimpMetadata *gexivdata, -// const gchar *mime_type) -//{ -// gchar *o_packet = NULL; -// gboolean write_tag = FALSE; -// gboolean namespace = FALSE; -// gboolean check_mime = TRUE; -// gboolean support_exif; -// gboolean support_xmp; -// gboolean support_iptc; -// GSList *xmp_structure_list = NULL; -// GList *key_list = NULL; -// gint i; -// GExiv2Metadata *gexiv2metadata; -// -// g_return_if_fail (IS_GIMP_METADATA (metadata)); -// -// gexiv2metadata = GEXIV2_METADATA(gexivdata); -// -// for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) -// { -// struct Namespaces n_space = namespaces_table[i]; -// gexiv2_metadata_register_xmp_namespace (n_space.namespace_URI, n_space.namespace_name); -// } -// -// support_exif = gexiv2_metadata_get_supports_exif (gexiv2metadata); -// support_xmp = gexiv2_metadata_get_supports_xmp (gexiv2metadata); -// support_iptc = gexiv2_metadata_get_supports_iptc (gexiv2metadata); -// -// for (key_list = metadata->priv->sorted_key_list; key_list; key_list = key_list->next) -// { -// const gchar *tag; -// const gchar *ns_name; -// gchar *p_key = (gchar *) key_list->data; -// gchar *value = NULL; -// gchar *category = NULL; -// gboolean is_xmp = FALSE; -// gboolean has_structure = FALSE; -// GimpAttribute *attribute; -// GimpAttributeValueType tag_value_type; -// -// write_tag = FALSE; -// namespace = FALSE; -// -// attribute = gimp_metadata_get_attribute_sorted (metadata, p_key); -// -// if (! attribute) -// continue; -// -// tag = gimp_attribute_get_name (attribute); -// has_structure = gimp_attribute_has_structure (attribute); -// -// if (mime_type) -// check_mime = gimp_metadata_is_tag_supported (tag, mime_type); -// -// if (check_mime) -// { -// gchar *t_packet = NULL; -// -// tag_value_type = gimp_attribute_get_value_type (attribute); -// value = gimp_attribute_get_string (attribute); -// category = g_ascii_strdown (gimp_attribute_get_attribute_type (attribute), -1); -// -// if (tag && value && category) -// { -// if(! g_strcmp0 (category, "exif") && support_exif) -// { -// write_tag = TRUE; -// } -// else if(! g_strcmp0 (category, "xmp") && support_xmp) -// { -// write_tag = TRUE; -// is_xmp = TRUE; -// -// namespace = gimp_attribute_is_new_namespace (attribute); -// -// if (namespace) -// { -// write_tag = FALSE; -// -// ns_name = gimp_attribute_get_attribute_ifd (attribute); -// -// for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) -// { -// struct Namespaces n_space = namespaces_table[i]; -// if(! g_strcmp0 (ns_name, n_space.namespace_name)) -// { -// write_tag = TRUE; -// break; -// } -// } -// } -// -// if (write_tag && has_structure) -// { -// gboolean success = TRUE; -// GSList *structure; -// GSList *list; -// GimpAttributeStructureType structure_type; -// -// structure = gimp_attribute_get_attribute_structure (attribute); -// structure_type = gimp_attribute_get_structure_type (attribute); -// -// for (list = structure; list; list = list->next) -// { -// const gchar *structure_element = (const gchar*) list->data; -// gboolean has_tag = gexiv2_metadata_has_tag (gexiv2metadata, structure_element); -// -// if (!has_tag && ! has_xmp_structure (xmp_structure_list, structure_element)) -// { -// switch (structure_type) -// { -// case STRUCTURE_TYPE_ALT: -// success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_ALT); /*start block*/ -// break; -// case STRUCTURE_TYPE_BAG: -// success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_BAG); /*start block*/ -// break; -// case STRUCTURE_TYPE_SEQ: -// success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_SEQ); /*start block*/ -// break; -// default: -// success = FALSE; -// break; -// } -// -// if (success) -// xmp_structure_list = g_slist_prepend (xmp_structure_list, (gpointer)structure_element); -// } -// } -// } -// } -// else if(! g_strcmp0 (category, "iptc") && support_iptc) -// { -// write_tag = TRUE; -// } -// else -// { -// write_tag = FALSE; -// } -// -// if (write_tag) -// { -// switch (tag_value_type) -// { -// case TYPE_INVALID: -// break; -// case TYPE_LONG: -// case TYPE_SLONG: -// case TYPE_FLOAT: -// case TYPE_DOUBLE: -// case TYPE_SHORT: -// case TYPE_SSHORT: -// case TYPE_DATE: -// case TYPE_TIME: -// case TYPE_ASCII: -// case TYPE_UNICODE: -// case TYPE_BYTE: -// case TYPE_RATIONAL: -// case TYPE_SRATIONAL: -// { -// gexiv2_metadata_set_tag_string (gexiv2metadata, tag, value); -// } -// break; -// case TYPE_MULTIPLE: -// { -// GValue h; -// gchar **values; -// -// h = gimp_attribute_get_value (attribute); -// values = (gchar **) g_value_get_boxed (&h); -// gexiv2_metadata_set_tag_multiple (gexiv2metadata, tag, (const gchar **) values); -// g_strfreev (values); -// } -// break; -// case TYPE_UNKNOWN: -// default: -// break; -// -// } -// -// if (is_xmp) -// { -// t_packet = gexiv2_metadata_generate_xmp_packet (gexiv2metadata, GEXIV2_USE_COMPACT_FORMAT | GEXIV2_OMIT_ALL_FORMATTING, 0); -// -// if (! g_strcmp0 (t_packet, o_packet)) -// { -// gexiv2_metadata_clear_tag (gexiv2metadata, tag); -// g_print ("cleared to gexiv2metadata:\n%s, %s\n", tag, value); -// } -// else -// { -// o_packet = g_strdup (t_packet); -// } -// } -// } -// } -// -// if (t_packet) -// g_free (t_packet); -// if (value) -// g_free (value); -// if (category) -// g_free (category); -// } -// } -// -// if (o_packet) -// g_free (o_packet); -// if (xmp_structure_list) -// g_slist_free (xmp_structure_list); -//} - -/** - * gimp_metadata_to_gexiv2: - * @metadata: The #GimpMetadata - * - * Converts @metadata to @gexiv2metadata packet - * - * Since: GIMP 2.10 - */ -void -gimp_metadata_to_gexiv2 (GimpMetadata *metadata) -{ - gchar *o_packet = NULL; - gboolean write_tag = FALSE; - gboolean namespace = FALSE; - gboolean support_exif; - gboolean support_xmp; - gboolean support_iptc; - GSList *xmp_structure_list = NULL; - GList *key_list = NULL; - gint i; - GExiv2Metadata *gexiv2metadata; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - - gexiv2metadata = GEXIV2_METADATA(metadata); - - for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) - { - struct Namespaces n_space = namespaces_table[i]; - gexiv2_metadata_register_xmp_namespace (n_space.namespace_URI, n_space.namespace_name); - } - - support_exif = gexiv2_metadata_get_supports_exif (gexiv2metadata); - support_xmp = gexiv2_metadata_get_supports_xmp (gexiv2metadata); - support_iptc = gexiv2_metadata_get_supports_iptc (gexiv2metadata); - - for (key_list = metadata->priv->sorted_key_list; key_list; key_list = key_list->next) - { - const gchar *tag; - const gchar *ns_name; - gchar *p_key = (gchar *) key_list->data; - gchar *value = NULL; - gchar *category = NULL; - gboolean is_xmp = FALSE; - gboolean has_structure = FALSE; - gchar *t_packet = NULL; - GimpAttribute *attribute; - GimpAttributeValueType tag_value_type; - - write_tag = FALSE; - namespace = FALSE; - - attribute = gimp_metadata_get_attribute_sorted (metadata, p_key); - - if (! attribute) - continue; - - tag = gimp_attribute_get_name (attribute); - has_structure = gimp_attribute_has_structure (attribute); - - tag_value_type = gimp_attribute_get_value_type (attribute); - value = gimp_attribute_get_string (attribute); - category = g_ascii_strdown (gimp_attribute_get_attribute_type (attribute), -1); - - if (tag && value && category) - { - if(! g_strcmp0 (category, "exif") && support_exif) - { - write_tag = TRUE; - } - else if(! g_strcmp0 (category, "xmp") && support_xmp) - { - write_tag = TRUE; - is_xmp = TRUE; - - namespace = gimp_attribute_is_new_namespace (attribute); - - if (namespace) - { - write_tag = FALSE; - - ns_name = gimp_attribute_get_attribute_ifd (attribute); - - for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) - { - struct Namespaces n_space = namespaces_table[i]; - if(! g_strcmp0 (ns_name, n_space.namespace_name)) - { - write_tag = TRUE; - break; - } - } - } - - if (write_tag && has_structure) - { - gboolean success = TRUE; - GSList *structure; - GSList *list; - GimpAttributeStructureType structure_type; - - structure = gimp_attribute_get_attribute_structure (attribute); - structure_type = gimp_attribute_get_structure_type (attribute); - - for (list = structure; list; list = list->next) - { - const gchar *structure_element = (const gchar*) list->data; - gboolean has_tag = gexiv2_metadata_has_tag (gexiv2metadata, structure_element); - - if (!has_tag && ! has_xmp_structure (xmp_structure_list, structure_element)) - { - switch (structure_type) - { - case STRUCTURE_TYPE_ALT: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_ALT); /*start block*/ - break; - case STRUCTURE_TYPE_BAG: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_BAG); /*start block*/ - break; - case STRUCTURE_TYPE_SEQ: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_SEQ); /*start block*/ - break; - default: - success = FALSE; - break; - } - - if (success) - xmp_structure_list = g_slist_prepend (xmp_structure_list, (gpointer)structure_element); - } - } - } - } - else if(! g_strcmp0 (category, "iptc") && support_iptc) - { - write_tag = TRUE; - } - else - { - write_tag = FALSE; - } - - if (write_tag) - { - switch (tag_value_type) - { - case TYPE_INVALID: - break; - case TYPE_LONG: - case TYPE_SLONG: - case TYPE_FLOAT: - case TYPE_DOUBLE: - case TYPE_SHORT: - case TYPE_SSHORT: - case TYPE_DATE: - case TYPE_TIME: - case TYPE_ASCII: - case TYPE_UNICODE: - case TYPE_BYTE: - case TYPE_RATIONAL: - case TYPE_SRATIONAL: - { - gexiv2_metadata_set_tag_string (gexiv2metadata, tag, value); - } - break; - case TYPE_MULTIPLE: - { - GValue h; - gchar **values; - - h = gimp_attribute_get_value (attribute); - values = (gchar **) g_value_get_boxed (&h); - gexiv2_metadata_set_tag_multiple (gexiv2metadata, tag, (const gchar **) values); - g_strfreev (values); - } - break; - case TYPE_UNKNOWN: - default: - break; - - } - - if (is_xmp) - { - /* XMP packet for testing - * There is no way to check, if storing of tags were successful, because gexiv2 has no error handling - * The only way is to compare a xpm packet before and after the storing process. If they are equal, the storing was not successful - * so the stored tag must be deleted, otherwise the whole xmp data is corrupt. */ - t_packet = gexiv2_metadata_generate_xmp_packet (gexiv2metadata, GEXIV2_USE_COMPACT_FORMAT | GEXIV2_OMIT_ALL_FORMATTING, 0); - - if (! g_strcmp0 (t_packet, o_packet)) - { - gexiv2_metadata_clear_tag (gexiv2metadata, tag); - g_print ("cleared to gexiv2metadata:\n%s, %s\n", tag, value); - } - else - { - o_packet = g_strdup (t_packet); - } - } - } - } - - if (t_packet) - g_free (t_packet); - if (value) - g_free (value); - if (category) - g_free (category); - } - - if (o_packet) - g_free (o_packet); - if (xmp_structure_list) - g_slist_free (xmp_structure_list); -} - -/** - * gimp_metadata_to_parent: - * @metadata: The #GimpMetadata - * @gexiv2metadata: The #GimpMetadata - * @mime_type: the mime type of the image - * - * Converts @metadata to @gexiv2metadata in gexiv2 format - * - * Since: GIMP 2.10 - */ -void -gimp_metadata_to_parent (GimpMetadata *metadata, - GimpAttribute *attribute) -{ - gchar *o_packet = NULL; - gboolean write_tag = FALSE; - gboolean namespace = FALSE; - gint i; - GExiv2Metadata *gexiv2metadata; - const gchar *tag; - const gchar *ns_name; - gchar *value = NULL; - gchar *category = NULL; - gboolean is_xmp = FALSE; - gboolean has_structure = FALSE; - GimpAttributeValueType tag_value_type; - gchar *t_packet = NULL; - GimpMetadataPrivate *priv; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - g_return_if_fail (GIMP_IS_ATTRIBUTE (attribute)); - - gexiv2metadata = GEXIV2_METADATA (metadata); - priv = GIMP_METADATA_GET_PRIVATE (metadata); - write_tag = FALSE; - namespace = FALSE; - - tag = gimp_attribute_get_name (attribute); - has_structure = gimp_attribute_has_structure (attribute); - - - tag_value_type = gimp_attribute_get_value_type (attribute); - value = gimp_attribute_get_string (attribute); - category = g_ascii_strdown (gimp_attribute_get_attribute_type (attribute), -1); - -// if (g_str_has_prefix (tag, "Xmp")) -// { -// g_print ("found xmp: %s\n", tag); -// } -// -// if (g_str_has_prefix (tag, "Xmp.xmpMM.History")) -// { -// g_print ("found struct: %s\n", tag); -// } - - - if (tag && value && category) - { - if(! g_strcmp0 (category, "exif")) - { - write_tag = TRUE; - } - else if(! g_strcmp0 (category, "xmp")) - { - write_tag = TRUE; - is_xmp = TRUE; - - /* XMP packet for testing before adding tag - * There is no way to check, if storing of tags were successful, because gexiv2 has no error handling - * The only way is to compare a xpm packet before and after the storing process. If they are equal, the storing was not successful - * so the stored tag must be deleted, otherwise the whole xmp data is corrupt. */ - o_packet = gexiv2_metadata_generate_xmp_packet (gexiv2metadata, GEXIV2_USE_COMPACT_FORMAT | GEXIV2_OMIT_ALL_FORMATTING, 0); - - namespace = gimp_attribute_is_new_namespace (attribute); - - if (namespace) - { - write_tag = FALSE; - - ns_name = gimp_attribute_get_attribute_ifd (attribute); - - for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) - { - struct Namespaces n_space = namespaces_table[i]; - if(! g_strcmp0 (ns_name, n_space.namespace_name)) - { - write_tag = TRUE; - break; - } - } - } - - if (write_tag && has_structure) - { - gboolean success = TRUE; - GSList *structure; - GSList *list; - GimpAttributeStructureType structure_type; - - structure = gimp_attribute_get_attribute_structure (attribute); - structure_type = gimp_attribute_get_structure_type (attribute); - - for (list = structure; list; list = list->next) - { - const gchar *structure_element = (const gchar*) list->data; - gboolean has_tag = gexiv2_metadata_has_tag (gexiv2metadata, structure_element); - - if (!has_tag && ! has_xmp_structure (priv->xmp_structure_list, structure_element)) - { - switch (structure_type) - { - case STRUCTURE_TYPE_ALT: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_ALT); /*start block*/ - break; - case STRUCTURE_TYPE_BAG: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_BAG); /*start block*/ - break; - case STRUCTURE_TYPE_SEQ: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_SEQ); /*start block*/ - break; - default: - success = FALSE; - break; - } - - if (success) - priv->xmp_structure_list = g_slist_prepend (priv->xmp_structure_list, (gpointer)structure_element); - } - } - } - } - else if(! g_strcmp0 (category, "iptc")) - { - write_tag = TRUE; - } - else - { - write_tag = FALSE; - } - - if (write_tag) - { - switch (tag_value_type) - { - case TYPE_INVALID: - break; - case TYPE_LONG: - case TYPE_SLONG: - case TYPE_FLOAT: - case TYPE_DOUBLE: - case TYPE_SHORT: - case TYPE_SSHORT: - case TYPE_DATE: - case TYPE_TIME: - case TYPE_ASCII: - case TYPE_UNICODE: - case TYPE_BYTE: - case TYPE_RATIONAL: - case TYPE_SRATIONAL: - { - gexiv2_metadata_set_tag_string (gexiv2metadata, tag, value); - } - break; - case TYPE_MULTIPLE: - { - GValue h; - gchar **values; - - h = gimp_attribute_get_value (attribute); - values = (gchar **) g_value_get_boxed (&h); - gexiv2_metadata_set_tag_multiple (gexiv2metadata, tag, (const gchar **) values); - g_strfreev (values); - } - break; - case TYPE_UNKNOWN: - default: - break; - - } - - if (is_xmp) - { - /* XMP packet for testing after adding tag */ - t_packet = gexiv2_metadata_generate_xmp_packet (gexiv2metadata, GEXIV2_USE_COMPACT_FORMAT | GEXIV2_OMIT_ALL_FORMATTING, 0); - - if (! g_strcmp0 (t_packet, o_packet)) - { - gexiv2_metadata_clear_tag (gexiv2metadata, tag); - g_print ("cleared to gexiv2metadata:\n%s, %s\n", tag, value); - } - } - } - } - - if (t_packet) - g_free (t_packet); - if (value) - g_free (value); - if (category) - g_free (category); - if (o_packet) - g_free (o_packet); -} - -/** - * gimp_metadata_to_xmp_packet: ToDo handle xmp-packet - * @metadata: The #GimpMetadata - * @mime_type : a mime_type - * - * Converts @metadata to a xmp packet - * It looks like an ugly hack, but let - * gexiv2/exiv2 do all the hard work. - * - * Return value: a #gchar*, representing a xml packet. - * - * Since: GIMP 2.10 - */ -const gchar * -gimp_metadata_to_xmp_packet (GimpMetadata *metadata, - const gchar *mime_type) - -{ - gint i; - const gchar *packet_string; - gchar *o_packet = NULL; - gboolean check_mime = TRUE; - gboolean write_tag = FALSE; - gboolean namespace = FALSE; - gboolean support_exif; - gboolean support_xmp; - gboolean support_iptc; - GExiv2Metadata *gexiv2metadata; - GSList *xmp_structure_list = NULL; - GList *key_list = NULL; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), NULL); - - gimp_metadata_from_gexiv2 (metadata); - - gexiv2metadata = gimp_metadata_new_gexiv2metadata (); - - for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) - { - struct Namespaces n_space = namespaces_table[i]; - gexiv2_metadata_register_xmp_namespace (n_space.namespace_URI, n_space.namespace_name); - } - - support_exif = gexiv2_metadata_get_supports_exif (gexiv2metadata); - support_xmp = gexiv2_metadata_get_supports_xmp (gexiv2metadata); - support_iptc = gexiv2_metadata_get_supports_iptc (gexiv2metadata); - - for (key_list = metadata->priv->sorted_key_list; key_list; key_list = key_list->next) - { - gchar *p_key = (gchar *) key_list->data; - - const gchar *tag; - const gchar *attribute_tag; - const gchar *ns_name; - gchar *new_tag = NULL; - gchar *value = NULL; - gchar *category = NULL; - gboolean has_structure; - gboolean temp_attribute = FALSE; - GimpAttribute *attribute; - GimpAttributeValueType tag_value_type; - - write_tag = FALSE; - namespace = FALSE; - - attribute = gimp_metadata_get_attribute_sorted (metadata, p_key); - - if (! attribute) - continue; - - tag = gimp_attribute_get_name (attribute); - attribute_tag = gimp_attribute_get_attribute_tag (attribute); - has_structure = gimp_attribute_has_structure (attribute); - - if (mime_type) - check_mime = gimp_metadata_is_tag_supported (tag, mime_type); - - if (check_mime) - { - gchar *sec_tag = NULL; - gchar *t_packet = NULL; - - tag_value_type = gimp_attribute_get_value_type (attribute); - value = gimp_attribute_get_string (attribute); - category = g_ascii_strdown (gimp_attribute_get_attribute_type (attribute), -1); - - if (tag && value && category) - { - if(! g_strcmp0 (category, "exif") && support_exif) - { - new_tag = g_strdup_printf ("Xmp.exif.%s", attribute_tag); - - write_tag = TRUE; - -// /* Now for some specialities */ -// if (! g_strcmp0 (new_tag, "Xmp.exif.ISOSpeedRatings")) -// { -// g_print ("ungültig\n"); -// attribute = gimp_attribute_new_string ("Xmp.exif.ISOSpeedRatings", value, TYPE_ASCII); -// if (attribute) -// { -// temp_attribute = TRUE; -// tag_value_type = TYPE_ASCII; -// } -// else -// { -// write_tag = FALSE; -// } -// } - } - else if(! g_strcmp0 (category, "xmp") && support_xmp) - { - new_tag = g_strdup_printf ("%s", tag); - - write_tag = TRUE; - - namespace = gimp_attribute_is_new_namespace (attribute); - - if (namespace) - { - write_tag = FALSE; - - ns_name = gimp_attribute_get_attribute_ifd (attribute); - - for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) - { - struct Namespaces n_space = namespaces_table[i]; - if(! g_strcmp0 (ns_name, n_space.namespace_name)) - { - write_tag = TRUE; - break; - } - } - } - - if (write_tag && has_structure) - { - gboolean success = TRUE; - GSList *structure; - GSList *list; - GimpAttributeStructureType structure_type; - - structure = gimp_attribute_get_attribute_structure (attribute); - structure_type = gimp_attribute_get_structure_type (attribute); - - for (list = structure; list; list = list->next) - { - const gchar *structure_element = (const gchar*) list->data; - gboolean has_tag = gexiv2_metadata_has_tag (gexiv2metadata, structure_element); - - if (!has_tag && ! has_xmp_structure (xmp_structure_list, structure_element)) - { - switch (structure_type) - { - case STRUCTURE_TYPE_ALT: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_ALT); /*start block*/ - break; - case STRUCTURE_TYPE_BAG: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_BAG); /*start block*/ - break; - case STRUCTURE_TYPE_SEQ: - success = gexiv2_metadata_set_xmp_tag_struct (gexiv2metadata, structure_element, GEXIV2_STRUCTURE_XA_SEQ); /*start block*/ - break; - default: - success = FALSE; - break; - } - - if (success) - xmp_structure_list = g_slist_prepend (xmp_structure_list, (gpointer)structure_element); - } - } - } - } - else if(! g_strcmp0 (category, "iptc") && support_iptc) - { - new_tag = g_strdup_printf ("Xmp.iptc.%s", attribute_tag); - sec_tag = g_strdup_printf ("Xmp.iptcExt.%s", attribute_tag); - write_tag = TRUE; - } - else - { - write_tag = FALSE; - } - - if (write_tag) - { - switch (tag_value_type) - { - case TYPE_INVALID: - break; - case TYPE_LONG: - case TYPE_SLONG: - case TYPE_FLOAT: - case TYPE_DOUBLE: - case TYPE_SHORT: - case TYPE_SSHORT: - case TYPE_DATE: - case TYPE_TIME: - case TYPE_ASCII: - case TYPE_UNICODE: - case TYPE_BYTE: - case TYPE_RATIONAL: - case TYPE_SRATIONAL: - { - gexiv2_metadata_set_tag_string (gexiv2metadata, new_tag, value); - if (sec_tag) - { - gexiv2_metadata_set_tag_string (gexiv2metadata, sec_tag, value); - g_free (sec_tag); - } - - } - break; - case TYPE_MULTIPLE: - { - GValue h; - gchar **values; - - h = gimp_attribute_get_value (attribute); - values = (gchar **) g_value_get_boxed (&h); - gexiv2_metadata_set_tag_multiple (gexiv2metadata, new_tag, (const gchar **) values); - if (sec_tag) - { - gexiv2_metadata_set_tag_multiple (gexiv2metadata, sec_tag, (const gchar **) values); - g_free (sec_tag); - } - g_strfreev (values); - } - break; - case TYPE_UNKNOWN: - default: - break; - - } - - t_packet = gexiv2_metadata_generate_xmp_packet (gexiv2metadata, GEXIV2_USE_COMPACT_FORMAT | GEXIV2_OMIT_ALL_FORMATTING, 0); - - if (! t_packet || ! g_strcmp0 (t_packet, o_packet)) - { - gexiv2_metadata_clear_tag (gexiv2metadata, new_tag); - } - else - { - o_packet = g_strdup (t_packet); - } - } - } - - if (t_packet) - g_free (t_packet); - if (value) - g_free (value); - if (category) - g_free (category); - if (new_tag) - g_free (new_tag); - - if (temp_attribute) - g_object_unref (attribute); - } - } - - if (o_packet) - g_free (o_packet); - if (xmp_structure_list) - g_slist_free (xmp_structure_list); - - packet_string = gexiv2_metadata_generate_xmp_packet (gexiv2metadata, GEXIV2_USE_COMPACT_FORMAT | GEXIV2_WRITE_ALIAS_COMMENTS, 0); - return packet_string; -} - -/** - * gimp_metadata_has_tag_type: - * @metadata: The metadata - * @tag_type: The #GimpAttributeTagType to test - * - * tests, if @metadata contains at least one tag of @tag_type - * - * Return value: TRUE if found, FALSE otherwise - * - * Since: GIMP 2.10 - */ -gboolean -gimp_metadata_has_tag_type (GimpMetadata *metadata, - GimpAttributeTagType tag_type) -{ - GHashTableIter iter; - gpointer p_key, p_value; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), FALSE); - - gimp_metadata_from_gexiv2 (metadata); - - g_hash_table_iter_init (&iter, metadata->priv->attribute_table); - - while (g_hash_table_iter_next (&iter, &p_key, &p_value)) - { - GimpAttribute *attribute; - - attribute = (GimpAttribute *) p_value; - - if (gimp_attribute_get_tag_type (attribute) == tag_type) - return TRUE; - - } - return FALSE; -} - -GList * -gimp_metadata_iter_init (GimpMetadata *metadata, GList **iter) -{ - g_return_val_if_fail (IS_GIMP_METADATA (metadata), NULL); - - gimp_metadata_from_gexiv2 (metadata); - - *iter = metadata->priv->sorted_key_list; - iter_initialized = TRUE; - - return metadata->priv->sorted_key_list; -} - -gboolean -gimp_metadata_iter_next (GimpMetadata *metadata, GimpAttribute **attribute, GList **prev) -{ - gchar *sorted; - GList *tmp; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), FALSE); - - *attribute = NULL; - - if (iter_initialized) - { - tmp = g_list_first (*prev); - } - else - { - tmp = g_list_next (*prev); - } - - if (tmp) - { - *prev = tmp; - sorted = (gchar *) tmp->data; - - *attribute = gimp_metadata_get_attribute_sorted (metadata, sorted); - } - - iter_initialized = FALSE; - - if (*attribute) - return TRUE; - else - return FALSE; - -} - -/** - * gimp_metadata_error_quark: - * - * Return value: #GQuark - * - * Since: GIMP 2.10 - */ -static GQuark -gimp_metadata_error_quark (void) -{ - static GQuark quark = 0; - - if (G_UNLIKELY (quark == 0)) - quark = g_quark_from_static_string ("gimp-metadata-error-quark"); - - return quark; -} - -/** - * gimp_metadata_deserialize_error: - * - * Error while parsing - * - * Since: GIMP 2.10 - */ -static void -gimp_metadata_deserialize_error (GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ - g_printerr ("XML parse error: %s\n", error->message); -} - -/** - * gimp_metadata_name_to_value: - * - * @attribute_names : #gchar ** - * @attribute_values : #gchar ** - * @name : #gchar * - * - * searches for values in @attribute_values by a given @name (parsing xml) - * - * Since: GIMP 2.10 - */ static const gchar* -gimp_metadata_name_to_value (const gchar **attribute_names, - const gchar **attribute_values, - const gchar *name) +gimp_metadata_attribute_name_to_value (const gchar **attribute_names, + const gchar **attribute_values, + const gchar *name) { while (*attribute_names) { @@ -2328,27 +228,13 @@ gimp_metadata_name_to_value (const gchar **attribute_names, return NULL; } -/** - * gimp_metadata_deserialize_start_element: - * - * @context : #GMarkupParseContext - * @element_name : #gchar * - * @attribute_names : #gchar ** - * @attribute_values : #gchar ** - * @user_data : #gpointer to #GimpMetadataParseData struct - * @error : #GError ** - * - * start of a tag (parsing xml) - * - * Since: GIMP 2.10 - */ static void gimp_metadata_deserialize_start_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) { GimpMetadataParseData *parse_data = user_data; @@ -2357,10 +243,10 @@ gimp_metadata_deserialize_start_element (GMarkupParseContext *context, const gchar *name; const gchar *encoding; - name = gimp_metadata_name_to_value (attribute_names, + name = gimp_metadata_attribute_name_to_value (attribute_names, attribute_values, "name"); - encoding = gimp_metadata_name_to_value (attribute_names, + encoding = gimp_metadata_attribute_name_to_value (attribute_names, attribute_values, "encoding"); @@ -2376,73 +262,16 @@ gimp_metadata_deserialize_start_element (GMarkupParseContext *context, parse_data->base64 = (encoding && ! strcmp (encoding, "base64")); } - else if (! strcmp (element_name, "attribute")) - { - const gchar *name = NULL; - const gchar *type = NULL; - - name = gimp_metadata_name_to_value (attribute_names, - attribute_values, - "name"); - type = gimp_metadata_name_to_value (attribute_names, - attribute_values, - "type"); - - if (! name) - { - g_set_error (error, gimp_metadata_error_quark (), 1001, - "Element 'tag' does not contain required attribute 'name'."); - return; - } - - if (! type) - { - g_set_error (error, gimp_metadata_error_quark (), 1001, - "Element 'tag' does not contain required attribute 'type'."); - return; - } - - strncpy (parse_data->name, name, sizeof (parse_data->name)); - parse_data->name[sizeof (parse_data->name) - 1] = 0; - - parse_data->type = (GimpAttributeValueType) atoi (type); - } - else if (! strcmp (element_name, "value")) - { - const gchar *encoding = NULL; - - encoding = gimp_metadata_name_to_value (attribute_names, - attribute_values, - "encoding"); - - parse_data->base64 = (encoding && ! strcmp (encoding, "base64")); - } - else if (! strcmp (element_name, "interpreted")) - { - const gchar *encoding = NULL; - - encoding = gimp_metadata_name_to_value (attribute_names, - attribute_values, - "encoding"); - - parse_data->base64 = (encoding && ! strcmp (encoding, "base64")); - } - } -/** - * gimp_metadata_deserialize_text: - * - * @context : #GMarkupParseContext - * @text : const #gchar * - * @text_len : #gsize - * @user_data : #gpointer to #GimpMetadataParseData struct - * @error : #GError ** - * - * text of a tag (parsing xml) - * - * Since: GIMP 2.10 - */ +static void +gimp_metadata_deserialize_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ +} + static void gimp_metadata_deserialize_text (GMarkupParseContext *context, const gchar *text, @@ -2450,13 +279,12 @@ gimp_metadata_deserialize_text (GMarkupParseContext *context, gpointer user_data, GError **error) { - GimpMetadataParseData *parse_data = user_data; - GimpAttribute *attribute = NULL; - const gchar *current_element; + GimpMetadataParseData *parse_data = user_data; + const gchar *current_element; current_element = g_markup_parse_context_get_element (context); - if (! g_strcmp0 (current_element, "tag")) /*old metadata*/ + if (! g_strcmp0 (current_element, "tag")) { gchar *value = g_strndup (text, text_len); @@ -2468,7 +296,7 @@ gimp_metadata_deserialize_text (GMarkupParseContext *context, decoded = g_base64_decode (value, &len); if (decoded[len - 1] == '\0') - gexiv2_metadata_set_tag_string (GEXIV2_METADATA (parse_data->metadata), + gexiv2_metadata_set_tag_string (parse_data->metadata, parse_data->name, (const gchar *) decoded); @@ -2476,239 +304,193 @@ gimp_metadata_deserialize_text (GMarkupParseContext *context, } else { - gexiv2_metadata_set_tag_string (GEXIV2_METADATA (parse_data->metadata), + gexiv2_metadata_set_tag_string (parse_data->metadata, parse_data->name, value); } g_free (value); } - else if (! g_strcmp0 (current_element, "value")) +} + +static void +gimp_metadata_deserialize_error (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + g_printerr ("Metadata parse error: %s\n", error->message); +} + +/** + * gimp_metadata_deserialize: + * @metadata_xml: A string of serialized metadata XML. + * + * Deserializes a string of XML that has been created by + * gimp_metadata_serialize(). + * + * Return value: The new #GimpMetadata. + * + * Since: 2.10 + */ +GimpMetadata * +gimp_metadata_deserialize (const gchar *metadata_xml) +{ + GimpMetadata *metadata; + GMarkupParser markup_parser; + GimpMetadataParseData parse_data; + GMarkupParseContext *context; + + g_return_val_if_fail (metadata_xml != NULL, NULL); + + metadata = gimp_metadata_new (); + + parse_data.metadata = metadata; + + markup_parser.start_element = gimp_metadata_deserialize_start_element; + markup_parser.end_element = gimp_metadata_deserialize_end_element; + markup_parser.text = gimp_metadata_deserialize_text; + markup_parser.passthrough = NULL; + markup_parser.error = gimp_metadata_deserialize_error; + + context = g_markup_parse_context_new (&markup_parser, 0, &parse_data, NULL); + + g_markup_parse_context_parse (context, + metadata_xml, strlen (metadata_xml), + NULL); + + g_markup_parse_context_unref (context); + + return metadata; +} + +static gchar * +gimp_metadata_escape (const gchar *name, + const gchar *value, + gboolean *base64) +{ + if (! g_utf8_validate (value, -1, NULL)) { - gchar *value = g_strndup (text, text_len); + gchar *encoded; - if (parse_data->base64) + encoded = g_base64_encode ((const guchar *) value, strlen (value) + 1); + + g_printerr ("Invalid UTF-8 in metadata value %s, encoding as base64: %s\n", + name, encoded); + + *base64 = TRUE; + + return encoded; + } + + *base64 = FALSE; + + return g_markup_escape_text (value, -1); +} + +static void +gimp_metadata_append_tag (GString *string, + const gchar *name, + gchar *value, + gboolean base64) +{ + if (value) + { + if (base64) { - guchar *decoded; - gsize len; - - decoded = g_base64_decode (value, &len); - - if (decoded[len - 1] == '\0') - attribute = gimp_attribute_new_string (parse_data->name, - (gchar *)decoded, - parse_data->type); - - g_free (decoded); + g_string_append_printf (string, " %s\n", + name, value); } else { - attribute = gimp_attribute_new_string (parse_data->name, - value, - parse_data->type); + g_string_append_printf (string, " %s\n", + name, value); } g_free (value); - - if (attribute && gimp_attribute_is_valid (attribute)) - { - gimp_metadata_add_attribute (parse_data->metadata, attribute); - current_attribute = attribute; - } - else - g_object_unref (attribute); - - } - else if (! g_strcmp0 (current_element, "structure")) - { - GimpAttribute *attribute = NULL; - gchar *value = NULL; - - attribute = current_attribute; - - if (attribute) - { - gint v; - GimpAttributeStructureType struct_type = STRUCTURE_TYPE_BAG; - - value = g_strndup (text, text_len); - - v = atoi (value); - - if (v > -1) - struct_type = (GimpAttributeStructureType) v; - - gimp_attribute_set_structure_type (attribute, struct_type); - - g_free (value); - } - } - else if (! g_strcmp0 (current_element, "interpreted")) - { - GimpAttribute *attribute = NULL; - gchar *value = NULL; - - attribute = current_attribute; - - if (attribute) - { - value = g_strndup (text, text_len); - - if (parse_data->base64) - { - guchar *decoded = NULL; - gsize len; - - decoded = g_base64_decode (value, &len); - - if (decoded[len - 1] == '\0') - gimp_attribute_set_interpreted_string (attribute, (const gchar *)decoded); - - g_free (decoded); - } - else - { - gimp_attribute_set_interpreted_string (attribute, (const gchar *)value); - } - g_free (value); - } } } /** - * gimp_metadata_deserialize_end_element: - * - * @context : #GMarkupParseContext - * @element_name : #gchar * - * @user_data : #gpointer to #GimpMetadataParseData struct - * @error : #GError ** - * - * end of a tag (parsing xml) - * - * Since: GIMP 2.10 - */ -static void -gimp_metadata_deserialize_end_element (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - GimpMetadataParseData *parse_data = user_data; - - if (! strcmp (element_name, "attribute")) - { - current_attribute = NULL; - } - else if (! strcmp (element_name, "value")) - { - parse_data->base64 = FALSE; - } - else if (! strcmp (element_name, "interpreted")) - { - parse_data->base64 = FALSE; - } -} - -static gboolean -has_xmp_structure (GSList *xmp_list, const gchar *entry) -{ - GSList *list; - - for (list = xmp_list; list; list = list->next) - { - const gchar *to_test = (const gchar*) list->data; - - if (! g_strcmp0 (to_test, entry)) - return TRUE; - } - - return FALSE; -} - -/** - * gimp_metadata_new_gexiv2metadata: - * - * Creates a new #GExiv2Metadata instance. - * - * Return value: The new #GExiv2Metadata. - * - * Since: 2.10 - */ -GExiv2Metadata * -gimp_metadata_new_gexiv2metadata (void) -{ - GExiv2Metadata *gexiv2metadata = NULL; - gint i; - - if (gexiv2_initialize ()) - { - gexiv2metadata = gexiv2_metadata_new (); - - if (! gexiv2_metadata_open_buf (gexiv2metadata, wilber_jpg, wilber_jpg_len, - NULL)) - { - g_object_unref (gexiv2metadata); - - return NULL; - } - for (i = 0; i < G_N_ELEMENTS (namespaces_table); i++) - { - struct Namespaces n_space = namespaces_table[i]; - gexiv2_metadata_register_xmp_namespace (n_space.namespace_URI, n_space.namespace_name); - } - - } - return gexiv2metadata; -} - - -/** - * gimp_metadata_save_to_file: + * gimp_metadata_serialize: * @metadata: A #GimpMetadata instance. - * @file: The file to save the metadata to - * @error: Return location for error message * - * Saves @metadata to @file. + * Serializes @metadata into an XML string that can later be deserialized + * using gimp_metadata_deserialize(). * - * Return value: %TRUE on success, %FALSE otherwise. + * Return value: The serialized XML string. * * Since: 2.10 */ -gboolean -gimp_metadata_save_to_file (GimpMetadata *metadata, - GFile *file, - GError **error) +gchar * +gimp_metadata_serialize (GimpMetadata *metadata) { - gchar *path; - gchar *filename; - gboolean success; + GString *string; + gchar **exif_data = NULL; + gchar **iptc_data = NULL; + gchar **xmp_data = NULL; + gchar *value; + gchar *escaped; + gboolean base64; + gint i; - g_return_val_if_fail (IS_GIMP_METADATA (metadata), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (GEXIV2_IS_METADATA (metadata), NULL); - path = g_file_get_path (file); + string = g_string_new (NULL); - if (! path) + g_string_append (string, "\n"); + g_string_append (string, "\n"); + + exif_data = gexiv2_metadata_get_exif_tags (metadata); + + if (exif_data) { - g_set_error (error, gimp_metadata_error_quark (), 0, - _("Can save metadata only to local files")); - return FALSE; + for (i = 0; exif_data[i] != NULL; i++) + { + value = gexiv2_metadata_get_tag_string (metadata, exif_data[i]); + escaped = gimp_metadata_escape (exif_data[i], value, &base64); + g_free (value); + + gimp_metadata_append_tag (string, exif_data[i], escaped, base64); + } + + g_strfreev (exif_data); } -#ifdef G_OS_WIN32 - filename = g_win32_locale_filename_from_utf8 (path); -#else - filename = g_strdup (path); -#endif + xmp_data = gexiv2_metadata_get_xmp_tags (metadata); - g_free (path); + if (xmp_data) + { + for (i = 0; xmp_data[i] != NULL; i++) + { + value = gexiv2_metadata_get_tag_string (metadata, xmp_data[i]); + escaped = gimp_metadata_escape (xmp_data[i], value, &base64); + g_free (value); - success = gexiv2_metadata_save_file (GEXIV2_METADATA (metadata), filename, error); + gimp_metadata_append_tag (string, xmp_data[i], escaped, base64); + } - g_free (filename); + g_strfreev (xmp_data); + } - return success; + iptc_data = gexiv2_metadata_get_iptc_tags (metadata); + + if (iptc_data) + { + for (i = 0; iptc_data[i] != NULL; i++) + { + value = gexiv2_metadata_get_tag_string (metadata, iptc_data[i]); + escaped = gimp_metadata_escape (iptc_data[i], value, &base64); + g_free (value); + + gimp_metadata_append_tag (string, iptc_data[i], escaped, base64); + } + + g_strfreev (iptc_data); + } + + g_string_append (string, "\n"); + + return g_string_free (string, FALSE); } /** @@ -2726,7 +508,7 @@ GimpMetadata * gimp_metadata_load_from_file (GFile *file, GError **error) { - GimpMetadata *metadata = NULL; + GExiv2Metadata *meta = NULL; gchar *path; gchar *filename; @@ -2752,12 +534,12 @@ gimp_metadata_load_from_file (GFile *file, if (gexiv2_initialize ()) { - metadata = gimp_metadata_new (); + meta = gexiv2_metadata_new (); - if (! gexiv2_metadata_open_path (GEXIV2_METADATA (metadata), filename, error)) + if (! gexiv2_metadata_open_path (meta, filename, error)) { + g_object_unref (meta); g_free (filename); - g_object_unref (metadata); return NULL; } @@ -2765,7 +547,56 @@ gimp_metadata_load_from_file (GFile *file, g_free (filename); - return metadata; + return meta; +} + +/** + * gimp_metadata_save_to_file: + * @metadata: A #GimpMetadata instance. + * @file: The file to save the metadata to + * @error: Return location for error message + * + * Saves @metadata to @file. + * + * Return value: %TRUE on success, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_save_to_file (GimpMetadata *metadata, + GFile *file, + GError **error) +{ + gchar *path; + gchar *filename; + gboolean success; + + g_return_val_if_fail (GEXIV2_IS_METADATA (metadata), FALSE); + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + path = g_file_get_path (file); + + if (! path) + { + g_set_error (error, gimp_metadata_error_quark (), 0, + _("Can save metadata only to local files")); + return FALSE; + } + +#ifdef G_OS_WIN32 + filename = g_win32_locale_filename_from_utf8 (path); +#else + filename = g_strdup (path); +#endif + + g_free (path); + + success = gexiv2_metadata_save_file (metadata, filename, error); + + g_free (filename); + + return success; } /** @@ -2788,20 +619,17 @@ gimp_metadata_set_from_exif (GimpMetadata *metadata, GError **error) { - GByteArray *exif_bytes; - GExiv2Metadata *exif_metadata; - guint8 data_size[2] = { 0, }; - const guint8 eoi[2] = { 0xff, 0xd9 }; + GByteArray *exif_bytes; + GimpMetadata *exif_metadata; + guint8 data_size[2] = { 0, }; + const guint8 eoi[2] = { 0xff, 0xd9 }; - g_return_val_if_fail (IS_GIMP_METADATA (metadata), FALSE); + g_return_val_if_fail (GEXIV2_IS_METADATA (metadata), FALSE); g_return_val_if_fail (exif_data != NULL, FALSE); g_return_val_if_fail (exif_data_length > 0, FALSE); g_return_val_if_fail (exif_data_length + 2 < 65536, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - exif_metadata = GEXIV2_METADATA (metadata); - g_object_ref (exif_metadata); - data_size[0] = ((exif_data_length + 2) & 0xFF00) >> 8; data_size[1] = ((exif_data_length + 2) & 0x00FF); @@ -2814,6 +642,8 @@ gimp_metadata_set_from_exif (GimpMetadata *metadata, (guint8 *) exif_data, exif_data_length); exif_bytes = g_byte_array_append (exif_bytes, eoi, 2); + exif_metadata = gimp_metadata_new (); + if (! gexiv2_metadata_open_buf (exif_metadata, exif_bytes->data, exif_bytes->len, error)) { @@ -2831,6 +661,7 @@ gimp_metadata_set_from_exif (GimpMetadata *metadata, return FALSE; } + gimp_metadata_add (exif_metadata, metadata); g_object_unref (exif_metadata); g_byte_array_free (exif_bytes, TRUE); @@ -2856,15 +687,14 @@ gimp_metadata_set_from_xmp (GimpMetadata *metadata, gint xmp_data_length, GError **error) { - GExiv2Metadata *xmp_metadata; + GimpMetadata *xmp_metadata; - g_return_val_if_fail (IS_GIMP_METADATA (metadata), FALSE); + g_return_val_if_fail (GEXIV2_IS_METADATA (metadata), FALSE); g_return_val_if_fail (xmp_data != NULL, FALSE); g_return_val_if_fail (xmp_data_length > 0, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - xmp_metadata = GEXIV2_METADATA (metadata); - g_object_ref (xmp_metadata); + xmp_metadata = gimp_metadata_new (); if (! gexiv2_metadata_open_buf (xmp_metadata, xmp_data, xmp_data_length, error)) @@ -2881,10 +711,376 @@ gimp_metadata_set_from_xmp (GimpMetadata *metadata, return FALSE; } + gimp_metadata_add (xmp_metadata, metadata); g_object_unref (xmp_metadata); + return TRUE; } +/** + * gimp_metadata_set_pixel_size: + * @metadata: A #GimpMetadata instance. + * @width: Width in pixels + * @height: Height in pixels + * + * Sets Exif.Image.ImageWidth and Exif.Image.ImageLength on @metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_set_pixel_size (GimpMetadata *metadata, + gint width, + gint height) +{ + gchar buffer[32]; + + g_return_if_fail (GEXIV2_IS_METADATA (metadata)); + + g_snprintf (buffer, sizeof (buffer), "%d", width); + gexiv2_metadata_set_tag_string (metadata, "Exif.Image.ImageWidth", buffer); + + g_snprintf (buffer, sizeof (buffer), "%d", height); + gexiv2_metadata_set_tag_string (metadata, "Exif.Image.ImageLength", buffer); +} + +/** + * gimp_metadata_set_bits_per_sample: + * @metadata: A #GimpMetadata instance. + * @bits_per_sample: Bits per pixel, per component + * + * Sets Exif.Image.BitsPerSample on @metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_set_bits_per_sample (GimpMetadata *metadata, + gint bits_per_sample) +{ + gchar buffer[32]; + + g_return_if_fail (GEXIV2_IS_METADATA (metadata)); + + g_snprintf (buffer, sizeof (buffer), "%d %d %d", + bits_per_sample, bits_per_sample, bits_per_sample); + gexiv2_metadata_set_tag_string (metadata, "Exif.Image.BitsPerSample", buffer); +} + +/** + * gimp_metadata_get_resolution: + * @metadata: A #GimpMetadata instance. + * @xres: Return location for the X Resolution, in ppi + * @yres: Return location for the Y Resolution, in ppi + * @unit: Return location for the unit unit + * + * Returns values based on Exif.Image.XResolution, + * Exif.Image.YResolution and Exif.Image.ResolutionUnit of @metadata. + * + * Return value: %TRUE on success, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_get_resolution (GimpMetadata *metadata, + gdouble *xres, + gdouble *yres, + GimpUnit *unit) +{ + gint xnom, xdenom; + gint ynom, ydenom; + + g_return_val_if_fail (GEXIV2_IS_METADATA (metadata), FALSE); + + if (gexiv2_metadata_get_exif_tag_rational (metadata, + "Exif.Image.XResolution", + &xnom, &xdenom) && + gexiv2_metadata_get_exif_tag_rational (metadata, + "Exif.Image.YResolution", + &ynom, &ydenom)) + { + gchar *un; + gint exif_unit = 2; + + un = gexiv2_metadata_get_tag_string (metadata, + "Exif.Image.ResolutionUnit"); + if (un) + { + exif_unit = atoi (un); + g_free (un); + } + + if (xnom != 0 && xdenom != 0 && + ynom != 0 && ydenom != 0) + { + gdouble xresolution = (gdouble) xnom / (gdouble) xdenom; + gdouble yresolution = (gdouble) ynom / (gdouble) ydenom; + + if (exif_unit == 3) + { + xresolution *= 2.54; + yresolution *= 2.54; + } + + if (xresolution >= GIMP_MIN_RESOLUTION && + xresolution <= GIMP_MAX_RESOLUTION && + yresolution >= GIMP_MIN_RESOLUTION && + yresolution <= GIMP_MAX_RESOLUTION) + { + if (xres) + *xres = xresolution; + + if (yres) + *yres = yresolution; + + if (unit) + { + if (exif_unit == 3) + *unit = GIMP_UNIT_MM; + else + *unit = GIMP_UNIT_INCH; + } + + return TRUE; + } + } + } + + return FALSE; +} + +/** + * gimp_metadata_set_resolution: + * @metadata: A #GimpMetadata instance. + * @xres: The image's X Resolution, in ppi + * @yres: The image's Y Resolution, in ppi + * @unit: The image's unit + * + * Sets Exif.Image.XResolution, Exif.Image.YResolution and + * Exif.Image.ResolutionUnit of @metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_set_resolution (GimpMetadata *metadata, + gdouble xres, + gdouble yres, + GimpUnit unit) +{ + gchar buffer[32]; + gint exif_unit; + gint factor; + + g_return_if_fail (GEXIV2_IS_METADATA (metadata)); + + if (gimp_unit_is_metric (unit)) + { + xres /= 2.54; + yres /= 2.54; + + exif_unit = 3; + } + else + { + exif_unit = 2; + } + + for (factor = 1; factor <= 100 /* arbitrary */; factor++) + { + if (fabs (xres * factor - ROUND (xres * factor)) < 0.01 && + fabs (yres * factor - ROUND (yres * factor)) < 0.01) + break; + } + + gexiv2_metadata_set_exif_tag_rational (metadata, + "Exif.Image.XResolution", + ROUND (xres * factor), factor); + + gexiv2_metadata_set_exif_tag_rational (metadata, + "Exif.Image.YResolution", + ROUND (yres * factor), factor); + + g_snprintf (buffer, sizeof (buffer), "%d", exif_unit); + gexiv2_metadata_set_tag_string (metadata, "Exif.Image.ResolutionUnit", buffer); +} + +/** + * gimp_metadata_get_colorspace: + * @metadata: A #GimpMetadata instance. + * + * Returns values based on Exif.Photo.ColorSpace, Xmp.exif.ColorSpace, + * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace, + * Exif.Canon.ColorSpace of @metadata. + * + * Return value: The colorspace specified by above tags. + * + * Since: 2.10 + */ +GimpMetadataColorspace +gimp_metadata_get_colorspace (GimpMetadata *metadata) +{ + glong exif_cs = -1; + + g_return_val_if_fail (GEXIV2_IS_METADATA (metadata), + GIMP_METADATA_COLORSPACE_UNSPECIFIED); + + /* the logic here was mostly taken from darktable and libkexiv2 */ + + if (gexiv2_metadata_has_tag (metadata, "Exif.Photo.ColorSpace")) + { + exif_cs = gexiv2_metadata_get_tag_long (metadata, + "Exif.Photo.ColorSpace"); + } + else if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace")) + { + exif_cs = gexiv2_metadata_get_tag_long (metadata, + "Xmp.exif.ColorSpace"); + } + + if (exif_cs == 0x01) + { + return GIMP_METADATA_COLORSPACE_SRGB; + } + else if (exif_cs == 0x02) + { + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + else + { + if (exif_cs == 0xffff) + { + gchar *iop_index; + + iop_index = gexiv2_metadata_get_tag_string (metadata, + "Exif.Iop.InteroperabilityIndex"); + + if (! g_strcmp0 (iop_index, "R03")) + { + g_free (iop_index); + + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + else if (! g_strcmp0 (iop_index, "R98")) + { + g_free (iop_index); + + return GIMP_METADATA_COLORSPACE_SRGB; + } + + g_free (iop_index); + } + + if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace")) + { + glong nikon_cs; + + nikon_cs = gexiv2_metadata_get_tag_long (metadata, + "Exif.Nikon3.ColorSpace"); + + if (nikon_cs == 0x01) + { + return GIMP_METADATA_COLORSPACE_SRGB; + } + else if (nikon_cs == 0x02) + { + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + } + + if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace")) + { + glong canon_cs; + + canon_cs = gexiv2_metadata_get_tag_long (metadata, + "Exif.Canon.ColorSpace"); + + if (canon_cs == 0x01) + { + return GIMP_METADATA_COLORSPACE_SRGB; + } + else if (canon_cs == 0x02) + { + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + } + + if (exif_cs == 0xffff) + return GIMP_METADATA_COLORSPACE_UNCALIBRATED; + } + + return GIMP_METADATA_COLORSPACE_UNSPECIFIED; +} + +/** + * gimp_metadata_set_colorspace: + * @metadata: A #GimpMetadata instance. + * @colorspace: The color space. + * + * Sets Exif.Photo.ColorSpace, Xmp.exif.ColorSpace, + * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace, + * Exif.Canon.ColorSpace of @metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_set_colorspace (GimpMetadata *metadata, + GimpMetadataColorspace colorspace) +{ + g_return_if_fail (GEXIV2_IS_METADATA (metadata)); + + switch (colorspace) + { + case GIMP_METADATA_COLORSPACE_UNSPECIFIED: + gexiv2_metadata_clear_tag (metadata, "Exif.Photo.ColorSpace"); + gexiv2_metadata_clear_tag (metadata, "Xmp.exif.ColorSpace"); + gexiv2_metadata_clear_tag (metadata, "Exif.Iop.InteroperabilityIndex"); + gexiv2_metadata_clear_tag (metadata, "Exif.Nikon3.ColorSpace"); + gexiv2_metadata_clear_tag (metadata, "Exif.Canon.ColorSpace"); + break; + + case GIMP_METADATA_COLORSPACE_UNCALIBRATED: + gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0xffff); + if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace")) + gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0xffff); + gexiv2_metadata_clear_tag (metadata, "Exif.Iop.InteroperabilityIndex"); + gexiv2_metadata_clear_tag (metadata, "Exif.Nikon3.ColorSpace"); + gexiv2_metadata_clear_tag (metadata, "Exif.Canon.ColorSpace"); + break; + + case GIMP_METADATA_COLORSPACE_SRGB: + gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0x01); + + if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace")) + gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0x01); + + if (gexiv2_metadata_has_tag (metadata, "Exif.Iop.InteroperabilityIndex")) + gexiv2_metadata_set_tag_string (metadata, + "Exif.Iop.InteroperabilityIndex", "R98"); + + if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace")) + gexiv2_metadata_set_tag_long (metadata, "Exif.Nikon3.ColorSpace", 0x01); + + if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace")) + gexiv2_metadata_set_tag_long (metadata, "Exif.Canon.ColorSpace", 0x01); + break; + + case GIMP_METADATA_COLORSPACE_ADOBERGB: + gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0x02); + + if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace")) + gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0x02); + + if (gexiv2_metadata_has_tag (metadata, "Exif.Iop.InteroperabilityIndex")) + gexiv2_metadata_set_tag_string (metadata, + "Exif.Iop.InteroperabilityIndex", "R03"); + + if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace")) + gexiv2_metadata_set_tag_long (metadata, "Exif.Nikon3.ColorSpace", 0x02); + + if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace")) + gexiv2_metadata_set_tag_long (metadata, "Exif.Canon.ColorSpace", 0x02); + break; + } +} + /** * gimp_metadata_is_tag_supported: * @tag: A metadata tag name @@ -2937,418 +1133,78 @@ gimp_metadata_is_tag_supported (const gchar *tag, return TRUE; } -/** - * gimp_metadata_get_colorspace: - * @metadata: Ab #GimpMetadata instance. - * - * Returns values based on Exif.Photo.ColorSpace, Xmp.exif.ColorSpace, - * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace, - * Exif.Canon.ColorSpace of @metadata. - * - * Return value: The colorspace specified by above tags. - * - * Since: 2.10 - */ -GimpMetadataColorspace -gimp_metadata_get_colorspace (GimpMetadata *metadata) + +/* private functions */ + +static GQuark +gimp_metadata_error_quark (void) { - glong exif_cs = -1; - GimpAttribute *attribute = NULL; - GValue val; + static GQuark quark = 0; - g_return_val_if_fail (IS_GIMP_METADATA (metadata), - GIMP_METADATA_COLORSPACE_UNSPECIFIED); + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("gimp-metadata-error-quark"); - /* the logic here was mostly taken from darktable and libkexiv2 */ + return quark; +} - attribute = gimp_metadata_get_attribute (metadata, "Exif.Photo.ColorSpace"); - if ( ! attribute) +static void +gimp_metadata_add (GimpMetadata *src, + GimpMetadata *dest) +{ + gchar *value; + gint i; + + if (gexiv2_metadata_get_supports_exif (src) && + gexiv2_metadata_get_supports_exif (dest)) { - attribute = gimp_metadata_get_attribute (metadata, "Xmp.exif.ColorSpace"); - } + gchar **exif_data = gexiv2_metadata_get_exif_tags (src); - if (attribute) - { - if (gimp_attribute_get_value_type (attribute) == TYPE_LONG || gimp_attribute_get_value_type (attribute) == TYPE_SLONG) + if (exif_data) { - val = gimp_attribute_get_value (attribute); - exif_cs = g_value_get_long (&val); - } - } - - if (exif_cs == 0x01) - { - return GIMP_METADATA_COLORSPACE_SRGB; - } - else if (exif_cs == 0x02) - { - return GIMP_METADATA_COLORSPACE_ADOBERGB; - } - else - { - if (exif_cs == 0xffff) - { - gchar *iop_index; - - attribute = gimp_metadata_get_attribute (metadata, "Exif.Iop.InteroperabilityIndex"); - if (attribute) - iop_index = gimp_attribute_get_string (attribute); - - if (! g_strcmp0 (iop_index, "R03")) + for (i = 0; exif_data[i] != NULL; i++) { - g_free (iop_index); - - return GIMP_METADATA_COLORSPACE_ADOBERGB; - } - else if (! g_strcmp0 (iop_index, "R98")) - { - g_free (iop_index); - - return GIMP_METADATA_COLORSPACE_SRGB; + value = gexiv2_metadata_get_tag_string (src, exif_data[i]); + gexiv2_metadata_set_tag_string (dest, exif_data[i], value); + g_free (value); } - g_free (iop_index); + g_strfreev (exif_data); } + } - attribute = gimp_metadata_get_attribute (metadata, "Exif.Nikon3.ColorSpace"); - if (attribute) + if (gexiv2_metadata_get_supports_xmp (src) && + gexiv2_metadata_get_supports_xmp (dest)) + { + gchar **xmp_data = gexiv2_metadata_get_xmp_tags (src); + + if (xmp_data) { - if (gimp_attribute_get_value_type (attribute) == TYPE_LONG || gimp_attribute_get_value_type (attribute) == TYPE_SLONG) + for (i = 0; xmp_data[i] != NULL; i++) { - glong nikon_cs; - - val = gimp_attribute_get_value (attribute); - nikon_cs = g_value_get_long (&val); - - if (nikon_cs == 0x01) - { - return GIMP_METADATA_COLORSPACE_SRGB; - } - else if (nikon_cs == 0x02) - { - return GIMP_METADATA_COLORSPACE_ADOBERGB; - } - } - } - - attribute = gimp_metadata_get_attribute (metadata, "Exif.Canon.ColorSpace"); - if (attribute) - { - if (gimp_attribute_get_value_type (attribute) == TYPE_LONG || gimp_attribute_get_value_type (attribute) == TYPE_SLONG) - { - glong canon_cs; - - val = gimp_attribute_get_value (attribute); - canon_cs = g_value_get_long (&val); - - if (canon_cs == 0x01) - { - return GIMP_METADATA_COLORSPACE_SRGB; - } - else if (canon_cs == 0x02) - { - return GIMP_METADATA_COLORSPACE_ADOBERGB; - } - } - } - - if (exif_cs == 0xffff) - return GIMP_METADATA_COLORSPACE_UNCALIBRATED; - } - - return GIMP_METADATA_COLORSPACE_UNSPECIFIED; -} - -/** - * gimp_metadata_get_resolution: - * @metadata: A #GimpMetadata instance. - * @xres: Return location for the X Resolution, in ppi - * @yres: Return location for the Y Resolution, in ppi - * @unit: Return location for the unit unit - * - * Returns values based on Exif.Image.XResolution, - * Exif.Image.YResolution and Exif.Image.ResolutionUnit of @metadata. - * - * Return value: %TRUE on success, %FALSE otherwise. - * - * Since: GIMP 2.10 - */ -gboolean -gimp_metadata_get_resolution (GimpMetadata *metadata, - gdouble *xres, - gdouble *yres, - GimpUnit *unit) -{ - GimpAttribute *x_attribute; - GimpAttribute *y_attribute; - GimpAttribute *res_attribute; - - gint xnom, xdenom; - gint ynom, ydenom; - gint exif_unit = 2; - - g_return_val_if_fail (IS_GIMP_METADATA (metadata), FALSE); - - x_attribute = gimp_metadata_get_attribute (metadata, "Exif.Image.XResolution"); - y_attribute = gimp_metadata_get_attribute (metadata, "Exif.Image.YResolution"); - res_attribute = gimp_metadata_get_attribute (metadata, "Exif.Image.ResolutionUnit"); - - if (x_attribute) - { - GValue value; - Rational *rats; - gint *_nom; - gint *_denom; - gint l; - - value = gimp_attribute_get_value (x_attribute); - - rats = g_value_get_boxed (&value); - - rational_to_int (rats, &_nom, &_denom, &l); - - if (l > 0) - { - xnom = _nom[0]; - xdenom = _denom[0]; - } - rational_free (rats); - } - else - return FALSE; - - if (y_attribute) - { - GValue value; - Rational *rats; - gint *_nom; - gint *_denom; - gint l; - - value = gimp_attribute_get_value (y_attribute); - - rats = g_value_get_boxed (&value); - - rational_to_int (rats, &_nom, &_denom, &l); - - if (l > 0) - { - ynom = _nom[0]; - ydenom = _denom[0]; - } - rational_free (rats); - } - else - return FALSE; - - if (res_attribute) - { - GValue value = gimp_attribute_get_value (res_attribute); - - exif_unit = (gint) g_value_get_uint (&value); - } - - if (xnom != 0 && xdenom != 0 && - ynom != 0 && ydenom != 0) - { - gdouble xresolution = (gdouble) xnom / (gdouble) xdenom; - gdouble yresolution = (gdouble) ynom / (gdouble) ydenom; - - if (exif_unit == 3) - { - xresolution *= 2.54; - yresolution *= 2.54; - } - - if (xresolution >= GIMP_MIN_RESOLUTION && - xresolution <= GIMP_MAX_RESOLUTION && - yresolution >= GIMP_MIN_RESOLUTION && - yresolution <= GIMP_MAX_RESOLUTION) - { - if (xres) - *xres = xresolution; - - if (yres) - *yres = yresolution; - - if (unit) - { - if (exif_unit == 3) - *unit = GIMP_UNIT_MM; - else - *unit = GIMP_UNIT_INCH; + value = gexiv2_metadata_get_tag_string (src, xmp_data[i]); + gexiv2_metadata_set_tag_string (dest, xmp_data[i], value); + g_free (value); } - return TRUE; + g_strfreev (xmp_data); } } - return FALSE; -} -/** - * gimp_metadata_set_bits_per_sample: - * @metadata: A #GimpMetadata instance. - * @bps: Bytes per pixel, per component - * - * Sets Exif.Image.BitsPerSample on @metadata. - * - * Since: GIMP 2.10 - */ -void -gimp_metadata_set_bits_per_sample (GimpMetadata *metadata, - gint bps) -{ - gchar buffer[32]; - - g_return_if_fail ( (metadata)); - - g_snprintf (buffer, sizeof (buffer), "%d", bps); - gimp_metadata_new_attribute (metadata, "Exif.Image.BitsPerSample", buffer, TYPE_SHORT); -} - -/** - * gimp_metadata_set_pixel_size: - * @metadata: A #GimpMetadata instance. - * @width: Width in pixels - * @height: Height in pixels - * - * Sets Exif.Image.ImageWidth and Exif.Image.ImageLength on @metadata. - * - * Since: GIMP 2.10 - */ -void -gimp_metadata_set_pixel_size (GimpMetadata *metadata, - gint width, - gint height) -{ - gchar buffer[32]; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - - g_snprintf (buffer, sizeof (buffer), "%d", width); - gimp_metadata_new_attribute (metadata, "Exif.Image.ImageWidth", buffer, TYPE_LONG); - - g_snprintf (buffer, sizeof (buffer), "%d", height); - gimp_metadata_new_attribute (metadata, "Exif.Image.ImageLength", buffer, TYPE_LONG); -} - -/** - * gimp_metadata_set_colorspace: - * @metadata: A #GimpMetadata instance. - * @colorspace: The color space. - * - * Sets Exif.Photo.ColorSpace, Xmp.exif.ColorSpace, - * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace, - * Exif.Canon.ColorSpace of @metadata. - * - * Since: 2.10 - */ -void -gimp_metadata_set_colorspace (GimpMetadata *metadata, - GimpMetadataColorspace colorspace) -{ - g_return_if_fail (IS_GIMP_METADATA (metadata)); - - gimp_metadata_remove_attribute (metadata, "Exif.Photo.ColorSpace"); - gimp_metadata_remove_attribute (metadata, "Xmp.exif.ColorSpace"); - gimp_metadata_remove_attribute (metadata, "Exif.Iop.InteroperabilityIndex"); - - switch (colorspace) + if (gexiv2_metadata_get_supports_iptc (src) && + gexiv2_metadata_get_supports_iptc (dest)) { - case GIMP_METADATA_COLORSPACE_UNSPECIFIED: - gimp_metadata_remove_attribute (metadata, "Exif.Nikon3.ColorSpace"); - gimp_metadata_remove_attribute (metadata, "Exif.Canon.ColorSpace"); - break; + gchar **iptc_data = gexiv2_metadata_get_iptc_tags (src); - case GIMP_METADATA_COLORSPACE_UNCALIBRATED: - gimp_metadata_new_attribute (metadata, "Exif.Photo.ColorSpace", "0xffff", TYPE_LONG); - gimp_metadata_new_attribute (metadata, "Xmp.exif.ColorSpace", "0xffff", TYPE_LONG); - break; + if (iptc_data) + { + for (i = 0; iptc_data[i] != NULL; i++) + { + value = gexiv2_metadata_get_tag_string (src, iptc_data[i]); + gexiv2_metadata_set_tag_string (dest, iptc_data[i], value); + g_free (value); + } - case GIMP_METADATA_COLORSPACE_SRGB: - gimp_metadata_new_attribute (metadata, "Exif.Photo.ColorSpace", "0x01", TYPE_LONG); - gimp_metadata_new_attribute (metadata, "Xmp.exif.ColorSpace", "0x01", TYPE_LONG); - gimp_metadata_new_attribute (metadata, "Exif.Iop.InteroperabilityIndex", "R98", TYPE_ASCII); - if (gimp_metadata_has_attribute (metadata, "Exif.Nikon3.ColorSpace")) - { - gimp_metadata_remove_attribute (metadata, "Exif.Nikon3.ColorSpace"); - gimp_metadata_new_attribute (metadata, "Exif.Nikon3.ColorSpace", "0x01", TYPE_LONG); + g_strfreev (iptc_data); } - if (gimp_metadata_has_attribute (metadata, "Exif.Canon.ColorSpace")) - { - gimp_metadata_remove_attribute (metadata, "Exif.Canon.ColorSpace"); - gimp_metadata_new_attribute (metadata, "Exif.Canon.ColorSpace", "0x01", TYPE_LONG); - } - break; - - case GIMP_METADATA_COLORSPACE_ADOBERGB: - gimp_metadata_new_attribute (metadata, "Exif.Photo.ColorSpace", "0x02", TYPE_LONG); - gimp_metadata_new_attribute (metadata, "Xmp.exif.ColorSpace", "0x02", TYPE_LONG); - gimp_metadata_new_attribute (metadata, "Exif.Iop.InteroperabilityIndex", "R03", TYPE_ASCII); - if (gimp_metadata_has_attribute (metadata, "Exif.Nikon3.ColorSpace")) - { - gimp_metadata_remove_attribute (metadata, "Exif.Nikon3.ColorSpace"); - gimp_metadata_new_attribute (metadata, "Exif.Nikon3.ColorSpace", "0x02", TYPE_LONG); - } - if (gimp_metadata_has_attribute (metadata, "Exif.Canon.ColorSpace")) - { - gimp_metadata_remove_attribute (metadata, "Exif.Canon.ColorSpace"); - gimp_metadata_new_attribute (metadata, "Exif.Canon.ColorSpace", "0x02", TYPE_LONG); - } - break; } } - -/** - * gimp_metadata_set_resolution: - * @metadata: A #GimpMetadata instance. - * @xres: The image's X Resolution, in ppi - * @yres: The image's Y Resolution, in ppi - * @unit: The image's unit - * - * Sets Exif.Image.XResolution, Exif.Image.YResolution and - * Exif.Image.ResolutionUnit @metadata. - * - * Since: GIMP 2.10 - */ -void -gimp_metadata_set_resolution (GimpMetadata *metadata, - gdouble xres, - gdouble yres, - GimpUnit unit) -{ - gchar buffer[64]; - gint exif_unit; - gint factor; - - g_return_if_fail (IS_GIMP_METADATA (metadata)); - - if (gimp_unit_is_metric (unit)) - { - xres /= 2.54; - yres /= 2.54; - - exif_unit = 3; - } - else - { - exif_unit = 2; - } - - for (factor = 1; factor <= 100 /* arbitrary */; factor++) - { - if (fabs (xres * factor - ROUND (xres * factor)) < 0.01 && - fabs (yres * factor - ROUND (yres * factor)) < 0.01) - break; - } - - g_snprintf (buffer, sizeof (buffer), "%d/%d", ROUND (xres * factor), factor); - gimp_metadata_new_attribute (metadata, "Exif.Image.XResolution", buffer, TYPE_RATIONAL); - - g_snprintf (buffer, sizeof (buffer), "%d/%d", ROUND (yres * factor), factor); - gimp_metadata_new_attribute (metadata, "Exif.Image.YResolution", buffer, TYPE_RATIONAL); - - g_snprintf (buffer, sizeof (buffer), "%d", exif_unit); - gimp_metadata_new_attribute (metadata, "Exif.Image.ResolutionUnit", buffer, TYPE_SHORT); -} - diff --git a/libgimpbase/gimpmetadata.h b/libgimpbase/gimpmetadata.h index cac1d8e2b2..3a6b27c17f 100644 --- a/libgimpbase/gimpmetadata.h +++ b/libgimpbase/gimpmetadata.h @@ -1,19 +1,29 @@ +/* LIBGIMPBASE - The GIMP Basic Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpmetadata.h + * Copyright (C) 2013 Hartmut Kuhse + * + * This library 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. + * + * This library 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 this library. If not, see + * . + */ -#ifndef __GIMPMETADATA_H__ -#define __GIMPMETADATA_H__ +#ifndef __GIMP_METADATA_H__ +#define __GIMP_METADATA_H__ G_BEGIN_DECLS -#include - -#define TYPE_GIMP_METADATA (gimp_metadata_get_type ()) -#define GIMP_METADATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_GIMP_METADATA, GimpMetadata)) -#define GIMP_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_GIMP_METADATA, GimpMetadataClass)) -#define IS_GIMP_METADATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_GIMP_METADATA)) -#define IS_GIMP_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_GIMP_METADATA)) -#define GIMP_METADATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_GIMP_METADATA, GimpMetadataClass)) -#define GIMP_METADATA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_GIMP_METADATA, GimpMetadataPrivate)) - typedef enum { GIMP_METADATA_LOAD_COMMENT = 1 << 0, @@ -42,73 +52,51 @@ typedef enum GIMP_METADATA_COLORSPACE_ADOBERGB } GimpMetadataColorspace; -GType gimp_metadata_get_type (void) G_GNUC_CONST; -GimpMetadata * gimp_metadata_new (void); -gint gimp_metadata_size (GimpMetadata *metadata); -GimpMetadata * gimp_metadata_duplicate (GimpMetadata *metadata); -GHashTable * gimp_metadata_get_table (GimpMetadata *metadata); -void gimp_metadata_add_attribute (GimpMetadata *metadata, - GimpAttribute *attribute); -GimpAttribute * gimp_metadata_get_attribute (GimpMetadata *metadata, - const gchar *name); -gboolean gimp_metadata_remove_attribute (GimpMetadata *metadata, - const gchar *name); -gboolean gimp_metadata_has_attribute (GimpMetadata *metadata, - const gchar *name); -gboolean gimp_metadata_new_attribute (GimpMetadata *metadata, - const gchar *name, - gchar *value, - GimpAttributeValueType type); -gchar * gimp_metadata_serialize (GimpMetadata *metadata); -GimpMetadata * gimp_metadata_deserialize (const gchar *xml); -void gimp_metadata_print (GimpMetadata *metadata); -const gchar * gimp_metadata_to_xmp_packet (GimpMetadata *metadata, - const gchar *mime_type); -gboolean gimp_metadata_has_tag_type (GimpMetadata *metadata, - GimpAttributeTagType tag_type); -GList * gimp_metadata_iter_init (GimpMetadata *metadata, - GList **iter); -gboolean gimp_metadata_iter_next (GimpMetadata *metadata, - GimpAttribute **attribute, - GList **prev); -gboolean gimp_metadata_save_to_file (GimpMetadata *metadata, - GFile *file, - GError **error); -GimpMetadata * gimp_metadata_load_from_file (GFile *file, - GError **error); -gboolean gimp_metadata_set_from_exif (GimpMetadata *metadata, - const guchar *exif_data, - gint exif_data_length, - GError **error); -gboolean gimp_metadata_set_from_xmp (GimpMetadata *metadata, - const guchar *xmp_data, - gint xmp_data_length, - GError **error); -gboolean gimp_metadata_is_tag_supported (const gchar *tag, - const gchar *mime_type); -GimpMetadataColorspace gimp_metadata_get_colorspace (GimpMetadata *metadata); -gboolean gimp_metadata_get_resolution (GimpMetadata *metadata, - gdouble *xres, - gdouble *yres, - GimpUnit *unit); -void gimp_metadata_set_resolution (GimpMetadata *metadata, - gdouble xres, - gdouble yres, - GimpUnit unit); -void gimp_metadata_set_bits_per_sample (GimpMetadata *metadata, - gint bits_per_sample); -void gimp_metadata_set_pixel_size (GimpMetadata *metadata, - gint width, - gint height); -void gimp_metadata_set_colorspace (GimpMetadata *metadata, - GimpMetadataColorspace colorspace); -//GimpMetadata * gimp_metadata_from_gexiv2metadata (GimpMetadata *metadata, -// GimpMetadata *gexivdata); -//void gimp_metadata_to_gexiv2metadata (GimpMetadata *metadata, -// GimpMetadata *gexivdata, -// const gchar *mime_type); +GimpMetadata * gimp_metadata_new (void); +GimpMetadata * gimp_metadata_duplicate (GimpMetadata *metadata); + +GimpMetadata * gimp_metadata_deserialize (const gchar *metadata_xml); +gchar * gimp_metadata_serialize (GimpMetadata *metadata); + +GimpMetadata * gimp_metadata_load_from_file (GFile *file, + GError **error); +gboolean gimp_metadata_save_to_file (GimpMetadata *metadata, + GFile *file, + GError **error); + +gboolean gimp_metadata_set_from_exif (GimpMetadata *metadata, + const guchar *exif_data, + gint exif_data_length, + GError **error); +gboolean gimp_metadata_set_from_xmp (GimpMetadata *metadata, + const guchar *xmp_data, + gint xmp_data_length, + GError **error); + +void gimp_metadata_set_pixel_size (GimpMetadata *metadata, + gint width, + gint height); +void gimp_metadata_set_bits_per_sample (GimpMetadata *metadata, + gint bits_per_sample); + +gboolean gimp_metadata_get_resolution (GimpMetadata *metadata, + gdouble *xres, + gdouble *yres, + GimpUnit *unit); +void gimp_metadata_set_resolution (GimpMetadata *metadata, + gdouble xres, + gdouble yres, + GimpUnit unit); + +GimpMetadataColorspace + gimp_metadata_get_colorspace (GimpMetadata *metadata); +void gimp_metadata_set_colorspace (GimpMetadata *metadata, + GimpMetadataColorspace colorspace); + +gboolean gimp_metadata_is_tag_supported (const gchar *tag, + const gchar *mime_type); G_END_DECLS -#endif +#endif /* __GIMP_METADATA_H__ */ diff --git a/libgimpbase/gimprational.c b/libgimpbase/gimprational.c deleted file mode 100644 index 93d67546bb..0000000000 --- a/libgimpbase/gimprational.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * gimprational.c - * - * Created on: 19.09.2014 - * Author: kuhse - */ - -#include - -#include "gimprational.h" - - -static gpointer rational_copy (gpointer data); -static gpointer srational_copy (gpointer data); - - -G_DEFINE_BOXED_TYPE (Rational, rational, - rational_copy, - rational_free) -G_DEFINE_BOXED_TYPE (SRational, srational, - srational_copy, - srational_free) - - -/** - * string_to_rational: - * - * @string: a #gchar array - * @rational: a pointer to a #Rational struct - * - * converts a string, representing one/more rational values into - * a #Rational struct. - * - * Since: 2.10 - */ -void -string_to_rational (gchar *string, Rational **rational) -{ - gchar **nom; - gchar **rats; - gint count; - gint i; - Rational *rval; - GArray *rational_array; - - rats = g_strsplit (string, " ", -1); - - count = 0; - while (rats[count]) - count++; - - rational_array = g_array_new (TRUE, TRUE, sizeof (RationalValue)); - - for (i = 0; i < count; i++) - { - RationalValue or; - - nom = g_strsplit (rats[i], "/", 2); - - if (nom[0] && nom[1]) - { - or.nom = (guint) atoi (nom [0]); - or.denom = (guint) atoi (nom [1]); - } - else - count--; - - rational_array = g_array_append_val (rational_array, or); - - g_strfreev (nom); - } - - g_strfreev (rats); - - rval = g_slice_new (Rational); - - rval->rational_array = rational_array; - rval->length = count; - - *rational = rval; -} - -/** - * rational_to_string: - * - * @rational : a pointer to a @Rational struct - * @nom : a pointer to a #gint array - * @denom : a pointer to a #gint array - * @length : a pointer to a #gint - * - * converts a @rational to nom/denum gchar arrays - * - * Since: 2.10 - */ -void -rational_to_int (Rational *rational, gint **nom, gint **denom, gint *length) -{ - gint i; - gint *_nom; - gint *_denom; - - g_return_if_fail (rational != NULL); - - _nom = g_new (gint, rational->length); - _denom = g_new (gint, rational->length); - - for (i = 0; i < rational->length; i++) - { - RationalValue one; - one = g_array_index(rational->rational_array, RationalValue, i); - _nom[i] = one.nom; - _denom[i] = one.denom; - } - - *nom = _nom; - *denom = _denom; - *length = rational->length; -} - -/** - * rational_copy: - * - * @data: a #gpointer to a #Rational structure - * - * copy part of the #Rational type - * - * Since: 2.10 - */ -static gpointer -rational_copy (gpointer data) -{ - struct _Rational *rational = (struct _Rational *) data; - struct _Rational *copy = g_slice_new (Rational); - gint i; - GArray *rlacp; - - if (!data) - return NULL; - - rlacp = g_array_new (TRUE, TRUE, sizeof (RationalValue)); - - for (i = 0; i < rational->length; i++) - { - RationalValue or; - RationalValue cor; - - or = g_array_index (rational->rational_array, RationalValue, i); - - cor.nom = or.nom; - cor.denom = or.denom; - - rlacp = g_array_append_val (rlacp, cor); - } - - copy->rational_array = rlacp; - copy->length = rational->length; - - return (gpointer) copy; -} - -/** - * rational_free: - * - * @data: a #gpointer to a #Rational structure - * - * free part of the #Rational type - * - * Since: 2.10 - */ -void -rational_free (gpointer data) -{ - struct _Rational *rational = (struct _Rational *) data; - - if (rational) - { - if (rational->rational_array) - g_array_free (rational->rational_array, TRUE); - rational->length = 0; - } -} - -/** - * string_to_srational: - * - * @string: a #gchar array - * @srational: a pointer to a #Rational struct - * - * converts a string, representing one/more srational values into - * a #SRational struct. - * - * Since: 2.10 - */ -void -string_to_srational (gchar *string, SRational **srational) -{ - gchar **nom; - gchar **srats; - gint count; - gint i; - SRational *srval; - GArray *srational_array; - - srats = g_strsplit (string, " ", -1); - - count = 0; - while (srats[count]) - count++; - - srational_array = g_array_new (TRUE, TRUE, sizeof (SRationalValue)); - - for (i = 0; i < count; i++) - { - SRationalValue or; - - nom = g_strsplit (srats[i], "/", 2); - - if (nom[0] && nom[1]) - { - or.nom = (gint) atoi (nom [0]); - or.denom = (guint) atoi (nom [1]); - } - else - count--; - - srational_array = g_array_append_val (srational_array, or); - - g_strfreev (nom); - } - - g_strfreev (srats); - - srval = g_slice_new (SRational); - - srval->srational_array = srational_array; - srval->length = count; - - *srational = srval; -} -/** - * srational_copy: - * - * @data: a #gpointer to a #SRational structure - * - * copy part of the #SRational type - * - * Since: 2.10 - */ -static gpointer -srational_copy (gpointer data) -{ - struct _SRational *srational = (struct _SRational *) data; - struct _SRational *copy = g_slice_new (SRational); - gint i; - GArray *rlacp; - - if (!data) - return NULL; - - rlacp = g_array_new (TRUE, TRUE, sizeof (SRationalValue)); - - for (i = 0; i < srational->length; i++) - { - SRationalValue or; - SRationalValue cor; - - or = g_array_index (srational->srational_array, SRationalValue, i); - - cor.nom = or.nom; - cor.denom = or.denom; - - rlacp = g_array_append_val (rlacp, cor); - } - - copy->srational_array = rlacp; - copy->length = srational->length; - - return (gpointer) copy; -} - -/** - * srational_free: - * - * @data: a #gpointer to a #SRational structure - * - * free part of the #SRational type - * - * Since: 2.10 - */ -void -srational_free (gpointer data) -{ - struct _SRational *srational = (struct _SRational *) data; - - if (srational) - { - if (srational->srational_array) - g_array_free (srational->srational_array, TRUE); - srational->length = 0; - } -} diff --git a/libgimpbase/gimprational.h b/libgimpbase/gimprational.h deleted file mode 100644 index ab020c89d3..0000000000 --- a/libgimpbase/gimprational.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * gimprational.h - * - * Created on: 19.09.2014 - * Author: kuhse - */ - -#ifndef __GIMPRATIONAL_H__ -#define __GIMPRATIONAL_H__ - -#include - -G_BEGIN_DECLS - -#define GIMP_TYPE_RATIONAL (rational_get_type ()) -#define GIMP_TYPE_SRATIONAL (srational_get_type ()) - -typedef struct _RationalValue RationalValue; - -struct _RationalValue -{ - guint nom; - guint denom; -}; - -typedef struct _SRationalValue SRationalValue; - -struct _SRationalValue -{ - gint nom; - guint denom; -}; - -typedef struct _Rational Rational; - -struct _Rational -{ - GArray *rational_array; - gint length; -}; - -typedef struct _SRational SRational; - -struct _SRational -{ - GArray *srational_array; - gint length; -}; - -GType rational_get_type (void) G_GNUC_CONST; -GType srational_get_type (void) G_GNUC_CONST; - -void rational_free (gpointer data); -void srational_free (gpointer data); - -void string_to_rational (gchar *string, - Rational **rational); -void rational_to_int (Rational *rational, - gint **nom, - gint **denom, - gint *length); -void string_to_srational (gchar *string, - SRational **srational); - - -G_END_DECLS - -#endif /* __GIMPRATIONAL_H__ */ diff --git a/libgimpwidgets/gimpicons.c b/libgimpwidgets/gimpicons.c index 2ddd6ed1c1..0bec46e149 100644 --- a/libgimpwidgets/gimpicons.c +++ b/libgimpwidgets/gimpicons.c @@ -166,7 +166,6 @@ static const GtkStockItem gimp_stock_items[] = { GIMP_STOCK_TOOL_PRESET, NULL, 0, 0, LIBGIMP_DOMAIN }, { GIMP_STOCK_IMAGE, NULL, 0, 0, LIBGIMP_DOMAIN }, - { GIMP_STOCK_IMAGE_METADATA, NULL, 0, 0, LIBGIMP_DOMAIN }, { GIMP_STOCK_LAYER, NULL, 0, 0, LIBGIMP_DOMAIN }, { GIMP_STOCK_TEXT_LAYER, NULL, 0, 0, LIBGIMP_DOMAIN }, { GIMP_STOCK_FLOATING_SELECTION, NULL, 0, 0, LIBGIMP_DOMAIN }, diff --git a/libgimpwidgets/gimpicons.h b/libgimpwidgets/gimpicons.h index 66f423ac76..4d82e5c77e 100644 --- a/libgimpwidgets/gimpicons.h +++ b/libgimpwidgets/gimpicons.h @@ -182,7 +182,6 @@ G_BEGIN_DECLS #define GIMP_STOCK_FLIP_VERTICAL "gimp-flip-vertical" #define GIMP_STOCK_IMAGE "gimp-image" -#define GIMP_STOCK_IMAGE_METADATA "gimp-image-metadata" #define GIMP_STOCK_LAYER "gimp-layer" #define GIMP_STOCK_TEXT_LAYER "gimp-text-layer" #define GIMP_STOCK_FLOATING_SELECTION "gimp-floating-selection" diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am index 57f1f3f295..90b048b3b1 100644 --- a/plug-ins/common/Makefile.am +++ b/plug-ins/common/Makefile.am @@ -52,7 +52,6 @@ libexec_PROGRAMS = \ align-layers \ animation-optimize \ animation-play \ - attributes \ blinds \ blur \ border-average \ @@ -117,10 +116,10 @@ libexec_PROGRAMS = \ grid \ guillotine \ hot \ - iptc \ jigsaw \ $(MAIL) \ max-rgb \ + metadata \ newsprint \ nl-filter \ oilify \ @@ -219,24 +218,6 @@ animation_play_LDADD = \ $(INTLLIBS) \ $(animation_play_RC) -attributes_SOURCES = \ - attributes.c - -attributes_LDADD = \ - $(libgimpui) \ - $(libgimpwidgets) \ - $(libgimpmodule) \ - $(libgimp) \ - $(libgimpmath) \ - $(libgimpconfig) \ - $(libgimpcolor) \ - $(libgimpbase) \ - $(GTK_LIBS) \ - $(GEGL_LIBS) \ - $(RT_LIBS) \ - $(INTLLIBS) \ - $(attributes_RC) - blinds_SOURCES = \ blinds.c @@ -1373,26 +1354,6 @@ hot_LDADD = \ $(INTLLIBS) \ $(hot_RC) -iptc_CFLAGS = $(GEXIV2_CFLAGS) - -iptc_SOURCES = \ - iptc.c - -iptc_LDADD = \ - $(libgimpui) \ - $(libgimpwidgets) \ - $(libgimpmodule) \ - $(libgimp) \ - $(libgimpmath) \ - $(libgimpconfig) \ - $(libgimpcolor) \ - $(libgimpbase) \ - $(GTK_LIBS) \ - $(GEXIV2_LIBS) \ - $(RT_LIBS) \ - $(INTLLIBS) \ - $(iptc_RC) - jigsaw_SOURCES = \ jigsaw.c @@ -1444,6 +1405,26 @@ max_rgb_LDADD = \ $(INTLLIBS) \ $(max_rgb_RC) +metadata_CFLAGS = $(GEXIV2_CFLAGS) + +metadata_SOURCES = \ + metadata.c + +metadata_LDADD = \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpmodule) \ + $(libgimp) \ + $(libgimpmath) \ + $(libgimpconfig) \ + $(libgimpcolor) \ + $(libgimpbase) \ + $(GTK_LIBS) \ + $(GEXIV2_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(metadata_RC) + newsprint_SOURCES = \ newsprint.c diff --git a/plug-ins/common/file-jp2-load.c b/plug-ins/common/file-jp2-load.c index 280361779e..0facb3c2e7 100644 --- a/plug-ins/common/file-jp2-load.c +++ b/plug-ins/common/file-jp2-load.c @@ -57,7 +57,6 @@ static void run (const gchar *name, gint *nreturn_vals, GimpParam **return_vals); static gint32 load_image (const gchar *filename, - gint32 *layer_ID, GError **error); static gboolean load_icc_profile (jas_image_t *jas_image, gint image_ID, @@ -127,7 +126,6 @@ run (const gchar *name, GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint image_ID; GError *error = NULL; - gint32 layer_ID; run_mode = param[0].data.d_int32; @@ -156,7 +154,7 @@ run (const gchar *name, break; } - image_ID = load_image (param[1].data.d_string, &layer_ID, &error); + image_ID = load_image (param[1].data.d_string, &error); if (image_ID != -1) { @@ -170,7 +168,7 @@ run (const gchar *name, { GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL; - gimp_image_metadata_load_finish (image_ID, layer_ID, "image/jp2", + gimp_image_metadata_load_finish (image_ID, "image/jp2", metadata, flags, interactive); @@ -205,13 +203,13 @@ run (const gchar *name, static gint32 load_image (const gchar *filename, - gint32 *layer_ID, GError **error) { gint fd; jas_stream_t *stream; gint32 image_ID = -1; jas_image_t *image; + gint32 layer_ID; GimpImageType image_type; GimpImageBaseType base_type; gint width; diff --git a/plug-ins/common/file-png.c b/plug-ins/common/file-png.c index 12c9030044..6efb7f1450 100644 --- a/plug-ins/common/file-png.c +++ b/plug-ins/common/file-png.c @@ -140,7 +140,6 @@ static void run (const gchar *name, GimpParam **return_vals); static gint32 load_image (const gchar *filename, - gint32 *layer_ID, gboolean interactive, gboolean *resolution_loaded, GError **error); @@ -148,7 +147,6 @@ static gboolean save_image (const gchar *filename, gint32 image_ID, gint32 drawable_ID, gint32 orig_image_ID, - gint *bits_depth, GError **error); static int respin_cmap (png_structp pp, @@ -418,7 +416,6 @@ run (const gchar *name, GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint32 image_ID; - gint32 layer_ID; gint32 drawable_ID; GError *error = NULL; @@ -451,7 +448,6 @@ run (const gchar *name, } image_ID = load_image (param[1].data.d_string, - &layer_ID, interactive, &resolution_loaded, &error); @@ -471,7 +467,7 @@ run (const gchar *name, if (resolution_loaded) flags &= ~GIMP_METADATA_LOAD_RESOLUTION; - gimp_image_metadata_load_finish (image_ID, layer_ID, "image/png", + gimp_image_metadata_load_finish (image_ID, "image/png", metadata, flags, interactive); @@ -496,7 +492,6 @@ run (const gchar *name, GimpMetadata *metadata; GimpMetadataSaveFlags metadata_flags; gint32 orig_image_ID; - gint bits_depth; GimpExportReturn export = GIMP_EXPORT_CANCEL; gboolean alpha; @@ -530,8 +525,8 @@ run (const gchar *name, } metadata = gimp_image_metadata_save_prepare (orig_image_ID, - "image/png", - &metadata_flags); + "image/png", + &metadata_flags); pngvals.save_exif = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0; pngvals.save_xmp = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0; @@ -613,7 +608,7 @@ run (const gchar *name, if (status == GIMP_PDB_SUCCESS) { if (save_image (param[3].data.d_string, - image_ID, drawable_ID, orig_image_ID, &bits_depth, &error)) + image_ID, drawable_ID, orig_image_ID, &error)) { if (metadata) { @@ -642,12 +637,10 @@ run (const gchar *name, metadata_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL; file = g_file_new_for_path (param[3].data.d_string); - gimp_image_metadata_save_finish (orig_image_ID, "image/png", metadata, metadata_flags, file, NULL); - g_object_unref (metadata); g_object_unref (file); } @@ -662,6 +655,8 @@ run (const gchar *name, if (export == GIMP_EXPORT_EXPORT) gimp_image_delete (image_ID); + if (metadata) + g_object_unref (metadata); } else if (strcmp (name, GET_DEFAULTS_PROC) == 0) { @@ -822,7 +817,6 @@ load_color_profile (png_structp pp, */ static gint32 load_image (const gchar *filename, - gint32 *layer_ID, gboolean interactive, gboolean *resolution_loaded, GError **error) @@ -1356,8 +1350,6 @@ load_image (const gchar *filename, g_object_unref (buffer); } - *layer_ID = layer; - return image; } @@ -1435,7 +1427,6 @@ save_image (const gchar *filename, gint32 image_ID, gint32 drawable_ID, gint32 orig_image_ID, - gint *bits_depth, GError **error) { gint i, k; /* Looping vars */ @@ -1509,8 +1500,6 @@ save_image (const gchar *filename, break; } - *bits_depth = bit_depth; - pp = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pp) { diff --git a/plug-ins/common/gimprc.common b/plug-ins/common/gimprc.common index a8e640677d..0ff328dbe8 100644 --- a/plug-ins/common/gimprc.common +++ b/plug-ins/common/gimprc.common @@ -1,7 +1,6 @@ align_layers_RC = align-layers.rc.o animation_optimize_RC = animation-optimize.rc.o animation_play_RC = animation-play.rc.o -attributes_RC = attributes.rc.o blinds_RC = blinds.rc.o blur_RC = blur.rc.o border_average_RC = border-average.rc.o @@ -66,10 +65,10 @@ gradient_map_RC = gradient-map.rc.o grid_RC = grid.rc.o guillotine_RC = guillotine.rc.o hot_RC = hot.rc.o -iptc_RC = iptc.rc.o jigsaw_RC = jigsaw.rc.o mail_RC = mail.rc.o max_rgb_RC = max-rgb.rc.o +metadata_RC = metadata.rc.o newsprint_RC = newsprint.rc.o nl_filter_RC = nl-filter.rc.o oilify_RC = oilify.rc.o diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl index 4c7951749d..324e7da565 100644 --- a/plug-ins/common/plugin-defs.pl +++ b/plug-ins/common/plugin-defs.pl @@ -2,7 +2,6 @@ 'align-layers' => { ui => 1 }, 'animation-optimize' => {}, 'animation-play' => { ui => 1, gegl => 1 }, - 'attributes' => { ui => 1, gegl => 1 }, 'blinds' => { ui => 1 }, 'blur' => {}, 'border-average' => { ui => 1, gegl => 1 }, @@ -67,10 +66,10 @@ 'grid' => { ui => 1 }, 'guillotine' => {}, 'hot' => { ui => 1 }, - 'iptc' => { ui => 1, libs => 'GEXIV2_LIBS', cflags => 'GEXIV2_CFLAGS' }, 'jigsaw' => { ui => 1 }, 'mail' => { ui => 1, optional => 1 }, 'max-rgb' => { ui => 1 }, + 'metadata' => { ui => 1, libs => 'GEXIV2_LIBS', cflags => 'GEXIV2_CFLAGS' }, 'newsprint' => { ui => 1 }, 'nl-filter' => { ui => 1 }, 'oilify' => { ui => 1 }, diff --git a/plug-ins/file-jpeg/jpeg-load.c b/plug-ins/file-jpeg/jpeg-load.c index ed1ac6b2ca..6cc945f14d 100644 --- a/plug-ins/file-jpeg/jpeg-load.c +++ b/plug-ins/file-jpeg/jpeg-load.c @@ -58,13 +58,12 @@ gint32 preview_layer_ID; gint32 load_image (const gchar *filename, GimpRunMode runmode, - gint32 *layer_ID, gboolean preview, gboolean *resolution_loaded, GError **error) { gint32 volatile image_ID; - gint32 _layer_ID; + gint32 layer_ID; struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; jpeg_saved_marker_ptr marker; @@ -233,11 +232,11 @@ load_image (const gchar *filename, cinfo.output_width, cinfo.output_height, layer_type, 100, GIMP_NORMAL_MODE); - _layer_ID = preview_layer_ID; + layer_ID = preview_layer_ID; } else { - _layer_ID = gimp_layer_new (image_ID, _("Background"), + layer_ID = gimp_layer_new (image_ID, _("Background"), cinfo.output_width, cinfo.output_height, layer_type, 100, GIMP_NORMAL_MODE); @@ -344,7 +343,7 @@ load_image (const gchar *filename, * loop counter, so that we don't have to keep track ourselves. */ - buffer = gimp_drawable_get_buffer (_layer_ID); + buffer = gimp_drawable_get_buffer (layer_ID); format = babl_format (image_type == GIMP_RGB ? "R'G'B' u8" : "Y' u8"); while (cinfo.output_scanline < cinfo.output_height) @@ -413,9 +412,7 @@ load_image (const gchar *filename, gimp_progress_update (1.0); } - gimp_image_insert_layer (image_ID, _layer_ID, -1, 0); - - *layer_ID = _layer_ID; + gimp_image_insert_layer (image_ID, layer_ID, -1, 0); return image_ID; } diff --git a/plug-ins/file-jpeg/jpeg-load.h b/plug-ins/file-jpeg/jpeg-load.h index 281e03dc26..d4e61b04ad 100644 --- a/plug-ins/file-jpeg/jpeg-load.h +++ b/plug-ins/file-jpeg/jpeg-load.h @@ -20,7 +20,6 @@ gint32 load_image (const gchar *filename, GimpRunMode runmode, - gint32 *layer_ID, gboolean preview, gboolean *resolution_loaded, GError **error); diff --git a/plug-ins/file-jpeg/jpeg-save.c b/plug-ins/file-jpeg/jpeg-save.c index e01cef6016..c38ff5c128 100644 --- a/plug-ins/file-jpeg/jpeg-save.c +++ b/plug-ins/file-jpeg/jpeg-save.c @@ -188,7 +188,6 @@ background_jpeg_save (PreviewPersistent *pp) GFile *file = g_file_new_for_path (pp->file_name); GFileInfo *info; gchar *text; - gint32 layer_ID; GError *error = NULL; info = g_file_query_info (file, @@ -219,7 +218,7 @@ background_jpeg_save (PreviewPersistent *pp) g_object_unref (file); /* and load the preview */ - load_image (pp->file_name, GIMP_RUN_NONINTERACTIVE, &layer_ID, TRUE, NULL, NULL); + load_image (pp->file_name, GIMP_RUN_NONINTERACTIVE, TRUE, NULL, NULL); } /* we cleanup here (load_image doesn't run in the background) */ diff --git a/plug-ins/file-jpeg/jpeg.c b/plug-ins/file-jpeg/jpeg.c index 298d1e303c..580834803b 100644 --- a/plug-ins/file-jpeg/jpeg.c +++ b/plug-ins/file-jpeg/jpeg.c @@ -173,7 +173,6 @@ run (const gchar *name, GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint32 image_ID; - gint32 layer_ID; gint32 drawable_ID; GimpParasite *parasite; GError *error = NULL; @@ -211,7 +210,7 @@ run (const gchar *name, break; } - image_ID = load_image (param[1].data.d_string, run_mode, &layer_ID, FALSE, + image_ID = load_image (param[1].data.d_string, run_mode, FALSE, &resolution_loaded, &error); if (image_ID != -1) @@ -224,12 +223,12 @@ run (const gchar *name, if (metadata) { - GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL; + GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL; if (resolution_loaded) flags &= ~GIMP_METADATA_LOAD_RESOLUTION; - gimp_image_metadata_load_finish (image_ID, layer_ID, "image/jpeg", + gimp_image_metadata_load_finish (image_ID, "image/jpeg", metadata, flags, load_interactive); @@ -575,6 +574,7 @@ run (const gchar *name, g_object_unref (file); } } + if (metadata) g_object_unref (metadata); } diff --git a/plug-ins/file-psd/psd.c b/plug-ins/file-psd/psd.c index f8cb84fcb1..0a52c0053a 100644 --- a/plug-ins/file-psd/psd.c +++ b/plug-ins/file-psd/psd.c @@ -211,7 +211,7 @@ run (const gchar *name, if (resolution_loaded) flags &= ~GIMP_METADATA_LOAD_RESOLUTION; - gimp_image_metadata_load_finish (image_ID, -1, "image/x-psd", + gimp_image_metadata_load_finish (image_ID, "image/x-psd", metadata, flags, interactive); @@ -315,8 +315,6 @@ run (const gchar *name, metadata, metadata_flags, file, NULL); g_object_unref (file); - - g_object_unref (metadata); } values[0].data.d_status = GIMP_PDB_SUCCESS; @@ -336,6 +334,8 @@ run (const gchar *name, if (export == GIMP_EXPORT_EXPORT) gimp_image_delete (image_ID); + if (metadata) + g_object_unref (metadata); } /* Unknown procedure */ diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c index 34a2b59908..fe83b94426 100644 --- a/plug-ins/file-tiff/file-tiff-load.c +++ b/plug-ins/file-tiff/file-tiff-load.c @@ -219,7 +219,6 @@ load_dialog (TIFF *tif, gint32 load_image (GFile *file, - gint32 *layer_ID, TIFF *tif, TiffSelectedPages *pages, gboolean *resolution_loaded, @@ -930,8 +929,6 @@ load_image (GFile *file, g_free (name); } - *layer_ID = layer; - if (! base_format && image_type == GIMP_INDEXED) { /* can't create the palette format here, need to get it from diff --git a/plug-ins/file-tiff/file-tiff-load.h b/plug-ins/file-tiff/file-tiff-load.h index 569503912f..372af71f53 100644 --- a/plug-ins/file-tiff/file-tiff-load.h +++ b/plug-ins/file-tiff/file-tiff-load.h @@ -37,7 +37,6 @@ gboolean load_dialog (TIFF *tif, TiffSelectedPages *pages); gint32 load_image (GFile *file, - gint32 *layer_ID, TIFF *tif, TiffSelectedPages *pages, gboolean *resolution_loaded, diff --git a/plug-ins/file-tiff/file-tiff.c b/plug-ins/file-tiff/file-tiff.c index d5dd476f50..aa57870b1e 100644 --- a/plug-ins/file-tiff/file-tiff.c +++ b/plug-ins/file-tiff/file-tiff.c @@ -264,14 +264,13 @@ run (const gchar *name, if (run_it) { - gint32 image; - gint32 layer_ID; - gboolean resolution_loaded = FALSE; + gint32 image; + gboolean resolution_loaded = FALSE; gimp_set_data (LOAD_PROC, &pages.target, sizeof (pages.target)); - image = load_image (file, &layer_ID, tif, &pages, + image = load_image (file, tif, &pages, &resolution_loaded, &error); @@ -292,7 +291,7 @@ run (const gchar *name, if (resolution_loaded) flags &= ~GIMP_METADATA_LOAD_RESOLUTION; - gimp_image_metadata_load_finish (image, layer_ID, "image/tiff", + gimp_image_metadata_load_finish (image, "image/tiff", metadata, flags, run_mode == GIMP_RUN_INTERACTIVE); @@ -472,9 +471,9 @@ run (const gchar *name, * exiv2 saves them with wrong type and the original values * could be invalid, see also bug 761823 */ - gimp_metadata_remove_attribute (metadata, "Exif.Image.0x0118"); - gimp_metadata_remove_attribute (metadata, "Exif.Image.0x0119"); - gimp_metadata_remove_attribute (metadata, "Exif.Image.PageNumber"); + gexiv2_metadata_clear_tag (metadata, "Exif.Image.0x0118"); + gexiv2_metadata_clear_tag (metadata, "Exif.Image.0x0119"); + gexiv2_metadata_clear_tag (metadata, "Exif.Image.PageNumber"); gimp_metadata_set_bits_per_sample (metadata, saved_bpp); @@ -500,7 +499,6 @@ run (const gchar *name, "image/tiff", metadata, metadata_flags, file, NULL); - g_object_unref (metadata); } /* Store mvals data */ @@ -517,6 +515,8 @@ run (const gchar *name, if (export == GIMP_EXPORT_EXPORT) gimp_image_delete (image); + if (metadata) + g_object_unref (metadata); } else { diff --git a/plug-ins/ui/Makefile.am b/plug-ins/ui/Makefile.am index 16de1dbba5..1b569f8930 100644 --- a/plug-ins/ui/Makefile.am +++ b/plug-ins/ui/Makefile.am @@ -5,8 +5,6 @@ uidata_DATA = \ plug-in-file-png.ui \ plug-in-file-raw.ui \ plug-in-file-tiff.ui \ - plug-in-attributes.ui \ - plug-in-iptc.ui - + plug-in-metadata.ui EXTRA_DIST = $(uidata_DATA) diff --git a/plug-ins/ui/plug-in-metadata.ui b/plug-ins/ui/plug-in-metadata.ui new file mode 100644 index 0000000000..1e34d8d3be --- /dev/null +++ b/plug-ins/ui/plug-in-metadata.ui @@ -0,0 +1,908 @@ + + + + + + + + + + + + + + + + + + + + + True + False + + + True + True + True + + + True + True + 6 + in + + + True + True + exif-liststore + False + 0 + + + + + + True + 3 + Exif Tag + + + + 0 + + + + + + + True + 3 + Value + + + + 1 + + + + + + + + + + + True + False + 4 + 4 + Exif + + + True + False + + + + + True + True + 6 + in + + + True + True + xmp-liststore + False + 0 + + + + + + True + 3 + XMP Tag + + + + 0 + + + + + + + True + 3 + Value + + + + 1 + + + + + + + + + 1 + + + + + True + False + 4 + 4 + XMP + + + 1 + False + + + + + True + False + 6 + 6 + + + True + True + + + True + False + + + True + False + 6 + 8 + 2 + 3 + 3 + + + True + False + 0 + 3 + 3 + Title + True + + + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 3 + 3 + Author + + + 1 + 2 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 3 + 3 + Authortitle + + + 2 + 3 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 3 + 3 + Copyright + + + 3 + 4 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 0 + 3 + 3 + Caption + + + 4 + 5 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 3 + 3 + Captionwriter + + + 5 + 6 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 0 + 3 + 3 + Headline + + + 6 + 7 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 0 + 3 + 3 + Special +Instructions + + + 7 + 8 + GTK_SHRINK | GTK_FILL + + + + + True + True + + True + + + 1 + 2 + + + + + True + True + + True + + + 1 + 2 + 1 + 2 + + + + + True + True + + True + + + 1 + 2 + 2 + 3 + + + + + True + True + + True + + + 1 + 2 + 3 + 4 + + + + + True + True + + True + + + 1 + 2 + 5 + 6 + + + + + True + True + in + + + True + True + + + + + 1 + 2 + 4 + 5 + + + + + True + True + in + + + True + True + + + + + 1 + 2 + 6 + 7 + + + + + True + True + in + + + True + True + + + + + 1 + 2 + 7 + 8 + + + + + False + True + 0 + + + + + + + True + False + 2 + 2 + Description + + + False + + + + + True + False + + + True + False + 6 + 4 + 2 + 3 + 3 + + + True + False + 0 + 0 + 3 + 3 + Keywords + + + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 3 + 3 + Category + + + 1 + 2 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 0 + 3 + 3 + Supplemental +Category + + + 2 + 3 + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 3 + 3 + Urgency + + + 3 + 4 + GTK_SHRINK | GTK_FILL + + + + + True + True + in + + + True + True + + + + + 1 + 2 + + + + + True + True + in + + + True + True + + + + + 1 + 2 + 2 + 3 + + + + + True + True + + True + + + 1 + 2 + 3 + 4 + + + + + True + True + + True + + + 1 + 2 + 1 + 2 + + + + + False + True + 0 + + + + + 1 + + + + + True + False + 2 + 2 + Keywords/Categories + + + 1 + False + + + + + True + False + + + True + False + 6 + 9 + 2 + 3 + 3 + + + True + False + + + 2 + 2 + 3 + + + + + True + False + 0 + 3 + 3 + Credit + + + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + 3 + 3 + Source + + + 1 + 2 + GTK_SHRINK | GTK_FILL + + + + + True + True + + True + + + 1 + 2 + + + + + True + True + + True + + + 1 + 2 + 1 + 2 + + + + + True + False + 0 + 3 + 3 + Transmission +reference + + + 8 + 9 + GTK_SHRINK | GTK_FILL + + + + + True + True + + True + + + 1 + 2 + 8 + 9 + + + + + True + False + 0 + 3 + 3 + City + + + 3 + 4 + GTK_SHRINK | GTK_FILL + + + + + True + True + + True + + + 1 + 2 + 3 + 4 + + + + + True + False + 0 + 3 + 3 + Sublocation + + + 4 + 5 + GTK_SHRINK | GTK_FILL + + + + + True + True + + True + + + 1 + 2 + 4 + 5 + + + + + True + False + 0 + 3 + 3 + Province/State + + + 5 + 6 + GTK_SHRINK | GTK_FILL + + + + + True + True + + True + + + 1 + 2 + 5 + 6 + + + + + True + False + 0 + Country + + + 6 + 7 + GTK_SHRINK | GTK_FILL + + + + + True + True + + True + + + 1 + 2 + 6 + 7 + + + + + True + False + + + 2 + 7 + 8 + + + + + False + True + 0 + + + + + 2 + + + + + True + False + 2 + 2 + Credits/Origin + + + 2 + False + + + + + False + True + 0 + + + + + Write IPTC Data + True + True + True + + + False + True + 1 + + + + + 2 + + + + + True + False + 4 + 4 + IPTC + + + 2 + False + + + + + True + True + 0 + + + + diff --git a/po-plug-ins/POTFILES.in b/po-plug-ins/POTFILES.in index 10c4437ee9..2d3c511c05 100644 --- a/po-plug-ins/POTFILES.in +++ b/po-plug-ins/POTFILES.in @@ -6,7 +6,6 @@ plug-ins/common/align-layers.c plug-ins/common/animation-optimize.c plug-ins/common/animation-play.c -plug-ins/common/attributes.c plug-ins/common/blinds.c plug-ins/common/blur.c plug-ins/common/border-average.c @@ -74,6 +73,7 @@ plug-ins/common/hot.c plug-ins/common/jigsaw.c plug-ins/common/mail.c plug-ins/common/max-rgb.c +plug-ins/common/metadata.c plug-ins/common/newsprint.c plug-ins/common/nl-filter.c plug-ins/common/oilify.c @@ -159,8 +159,7 @@ plug-ins/gimpressionist/utils.c [type: gettext/glade]plug-ins/ui/plug-in-file-png.ui [type: gettext/glade]plug-ins/ui/plug-in-file-raw.ui [type: gettext/glade]plug-ins/ui/plug-in-file-tiff.ui -[type: gettext/glade]plug-ins/ui/plug-in-metainfo.ui -[type: gettext/glade]plug-ins/ui/plug-in-attributes.ui +[type: gettext/glade]plug-ins/ui/plug-in-metadata.ui plug-ins/gradient-flare/gradient-flare.c plug-ins/help-browser/dialog.c plug-ins/help-browser/help-browser.c @@ -218,11 +217,6 @@ plug-ins/lighting/lighting-ui.c plug-ins/map-object/map-object-apply.c plug-ins/map-object/map-object-main.c plug-ins/map-object/map-object-ui.c -plug-ins/metainfo/interface.c -plug-ins/metainfo/page-administration.c -plug-ins/metainfo/page-rights.c -plug-ins/metainfo/page-description.c -plug-ins/metainfo/page-artwork.c plug-ins/pagecurl/pagecurl.c plug-ins/print/print-draw-page.c plug-ins/print/print-page-layout.c diff --git a/tools/pdbgen/pdb/item.pdb b/tools/pdbgen/pdb/item.pdb index 2aff3cff7d..b6f5ff99f8 100644 --- a/tools/pdbgen/pdb/item.pdb +++ b/tools/pdbgen/pdb/item.pdb @@ -783,61 +783,6 @@ CODE ); } -sub item_get_metadata { - $blurb = "Returns the item's metadata."; - $help = 'Returns metadata from the item.'; - - &std_pdb_misc('2016', '2.10'); - - @inargs = ( - { name => 'item', type => 'item', - desc => 'The item' } - ); - - @outargs = ( - { name => 'metadata_string', type => 'string', wrap => 1, - desc => 'The metadata as a xml string'} - ); - - %invoke = ( - code => <<'CODE' -{ - GimpMetadata *metadata = gimp_item_get_metadata (item); - - if (metadata) - metadata_string = gimp_metadata_serialize (metadata); -} -CODE - ); -} - -sub item_set_metadata { - $blurb = "Set the item's metadata."; - $help = 'Sets metadata on the item.'; - - &std_pdb_misc('2016', '2.10'); - - @inargs = ( - { name => 'item', type => 'item', - desc => 'The item' }, - { name => 'metadata_string', type => 'string', wrap => 1, - desc => 'The metadata as a xml string' } - ); - - %invoke = ( - code => <<'CODE' -{ - GimpMetadata *metadata = gimp_metadata_deserialize (metadata_string); - - gimp_item_set_metadata (item, metadata, TRUE); - - if (metadata) - g_object_unref (metadata); -} -CODE - ); -} - sub item_attach_parasite { $blurb = 'Add a parasite to an item.'; @@ -951,12 +896,10 @@ CODE } @headers = qw("core/gimplayermask.h" - "libgimpbase/gimpbase.h" "core/gimplist.h" "core/gimpselection.h" - "core/gimpitem.h" "text/gimptextlayer.h" - "vectors/gimpvectors.h" + "vectors/gimpvectors.h" "gimppdb-utils.h" "gimppdbcontext.h" "gimp-intl.h"); @@ -967,13 +910,13 @@ CODE item_is_drawable item_is_layer item_is_text_layer - item_is_channel - item_is_layer_mask - item_is_selection - item_is_vectors - item_is_group + item_is_channel + item_is_layer_mask + item_is_selection + item_is_vectors + item_is_group item_get_parent - item_get_children + item_get_children item_get_name item_set_name item_get_visible item_set_visible item_get_linked item_set_linked @@ -981,10 +924,9 @@ CODE item_get_lock_position item_set_lock_position item_get_color_tag item_set_color_tag item_get_tattoo item_set_tattoo - item_get_metadata item_set_metadata - item_attach_parasite item_detach_parasite - item_get_parasite - item_get_parasite_list); + item_attach_parasite item_detach_parasite + item_get_parasite + item_get_parasite_list); %exports = (app => [@procs], lib => [@procs]);