Commit 21bed1e2 authored by Hartmut Kuhse's avatar Hartmut Kuhse Committed by Michael Natterer

Completely rewrite metadata handling using gexiv2

Based on original patches from Hartmut Kuhse and modified
by Michael Natterer. Changes include:

- remove libexif dependency and add a hard dependency on gexiv2
- typedef GExiv2Metadata to GimpMetadata to avoid having to
  include gexiv2 globally
- add basic GimpMetadata handling functions to libgimpbase
- add image and image file specific metadata functions to libgimp,
  including the exif orientation image rotate dialog
- port plug-ins to use the new APIs
- port file-tiff-save's UI to GtkBuilder
- add new plug-in "metadata" to view the image's metadata
- keep metadata around as GimpImage member in the core
- update the image's metadata on image size, resolution and precision
  changes
- obsolete the old metadata parasites
- migrate the old parasites to new GimpMetadata object on XCF load
parent c51ce66f
......@@ -177,6 +177,7 @@ gimpconsoleldadd = \
$(CAIRO_LIBS) \
$(GEGL_LIBS) \
$(GLIB_LIBS) \
$(GEXIV2_LIBS) \
$(INTLLIBS) \
$(RT_LIBS)
......
......@@ -110,7 +110,8 @@ test_config_LDADD = \
$(PANGOCAIRO_LIBS) \
$(GDK_PIXBUF_LIBS) \
$(GEGL_LIBS) \
$(GLIB_LIBS)
$(GIO_LIBS) \
$(GEXIV2_LIBS)
CLEANFILES = $(EXTRA_PROGRAMS) foorc
......
......@@ -23,7 +23,7 @@
#include "stdlib.h"
#include "string.h"
#include <glib-object.h>
#include <gio/gio.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpbase/gimpbase-private.h"
......
......@@ -10,6 +10,7 @@ AM_CPPFLAGS = \
$(CAIRO_CFLAGS) \
$(GEGL_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
$(GEXIV2_CFLAGS) \
-I$(includedir)
noinst_LIBRARIES = libappcore.a
......@@ -219,6 +220,8 @@ libappcore_a_sources = \
gimpimage-item-list.h \
gimpimage-merge.c \
gimpimage-merge.h \
gimpimage-metadata.c \
gimpimage-metadata.h \
gimpimage-new.c \
gimpimage-new.h \
gimpimage-pick-color.c \
......
......@@ -1115,6 +1115,7 @@ 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_GUIDE, "GIMP_UNDO_GUIDE", "guide" },
{ GIMP_UNDO_SAMPLE_POINT, "GIMP_UNDO_SAMPLE_POINT", "sample-point" },
......@@ -1205,6 +1206,7 @@ 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_GUIDE, NC_("undo-type", "Guide"), NULL },
{ GIMP_UNDO_SAMPLE_POINT, NC_("undo-type", "Sample Point"), NULL },
......
......@@ -530,6 +530,7 @@ 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_GUIDE, /*< desc="Guide" >*/
GIMP_UNDO_SAMPLE_POINT, /*< desc="Sample Point" >*/
......
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "gimpimage.h"
#include "gimpimage-metadata.h"
#include "gimpimage-private.h"
#include "gimpimage-undo-push.h"
/* public functions */
GimpMetadata *
gimp_image_get_metadata (GimpImage *image)
{
GimpImagePrivate *private;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
private = GIMP_IMAGE_GET_PRIVATE (image);
return private->metadata;
}
void
gimp_image_set_metadata (GimpImage *image,
GimpMetadata *metadata,
gboolean push_undo)
{
GimpImagePrivate *private;
g_return_if_fail (GIMP_IS_IMAGE (image));
private = GIMP_IMAGE_GET_PRIVATE (image);
if (metadata != private->metadata)
{
if (push_undo)
gimp_image_undo_push_image_metadata (image, NULL);
if (private->metadata)
g_object_unref (private->metadata);
private->metadata = metadata;
if (private->metadata)
{
gdouble xres, yres;
g_object_ref (private->metadata);
gimp_metadata_set_pixel_size (metadata,
gimp_image_get_width (image),
gimp_image_get_height (image));
switch (gimp_image_get_component_type (image))
{
case GIMP_COMPONENT_TYPE_U8:
gimp_metadata_set_bits_per_sample (metadata, 8);
break;
case GIMP_COMPONENT_TYPE_U16:
case GIMP_COMPONENT_TYPE_HALF:
gimp_metadata_set_bits_per_sample (metadata, 16);
break;
case GIMP_COMPONENT_TYPE_U32:
case GIMP_COMPONENT_TYPE_FLOAT:
gimp_metadata_set_bits_per_sample (metadata, 32);
break;
}
gimp_image_get_resolution (image, &xres, &yres);
gimp_metadata_set_resolution (metadata, xres, yres,
gimp_image_get_unit (image));
}
g_object_notify (G_OBJECT (image), "metadata");
}
}
......@@ -15,25 +15,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* EXIF-handling code for the metadata library.
*/
#ifndef __GIMP_EXIF_H__
#define __GIMP_EXIF_H__
void gimp_metadata_store_exif (gint32 image_ID,
ExifData *exif_data);
#ifndef __GIMP_IMAGE_METADATA_H__
#define __GIMP_IMAGE_METADATA_H__
ExifData * gimp_metadata_generate_exif (gint32 image_ID);
const gchar * gimp_exif_content_get_value (ExifContent *content,
ExifTag tag,
gchar *value,
gint maxlen);
GimpMetadata * gimp_image_get_metadata (GimpImage *image);
void gimp_image_set_metadata (GimpImage *image,
GimpMetadata *metadata,
gboolean push_undo);
void gimp_exif_data_remove_entry (ExifData *exif_data,
ExifIfd ifd,
ExifTag tag);
#endif /* __GIMP_EXIF_H__ */
#endif /* __GIMP_IMAGE_METADATA_H__ */
......@@ -55,6 +55,8 @@ struct _GimpImagePrivate
const Babl *babl_palette_rgb; /* palette's RGB Babl format */
const Babl *babl_palette_rgba; /* palette's RGBA Babl format */
GimpMetadata *metadata; /* image's metadata */
gint dirty; /* dirty flag -- # of ops */
guint dirty_time; /* time when image became dirty */
gint export_dirty; /* 'dirty' but for export */
......
......@@ -148,6 +148,18 @@ gimp_image_undo_push_image_colormap (GimpImage *image,
NULL);
}
GimpUndo *
gimp_image_undo_push_image_metadata (GimpImage *image,
const gchar *undo_desc)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_IMAGE_UNDO,
GIMP_UNDO_IMAGE_METADATA, undo_desc,
GIMP_DIRTY_IMAGE_META,
NULL);
}
GimpUndo *
gimp_image_undo_push_image_parasite (GimpImage *image,
const gchar *undo_desc,
......
......@@ -38,6 +38,8 @@ GimpUndo * gimp_image_undo_push_image_grid (GimpImage *image,
GimpGrid *grid);
GimpUndo * gimp_image_undo_push_image_colormap (GimpImage *image,
const gchar *undo_desc);
GimpUndo * gimp_image_undo_push_image_metadata (GimpImage *image,
const gchar *undo_desc);
GimpUndo * gimp_image_undo_push_image_parasite (GimpImage *image,
const gchar *undo_desc,
const GimpParasite *parasite);
......
......@@ -23,6 +23,7 @@
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include <gexiv2/gexiv2.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
......@@ -47,6 +48,7 @@
#include "gimpimage.h"
#include "gimpimage-colormap.h"
#include "gimpimage-guides.h"
#include "gimpimage-metadata.h"
#include "gimpimage-sample-points.h"
#include "gimpimage-preview.h"
#include "gimpimage-private.h"
......@@ -130,6 +132,7 @@ enum
PROP_HEIGHT,
PROP_BASE_TYPE,
PROP_PRECISION,
PROP_METADATA,
PROP_BUFFER
};
......@@ -165,12 +168,14 @@ static gchar * gimp_image_get_description (GimpViewable *viewable,
static void gimp_image_real_mode_changed (GimpImage *image);
static void gimp_image_real_precision_changed(GimpImage *image);
static void gimp_image_real_resolution_changed(GimpImage *image);
static void gimp_image_real_size_changed_detailed
(GimpImage *image,
gint previous_origin_x,
gint previous_origin_y,
gint previous_width,
gint previous_height);
static void gimp_image_real_unit_changed (GimpImage *image);
static void gimp_image_real_colormap_changed (GimpImage *image,
gint color_index);
......@@ -552,9 +557,9 @@ gimp_image_class_init (GimpImageClass *klass)
klass->component_visibility_changed = NULL;
klass->component_active_changed = NULL;
klass->mask_changed = NULL;
klass->resolution_changed = NULL;
klass->resolution_changed = gimp_image_real_resolution_changed;
klass->size_changed_detailed = gimp_image_real_size_changed_detailed;
klass->unit_changed = NULL;
klass->unit_changed = gimp_image_real_unit_changed;
klass->quick_mask_changed = NULL;
klass->selection_invalidate = NULL;
......@@ -610,6 +615,11 @@ gimp_image_class_init (GimpImageClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_METADATA,
g_param_spec_object ("metadata", NULL, NULL,
GEXIV2_TYPE_METADATA,
GIMP_PARAM_READABLE));
g_object_class_override_property (object_class, PROP_BUFFER, "buffer");
g_type_class_add_private (klass, sizeof (GimpImagePrivate));
......@@ -667,6 +677,8 @@ gimp_image_init (GimpImage *image)
private->n_colors = 0;
private->palette = NULL;
private->metadata = NULL;
private->dirty = 1;
private->dirty_time = 0;
private->undo_freeze_count = 0;
......@@ -837,6 +849,7 @@ gimp_image_set_property (GObject *object,
case PROP_PRECISION:
private->precision = g_value_get_enum (value);
break;
case PROP_METADATA:
case PROP_BUFFER:
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
......@@ -873,6 +886,9 @@ gimp_image_get_property (GObject *object,
case PROP_PRECISION:
g_value_set_enum (value, private->precision);
break;
case PROP_METADATA:
g_value_set_object (value, gimp_image_get_metadata (image));
break;
case PROP_BUFFER:
g_value_set_object (value, gimp_image_get_buffer (GIMP_PICKABLE (image)));
break;
......@@ -948,6 +964,12 @@ gimp_image_finalize (GObject *object)
if (private->colormap)
gimp_image_colormap_free (image);
if (private->metadata)
{
g_object_unref (private->metadata);
private->metadata = NULL;
}
if (private->layers)
{
g_object_unref (private->layers);
......@@ -1128,9 +1150,10 @@ gimp_image_get_size (GimpViewable *viewable,
static void
gimp_image_size_changed (GimpViewable *viewable)
{
GimpImage *image = GIMP_IMAGE (viewable);
GList *all_items;
GList *list;
GimpImage *image = GIMP_IMAGE (viewable);
GimpMetadata *metadata;
GList *all_items;
GList *list;
if (GIMP_VIEWABLE_CLASS (parent_class)->size_changed)
GIMP_VIEWABLE_CLASS (parent_class)->size_changed (viewable);
......@@ -1155,6 +1178,12 @@ gimp_image_size_changed (GimpViewable *viewable)
gimp_viewable_size_changed (GIMP_VIEWABLE (gimp_image_get_mask (image)));
metadata = gimp_image_get_metadata (image);
if (metadata)
gimp_metadata_set_pixel_size (metadata,
gimp_image_get_width (image),
gimp_image_get_height (image));
gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
}
......@@ -1181,9 +1210,48 @@ gimp_image_real_mode_changed (GimpImage *image)
static void
gimp_image_real_precision_changed (GimpImage *image)
{
GimpMetadata *metadata;
metadata = gimp_image_get_metadata (image);
if (metadata)
{
switch (gimp_image_get_component_type (image))
{
case GIMP_COMPONENT_TYPE_U8:
gimp_metadata_set_bits_per_sample (metadata, 8);
break;
case GIMP_COMPONENT_TYPE_U16:
case GIMP_COMPONENT_TYPE_HALF:
gimp_metadata_set_bits_per_sample (metadata, 16);
break;
case GIMP_COMPONENT_TYPE_U32:
case GIMP_COMPONENT_TYPE_FLOAT:
gimp_metadata_set_bits_per_sample (metadata, 32);
break;
}
}
gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
}
static void
gimp_image_real_resolution_changed (GimpImage *image)
{
GimpMetadata *metadata;
metadata = gimp_image_get_metadata (image);
if (metadata)
{
gdouble xres, yres;
gimp_image_get_resolution (image, &xres, &yres);
gimp_metadata_set_resolution (metadata, xres, yres,
gimp_image_get_unit (image));
}
}
static void
gimp_image_real_size_changed_detailed (GimpImage *image,
gint previous_origin_x,
......@@ -1198,6 +1266,22 @@ gimp_image_real_size_changed_detailed (GimpImage *image,
gimp_viewable_size_changed (GIMP_VIEWABLE (image));
}
static void
gimp_image_real_unit_changed (GimpImage *image)
{
GimpMetadata *metadata;
metadata = gimp_image_get_metadata (image);
if (metadata)
{
gdouble xres, yres;
gimp_image_get_resolution (image, &xres, &yres);
gimp_metadata_set_resolution (metadata, xres, yres,
gimp_image_get_unit (image));
}
}
static void
gimp_image_real_colormap_changed (GimpImage *image,
gint color_index)
......
......@@ -35,6 +35,7 @@
#include "gimpimage.h"
#include "gimpimage-colormap.h"
#include "gimpimage-grid.h"
#include "gimpimage-metadata.h"
#include "gimpimage-private.h"
#include "gimpimageundo.h"
#include "gimpparasitelist.h"
......@@ -186,6 +187,11 @@ gimp_image_undo_constructed (GObject *object)
GIMP_IMAGE_COLORMAP_SIZE);
break;
case GIMP_UNDO_IMAGE_METADATA:
image_undo->metadata =
gimp_metadata_duplicate (gimp_image_get_metadata (image));
break;
case GIMP_UNDO_PARASITE_ATTACH:
case GIMP_UNDO_PARASITE_REMOVE:
g_assert (image_undo->parasite_name != NULL);
......@@ -284,6 +290,9 @@ gimp_image_undo_get_memsize (GimpObject *object,
if (image_undo->colormap)
memsize += GIMP_IMAGE_COLORMAP_SIZE;
if (image_undo->metadata)
memsize += gimp_g_object_get_memsize (G_OBJECT (image_undo->metadata));
memsize += gimp_object_get_memsize (GIMP_OBJECT (image_undo->grid),
gui_size);
memsize += gimp_string_get_memsize (image_undo->parasite_name);
......@@ -447,6 +456,20 @@ gimp_image_undo_pop (GimpUndo *undo,
}
break;
case GIMP_UNDO_IMAGE_METADATA:
{
GimpMetadata *metadata;
metadata = gimp_metadata_duplicate (gimp_image_get_metadata (image));
gimp_image_set_metadata (image, image_undo->metadata, FALSE);
if (image_undo->metadata)
g_object_unref (image_undo->metadata);
image_undo->metadata = metadata;
}
break;
case GIMP_UNDO_PARASITE_ATTACH:
case GIMP_UNDO_PARASITE_REMOVE:
{
......@@ -495,6 +518,12 @@ gimp_image_undo_free (GimpUndo *undo,
image_undo->colormap = NULL;
}
if (image_undo->metadata)
{
g_free (image_undo->metadata);
image_undo->metadata = NULL;
}
if (image_undo->parasite_name)
{
g_free (image_undo->parasite_name);
......
......@@ -50,6 +50,7 @@ struct _GimpImageUndo
GimpGrid *grid;
gint num_colors;
guchar *colormap;
GimpMetadata *metadata;
gchar *parasite_name;
GimpParasite *parasite;
};
......
......@@ -42,6 +42,7 @@
#include "core/gimpimage-duplicate.h"
#include "core/gimpimage-flip.h"
#include "core/gimpimage-merge.h"
#include "core/gimpimage-metadata.h"
#include "core/gimpimage-pick-color.h"
#include "core/gimpimage-pick-layer.h"
#include "core/gimpimage-resize.h"
......@@ -1706,6 +1707,67 @@ image_set_colormap_invoker (GimpProcedure *procedure,
error ? *error : NULL);
}
static GimpValueArray *
image_get_metadata_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpValueArray *return_vals;
GimpImage *image;
gchar *metadata_string = NULL;
image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);
if (success)
{
GimpMetadata *metadata = gimp_image_get_metadata (image);
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 *
image_set_metadata_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpImage *image;
const gchar *metadata_string;
image = gimp_value_get_image (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_image_set_metadata (image, metadata, TRUE);
if (metadata)
g_object_unref (metadata);
}
return gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
}
static GimpValueArray *
image_clean_all_invoker (GimpProcedure *procedure,
Gimp *gimp,
......@@ -4553,6 +4615,66 @@ register_image_procs (GimpPDB *pdb)
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-image-get-metadata
*/
procedure = gimp_procedure_new (image_get_metadata_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-image-get-metadata");
gimp_procedure_set_static_strings (procedure,
"gimp-image-get-metadata",
"Returns the image's metadata.",
"Returns exif/iptc/xmp metadata from the image.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",
NULL);
gimp_procedure_add_argument (procedure,
gimp_param_spec_image_id ("image",
"image",
"The image",
pdb->gimp, FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("metadata-string",
"metadata string",
"The exif/ptc/xmp metadata as a string",
FALSE, FALSE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-image-set-metadata
*/
procedure = gimp_procedure_new (image_set_metadata_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-image-set-metadata");
gimp_procedure_set_static_strings (procedure,
"gimp-image-set-metadata",
"Set the image's metadata.",
"Sets exif/iptc/xmp metadata on the image.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",
NULL);
gimp_procedure_add_argument (procedure,
gimp_param_spec_image_id ("image",
"image",
"The image",
pdb->gimp, FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("metadata-string",
"metadata string",
"The exif/ptc/xmp metadata as a string",
FALSE, FALSE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-image-clean-all
*/
......
......@@ -28,7 +28,7 @@
#include "internal-procs.h"
/* 701 procedures registered total */
/* 703 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)
......
......@@ -22,6 +22,7 @@
#include <pango/pango.h>
#include <pango/pangoft2.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gexiv2/gexiv2.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
......@@ -38,6 +39,7 @@ static gchar * sanity_check_pango (void);
static gchar * sanity_check_fontconfig (void);
static gchar * sanity_check_freetype (void);
static gchar * sanity_check_gdk_pixbuf (void);
static gchar * sanity_check_gexiv2 (void);
static gchar * sanity_check_babl (void);
static gchar * sanity_check_gegl (void);
static gchar * sanity_check_gegl_ops (void);
......@@ -69,6 +71,9 @@ sanity_check (void)
if (! abort_message)
abort_message = sanity_check_gdk_pixbuf ();
if (! abort_message)
abort_message = sanity_check_gexiv2 ();
if (! abort_message)
abort_message = sanity_check_babl ();
......@@ -346,6 +351,46 @@ sanity_check_gdk_pixbuf (void)
return NULL;
}
static gchar *
sanity_check_gexiv2 (void)
{
#ifdef GEXIV2_MAJOR_VERSION
#define GEXIV2_REQUIRED_MAJOR 0
#define GEXIV2_REQUIRED_MINOR 7
#define GEXIV2_REQUIRED_MICRO 0
gint gexiv2_version = gexiv2_get_version ();
if (gexiv2_version < (GEXIV2_REQUIRED_MAJOR * 100 * 100 +
GEXIV2_REQUIRED_MINOR * 100 +
GEXIV2_REQUIRED_MICRO))
{
const gint gexiv2_major_version = gexiv2_version / 100 / 100;
const gint gexiv2_minor_version = gexiv2_version / 100 % 100;
const gint gexiv2_micro_version = gexiv2_version % 100;
return g_strdup_printf
("gexiv2 version too old!\n\n"
"GIMP requires gexiv2 version %d.%d.%d or later.\n"
"Installed gexiv2 version is %d.%d.%d.\n\n"
"Somehow you or your software packager managed\n"
"to install GIMP with an older gexiv2 version.\n\n"
"Please upgrade to gexiv2 version %d.%d.%d or later.",
GEXIV2_REQUIRED_MAJOR, GEXIV2_REQUIRED_MINOR, GEXIV2_REQUIRED_MICRO,
gexiv2_major_version, gexiv2_minor_version, gexiv2_micro_version,
GEXIV2_REQUIRED_MAJOR, GEXIV2_REQUIRED_MINOR, GEXIV2_REQUIRED_MICRO);