[gimp] Issue #5691: Import/Export of GeoTIFF loses important header tags.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Issue #5691: Import/Export of GeoTIFF loses important header tags.
- Date: Sun, 1 Nov 2020 13:34:19 +0000 (UTC)
commit b67ca557f0838719d5e784d2b1084860c8814ccf
Author: Ruthra Kumar <ruthrab gmail com>
Date: Thu Oct 29 08:01:26 2020 +0530
Issue #5691: Import/Export of GeoTIFF loses important header tags.
file-tiff plugin can read and write GeoTIFF tags
New checkbox 'Save GeoTIFF data' has been added to Export dialog.
Signed-off-by: Ruthra Kumar <ruthrab gmail com>
plug-ins/file-tiff/file-tiff-io.c | 20 +++++++++++
plug-ins/file-tiff/file-tiff-io.h | 18 ++++++++++
plug-ins/file-tiff/file-tiff-load.c | 68 +++++++++++++++++++++++++++++++++++
plug-ins/file-tiff/file-tiff-save.c | 72 +++++++++++++++++++++++++++++++++++++
plug-ins/file-tiff/file-tiff.c | 6 ++++
5 files changed, 184 insertions(+)
---
diff --git a/plug-ins/file-tiff/file-tiff-io.c b/plug-ins/file-tiff/file-tiff-io.c
index 4c45b9e190..6c0a3040b4 100644
--- a/plug-ins/file-tiff/file-tiff-io.c
+++ b/plug-ins/file-tiff/file-tiff-io.c
@@ -46,6 +46,7 @@ typedef struct
gsize position;
} TiffIO;
+static TIFFExtendProc parent_extender;
static void tiff_io_warning (const gchar *module,
const gchar *fmt,
@@ -64,6 +65,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..fc26357758 100644
--- a/plug-ins/file-tiff/file-tiff-io.h
+++ b/plug-ins/file-tiff/file-tiff-io.h
@@ -22,6 +22,24 @@
#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 56c504af91..2edd742470 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -887,6 +887,74 @@ 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 337ad08aa8..0965cdbc66 100644
--- a/plug-ins/file-tiff/file-tiff-save.c
+++ b/plug-ins/file-tiff/file-tiff-save.c
@@ -320,10 +320,12 @@ save_layer (TIFF *tif,
gint offset_x, offset_y;
gint config_compression;
gboolean config_save_transp_pixels;
+ gboolean config_save_geotiff_tags;
g_object_get (config,
"compression", &config_compression,
"save-transparent-pixels", &config_save_transp_pixels,
+ "save-geotiff", &config_save_geotiff_tags,
NULL);
compression = gimp_compression_to_tiff_compression (config_compression);
@@ -771,6 +773,72 @@ save_layer (TIFF *tif,
* (gdouble) row / (gdouble) rows);
}
+ /* Save GeoTIFF tags to file, if available */
+ if (config_save_geotiff_tags)
+ {
+ 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);
@@ -1358,6 +1426,10 @@ save_dialog (GimpImage *image,
_("Save thumbnail"));
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
+ button = gimp_prop_check_button_new (config, "save-geotiff",
+ _("Save GeoTIFF data"));
+ gtk_grid_attach (GTK_GRID (grid), button, 0 ,row++, 2, 1);
+
#ifdef TIFFTAG_ICCPROFILE
button = gimp_prop_check_button_new (config, "save-color-profile",
_("Save color profile"));
diff --git a/plug-ins/file-tiff/file-tiff.c b/plug-ins/file-tiff/file-tiff.c
index 9b9c6bbf15..b05e3dbd44 100644
--- a/plug-ins/file-tiff/file-tiff.c
+++ b/plug-ins/file-tiff/file-tiff.c
@@ -258,6 +258,12 @@ tiff_create_procedure (GimpPlugIn *plug_in,
"Save color profile",
gimp_export_color_profile (),
G_PARAM_READWRITE);
+
+ GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-geotiff",
+ "Save GeoTIFF data",
+ "Save GeoTIFF data",
+ TRUE,
+ G_PARAM_READWRITE);
}
return procedure;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]