[gimp/gimp-2-10] GeoTIFF tags support added to file-tiff plugin.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] GeoTIFF tags support added to file-tiff plugin.
- Date: Tue, 3 Nov 2020 09:17:13 +0000 (UTC)
commit 0b40a4c8bcd494dfb5728c849f1f324e3c8eb41a
Author: Ruthra Kumar <ruthrab gmail com>
Date: Tue Nov 3 11:55:33 2020 +0530
GeoTIFF tags support added to file-tiff plugin.
New checkbox 'Save GeoTIFF data' added to Export Dialog box.
plug-ins/file-tiff/file-tiff-io.c | 20 ++++++++++
plug-ins/file-tiff/file-tiff-io.h | 17 +++++++++
plug-ins/file-tiff/file-tiff-load.c | 67 ++++++++++++++++++++++++++++++++++
plug-ins/file-tiff/file-tiff-save.c | 73 +++++++++++++++++++++++++++++++++++++
plug-ins/file-tiff/file-tiff-save.h | 1 +
plug-ins/file-tiff/file-tiff.c | 2 +
plug-ins/ui/plug-in-file-tiff.ui | 15 ++++++++
7 files changed, 195 insertions(+)
---
diff --git a/plug-ins/file-tiff/file-tiff-io.c b/plug-ins/file-tiff/file-tiff-io.c
index 4c45b9e190..fb63c661b1 100644
--- a/plug-ins/file-tiff/file-tiff-io.c
+++ b/plug-ins/file-tiff/file-tiff-io.c
@@ -47,6 +47,8 @@ typedef struct
} TiffIO;
+static TIFFExtendProc parent_extender;
+
static void tiff_io_warning (const gchar *module,
const gchar *fmt,
va_list ap) G_GNUC_PRINTF (2, 0);
@@ -64,7 +66,23 @@ static toff_t tiff_io_seek (thandle_t handle,
gint whence);
static gint tiff_io_close (thandle_t handle);
static toff_t tiff_io_get_file_size (thandle_t handle);
+static void register_geotags (TIFF *tif);
+
+static void
+register_geotags (TIFF *tif)
+{
+ static gboolean geotifftags_registered = FALSE;
+
+ if (geotifftags_registered)
+ return;
+
+ geotifftags_registered = TRUE;
+ TIFFMergeFieldInfo (tif, geotifftags_fieldinfo, (sizeof (geotifftags_fieldinfo) / sizeof
(geotifftags_fieldinfo[0])));
+
+ if (parent_extender)
+ (*parent_extender) (tif);
+}
static TiffIO tiff_io = { 0, };
@@ -77,6 +95,8 @@ tiff_open (GFile *file,
TIFFSetWarningHandler ((TIFFErrorHandler) tiff_io_warning);
TIFFSetErrorHandler ((TIFFErrorHandler) tiff_io_error);
+ parent_extender = TIFFSetTagExtender (register_geotags);
+
tiff_io.file = file;
if (! strcmp (mode, "r"))
diff --git a/plug-ins/file-tiff/file-tiff-io.h b/plug-ins/file-tiff/file-tiff-io.h
index f4d4e31879..6add4de3f5 100644
--- a/plug-ins/file-tiff/file-tiff-io.h
+++ b/plug-ins/file-tiff/file-tiff-io.h
@@ -22,6 +22,23 @@
#ifndef __FILE_TIFF_IO_H__
#define __FILE_TIFF_IO_H__
+/* Adding support for GeoTIFF Tags */
+
+#define GEOTIFF_MODELPIXELSCALE 33550
+#define GEOTIFF_MODELTIEPOINT 33922
+#define GEOTIFF_MODELTRANSFORMATION 34264
+#define GEOTIFF_KEYDIRECTORY 34735
+#define GEOTIFF_DOUBLEPARAMS 34736
+#define GEOTIFF_ASCIIPARAMS 34737
+
+static const TIFFFieldInfo geotifftags_fieldinfo[] = {
+ { GEOTIFF_MODELPIXELSCALE, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoModelPixelScale" },
+ { GEOTIFF_MODELTIEPOINT, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoTiePoints" },
+ { GEOTIFF_MODELTRANSFORMATION, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoModelTransformation" },
+ { GEOTIFF_KEYDIRECTORY, -1, -1, TIFF_SHORT, FIELD_CUSTOM, TRUE, TRUE, "GeoKeyDirectory" },
+ { GEOTIFF_DOUBLEPARAMS, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, "GeoDoubleParams" },
+ { GEOTIFF_ASCIIPARAMS, -1, -1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, "GeoAsciiParams" }
+};
TIFF * tiff_open (GFile *file,
const gchar *mode,
diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c
index 255930111f..2586ad84e4 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -881,6 +881,73 @@ load_image (GFile *file,
}
}
+ /* Attach GeoTIFF Tags as Parasite, If available */
+ {
+ GimpParasite *parasite = NULL;
+ void *geotag_data = NULL;
+ uint32 count = 0;
+
+ if (TIFFGetField (tif, GEOTIFF_MODELPIXELSCALE, &count, &geotag_data))
+ {
+ parasite = gimp_parasite_new ("Gimp_GeoTIFF_ModelPixelScale",
+ GIMP_PARASITE_PERSISTENT,
+ (TIFFDataWidth (TIFF_DOUBLE) * count),
+ geotag_data);
+ gimp_image_attach_parasite (*image, parasite);
+ gimp_parasite_free (parasite);
+ }
+
+ if (TIFFGetField (tif, GEOTIFF_MODELTIEPOINT, &count, &geotag_data))
+ {
+ parasite = gimp_parasite_new ("Gimp_GeoTIFF_ModelTiePoint",
+ GIMP_PARASITE_PERSISTENT,
+ (TIFFDataWidth (TIFF_DOUBLE) * count),
+ geotag_data);
+ gimp_image_attach_parasite (*image, parasite);
+ gimp_parasite_free (parasite);
+ }
+
+ if (TIFFGetField (tif, GEOTIFF_MODELTRANSFORMATION, &count, &geotag_data))
+ {
+ parasite = gimp_parasite_new ("Gimp_GeoTIFF_ModelTransformation",
+ GIMP_PARASITE_PERSISTENT,
+ (TIFFDataWidth (TIFF_DOUBLE) * count),
+ geotag_data);
+ gimp_image_attach_parasite (*image, parasite);
+ gimp_parasite_free (parasite);
+ }
+
+ if (TIFFGetField (tif, GEOTIFF_KEYDIRECTORY, &count, &geotag_data) )
+ {
+ parasite = gimp_parasite_new ("Gimp_GeoTIFF_KeyDirectory",
+ GIMP_PARASITE_PERSISTENT,
+ (TIFFDataWidth (TIFF_SHORT) * count),
+ geotag_data);
+ gimp_image_attach_parasite (*image, parasite);
+ gimp_parasite_free (parasite);
+ }
+
+ if (TIFFGetField (tif, GEOTIFF_DOUBLEPARAMS, &count, &geotag_data))
+ {
+ parasite = gimp_parasite_new ("Gimp_GeoTIFF_DoubleParams",
+ GIMP_PARASITE_PERSISTENT,
+ (TIFFDataWidth (TIFF_DOUBLE) * count),
+ geotag_data);
+ gimp_image_attach_parasite (*image, parasite);
+ gimp_parasite_free (parasite);
+ }
+
+ if (TIFFGetField (tif, GEOTIFF_ASCIIPARAMS, &count, &geotag_data))
+ {
+ parasite = gimp_parasite_new ("Gimp_GeoTIFF_Asciiparams",
+ GIMP_PARASITE_PERSISTENT,
+ (TIFFDataWidth (TIFF_ASCII) * count),
+ geotag_data);
+ gimp_image_attach_parasite (*image, parasite);
+ gimp_parasite_free (parasite);
+ }
+ }
+
/* any resolution info in the file? */
{
gfloat xres = 72.0;
diff --git a/plug-ins/file-tiff/file-tiff-save.c b/plug-ins/file-tiff/file-tiff-save.c
index ce80cbe98d..d536d58a47 100644
--- a/plug-ins/file-tiff/file-tiff-save.c
+++ b/plug-ins/file-tiff/file-tiff-save.c
@@ -753,6 +753,72 @@ save_layer (TIFF *tif,
* (gdouble) row / (gdouble) rows);
}
+ /* Save GeoTIFF tags to file, if available */
+ if (tsvals->save_geotiff)
+ {
+ GimpParasite *parasite = NULL;
+
+ parasite = gimp_image_get_parasite (image,"Gimp_GeoTIFF_ModelPixelScale");
+
+ if (parasite)
+ {
+ TIFFSetField (tif,
+ GEOTIFF_MODELPIXELSCALE,
+ (gimp_parasite_data_size (parasite) / TIFFDataWidth (TIFF_DOUBLE)),
+ gimp_parasite_data (parasite));
+ gimp_parasite_free (parasite);
+ }
+
+ parasite = gimp_image_get_parasite (image,"Gimp_GeoTIFF_ModelTiePoint");
+ if (parasite)
+ {
+ TIFFSetField (tif,
+ GEOTIFF_MODELTIEPOINT,
+ (gimp_parasite_data_size (parasite) / TIFFDataWidth (TIFF_DOUBLE)),
+ gimp_parasite_data (parasite));
+ gimp_parasite_free (parasite);
+ }
+
+ parasite = gimp_image_get_parasite (image,"Gimp_GeoTIFF_ModelTransformation");
+ if (parasite)
+ {
+ TIFFSetField (tif,
+ GEOTIFF_MODELTRANSFORMATION,
+ (gimp_parasite_data_size (parasite) / TIFFDataWidth (TIFF_DOUBLE)),
+ gimp_parasite_data (parasite));
+ gimp_parasite_free (parasite);
+ }
+
+ parasite = gimp_image_get_parasite (image,"Gimp_GeoTIFF_KeyDirectory");
+ if (parasite)
+ {
+ TIFFSetField (tif,
+ GEOTIFF_KEYDIRECTORY,
+ (gimp_parasite_data_size (parasite) / TIFFDataWidth (TIFF_SHORT)),
+ gimp_parasite_data (parasite));
+ gimp_parasite_free (parasite);
+ }
+
+ parasite = gimp_image_get_parasite (image,"Gimp_GeoTIFF_DoubleParams");
+ if (parasite)
+ {
+ TIFFSetField (tif,
+ GEOTIFF_DOUBLEPARAMS,
+ (gimp_parasite_data_size (parasite) / TIFFDataWidth (TIFF_DOUBLE)),
+ gimp_parasite_data (parasite));
+ gimp_parasite_free (parasite);
+ }
+
+ parasite = gimp_image_get_parasite (image,"Gimp_GeoTIFF_Asciiparams");
+ if (parasite)
+ {
+ TIFFSetField (tif,
+ GEOTIFF_ASCIIPARAMS,
+ gimp_parasite_data (parasite));
+ gimp_parasite_free (parasite);
+ }
+ }
+
TIFFWriteDirectory (tif);
gimp_progress_update (progress_base + progress_fraction);
@@ -1252,6 +1318,13 @@ save_dialog (TiffSaveVals *tsvals,
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_iptc);
+ toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-geotiff"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
+ tsvals->save_geotiff);
+ g_signal_connect (toggle, "toggled",
+ G_CALLBACK (gimp_toggle_button_update),
+ &tsvals->save_geotiff);
+
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-thumbnail"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
tsvals->save_thumbnail);
diff --git a/plug-ins/file-tiff/file-tiff-save.h b/plug-ins/file-tiff/file-tiff-save.h
index b5fb1b3157..9cb97b7465 100644
--- a/plug-ins/file-tiff/file-tiff-save.h
+++ b/plug-ins/file-tiff/file-tiff-save.h
@@ -31,6 +31,7 @@ typedef struct
gboolean save_exif;
gboolean save_xmp;
gboolean save_iptc;
+ gboolean save_geotiff;
gboolean save_thumbnail;
gboolean save_profile;
gboolean save_layers;
diff --git a/plug-ins/file-tiff/file-tiff.c b/plug-ins/file-tiff/file-tiff.c
index 61405f12c4..f9034ef562 100644
--- a/plug-ins/file-tiff/file-tiff.c
+++ b/plug-ins/file-tiff/file-tiff.c
@@ -86,6 +86,7 @@ static TiffSaveVals tsvals =
FALSE, /* save exif */
FALSE, /* save xmp */
FALSE, /* save iptc */
+ TRUE, /* save geotiff */
TRUE, /* save thumbnail */
TRUE, /* save profile */
TRUE, /* save layers */
@@ -286,6 +287,7 @@ run (const gchar *name,
tsvals.save_iptc = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
tsvals.save_thumbnail = (metadata_flags & GIMP_METADATA_SAVE_THUMBNAIL) != 0;
tsvals.save_profile = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
+ tsvals.save_geotiff = TRUE;
parasite = gimp_image_get_parasite (orig_image, "gimp-comment");
if (parasite)
diff --git a/plug-ins/ui/plug-in-file-tiff.ui b/plug-ins/ui/plug-in-file-tiff.ui
index c6672960e5..ede5c9a8b8 100644
--- a/plug-ins/ui/plug-in-file-tiff.ui
+++ b/plug-ins/ui/plug-in-file-tiff.ui
@@ -245,6 +245,21 @@
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="save-geotiff">
+ <property name="label" translatable="yes">Save _GeoTIFF data</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">True</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]