[gimp] plug-ins: merge the file-tiff-load and file-tiff-save plug-ins



commit c64a1041555d6594e231ec97a88e663141ec6155
Author: Michael Natterer <mitch gimp org>
Date:   Thu Dec 3 01:02:43 2015 +0100

    plug-ins: merge the file-tiff-load and file-tiff-save plug-ins
    
    so they can share duplicated code.

 plug-ins/file-tiff/.gitignore       |    6 +-
 plug-ins/file-tiff/Makefile.am      |   31 +--
 plug-ins/file-tiff/file-tiff-io.c   |  128 ++++++++
 plug-ins/file-tiff/file-tiff-io.h   |   31 ++
 plug-ins/file-tiff/file-tiff-load.c |  417 ++++-----------------------
 plug-ins/file-tiff/file-tiff-load.h |   46 +++
 plug-ins/file-tiff/file-tiff-save.c |  539 +++-------------------------------
 plug-ins/file-tiff/file-tiff-save.h |   55 ++++
 plug-ins/file-tiff/file-tiff.c      |  554 +++++++++++++++++++++++++++++++++++
 po-plug-ins/POTFILES.in             |    1 +
 10 files changed, 929 insertions(+), 879 deletions(-)
---
diff --git a/plug-ins/file-tiff/.gitignore b/plug-ins/file-tiff/.gitignore
index 5936c50..3e442a7 100644
--- a/plug-ins/file-tiff/.gitignore
+++ b/plug-ins/file-tiff/.gitignore
@@ -3,7 +3,5 @@
 /.deps
 /_libs
 /.libs
-/file-tiff-load
-/file-tiff-load.exe
-/file-tiff-save
-/file-tiff-save.exe
+/file-tiff
+/file-tiff.exe
diff --git a/plug-ins/file-tiff/Makefile.am b/plug-ins/file-tiff/Makefile.am
index 0fa9dd1..8855180 100644
--- a/plug-ins/file-tiff/Makefile.am
+++ b/plug-ins/file-tiff/Makefile.am
@@ -14,8 +14,7 @@ endif
 
 if HAVE_WINDRES
 include $(top_srcdir)/build/windows/gimprc-plug-ins.rule
-file_tiff_load_RC = file-tiff-load.rc.o
-file_tiff_save_RC = file-tiff-save.rc.o
+file_tiff_RC = file-tiff.rc.o
 endif
 
 AM_LDFLAGS = $(mwindows)
@@ -31,15 +30,18 @@ AM_CPPFLAGS = \
        $(GEXIV2_CFLAGS)        \
        -I$(includedir)
 
-libexec_PROGRAMS = file-tiff-load file-tiff-save
+libexec_PROGRAMS = file-tiff
 
-file_tiff_load_SOURCES = \
-       file-tiff-load.c
+file_tiff_SOURCES = \
+       file-tiff.c             \
+       file-tiff-io.c          \
+       file-tiff-io.h          \
+       file-tiff-load.c        \
+       file-tiff-load.h        \
+       file-tiff-save.c        \
+       file-tiff-save.h
 
-file_tiff_save_SOURCES = \
-       file-tiff-save.c
-
-ldadd = \
+file_tiff_LDADD = \
        $(libgimpui)            \
        $(libgimpwidgets)       \
        $(libgimpconfig)        \
@@ -51,12 +53,5 @@ ldadd = \
        $(GTK_LIBS)             \
        $(GEGL_LIBS)            \
        $(RT_LIBS)              \
-       $(INTLLIBS)
-
-file_tiff_load_LDADD = \
-       $(ldadd)                \
-       $(file_tiff_load_RC)
-
-file_tiff_save_LDADD = \
-       $(ldadd)                \
-       $(file_tiff_load_RC)
+       $(INTLLIBS)             \
+       $(file_tiff_RC)
diff --git a/plug-ins/file-tiff/file-tiff-io.c b/plug-ins/file-tiff/file-tiff-io.c
new file mode 100644
index 0000000..2139236
--- /dev/null
+++ b/plug-ins/file-tiff/file-tiff-io.c
@@ -0,0 +1,128 @@
+/* tiff loading for GIMP
+ *  -Peter Mattis
+ *
+ * The TIFF loading code has been completely revamped by Nick Lamb
+ * njl195 zepler org uk -- 18 May 1998
+ * And it now gains support for tiles (and doubtless a zillion bugs)
+ * njl195 zepler org uk -- 12 June 1999
+ * LZW patent fuss continues :(
+ * njl195 zepler org uk -- 20 April 2000
+ * The code for this filter is based on "tifftopnm" and "pnmtotiff",
+ *  2 programs that are a part of the netpbm package.
+ * khk khk net -- 13 May 2000
+ * Added support for ICCPROFILE tiff tag. If this tag is present in a
+ * TIFF file, then a parasite is created and vice versa.
+ * peter kirchgessner net -- 29 Oct 2002
+ * Progress bar only when run interactive
+ * Added support for layer offsets - pablo dangelo web de -- 7 Jan 2004
+ * Honor EXTRASAMPLES tag while loading images with alphachannel
+ * pablo dangelo web de -- 16 Jan 2004
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <tiffio.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#include "file-tiff-io.h"
+
+
+static void   tiff_warning (const gchar *module,
+                            const gchar *fmt,
+                            va_list      ap) G_GNUC_PRINTF (2, 0);
+static void   tiff_error   (const gchar *module,
+                            const gchar *fmt,
+                            va_list      ap) G_GNUC_PRINTF (2, 0);
+
+
+TIFF *
+tiff_open (const gchar  *filename,
+           const gchar  *mode,
+           GError      **error)
+{
+  TIFFSetWarningHandler (tiff_warning);
+  TIFFSetErrorHandler (tiff_error);
+
+#ifdef G_OS_WIN32
+  gunichar2 *utf16_filename = g_utf8_to_utf16 (filename, -1, NULL, NULL, error);
+
+  if (utf16_filename)
+    {
+      TIFF *tif = TIFFOpenW (utf16_filename, mode);
+
+      g_free (utf16_filename);
+
+      return tif;
+    }
+
+  return NULL;
+#else
+  return TIFFOpen (filename, mode);
+#endif
+}
+
+static void
+tiff_warning (const gchar *module,
+              const gchar *fmt,
+              va_list      ap)
+{
+  gint tag = 0;
+
+  if (! strcmp (fmt, "%s: unknown field with tag %d (0x%x) encountered"))
+    {
+      va_list ap_test;
+
+      G_VA_COPY (ap_test, ap);
+
+      va_arg (ap_test, const char *); /* ignore first arg */
+
+      tag = va_arg (ap_test, int);
+    }
+  /* for older versions of libtiff? */
+  else if (! strcmp (fmt, "unknown field with tag %d (0x%x) ignored"))
+    {
+      va_list ap_test;
+
+      G_VA_COPY (ap_test, ap);
+
+      tag = va_arg (ap_test, int);
+    }
+
+  /* Workaround for: http://bugzilla.gnome.org/show_bug.cgi?id=131975
+   * Ignore the warnings about unregistered private tags (>= 32768).
+   */
+  if (tag >= 32768)
+    return;
+
+  /* Other unknown fields are only reported to stderr. */
+  if (tag > 0)
+    {
+      gchar *msg = g_strdup_vprintf (fmt, ap);
+
+      g_printerr ("%s\n", msg);
+      g_free (msg);
+
+      return;
+    }
+
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
+}
+
+static void
+tiff_error (const gchar *module,
+            const gchar *fmt,
+            va_list      ap)
+{
+  /* Workaround for: http://bugzilla.gnome.org/show_bug.cgi?id=132297
+   * Ignore the errors related to random access and JPEG compression
+   */
+  if (! strcmp (fmt, "Compression algorithm does not support random access"))
+    return;
+
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
+}
diff --git a/plug-ins/file-tiff/file-tiff-io.h b/plug-ins/file-tiff/file-tiff-io.h
new file mode 100644
index 0000000..b9c285b
--- /dev/null
+++ b/plug-ins/file-tiff/file-tiff-io.h
@@ -0,0 +1,31 @@
+/* tiff loading for GIMP
+ *  -Peter Mattis
+ *
+ * The TIFF loading code has been completely revamped by Nick Lamb
+ * njl195 zepler org uk -- 18 May 1998
+ * And it now gains support for tiles (and doubtless a zillion bugs)
+ * njl195 zepler org uk -- 12 June 1999
+ * LZW patent fuss continues :(
+ * njl195 zepler org uk -- 20 April 2000
+ * The code for this filter is based on "tifftopnm" and "pnmtotiff",
+ *  2 programs that are a part of the netpbm package.
+ * khk khk net -- 13 May 2000
+ * Added support for ICCPROFILE tiff tag. If this tag is present in a
+ * TIFF file, then a parasite is created and vice versa.
+ * peter kirchgessner net -- 29 Oct 2002
+ * Progress bar only when run interactive
+ * Added support for layer offsets - pablo dangelo web de -- 7 Jan 2004
+ * Honor EXTRASAMPLES tag while loading images with alphachannel
+ * pablo dangelo web de -- 16 Jan 2004
+ */
+
+#ifndef __FILE_TIFF_IO_H__
+#define __FILE_TIFF_IO_H__
+
+
+TIFF * tiff_open (const gchar  *filename,
+                  const gchar  *mode,
+                  GError      **error);
+
+
+#endif /* __FILE_TIFF_IO_H__ */
diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c
index 9a0bff1..affaf10 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -52,12 +52,12 @@
 #include <libgimp/gimp.h>
 #include <libgimp/gimpui.h>
 
+#include "file-tiff-load.h"
+
 #include "libgimp/stdplugins-intl.h"
 
 
-#define LOAD_PROC      "file-tiff-load"
-#define PLUG_IN_BINARY "file-tiff-load"
-#define PLUG_IN_ROLE   "gimp-file-tiff-load"
+#define PLUG_IN_ROLE "gimp-file-tiff-load"
 
 
 typedef struct
@@ -76,362 +76,43 @@ typedef struct
   guchar     *pixel;
 } ChannelData;
 
-typedef struct
-{
-  gint  o_pages;
-  gint  n_pages;
-  gint *pages;
-} TiffSelectedPages;
 
-
-/* Declare some local functions.
- */
-static void               query            (void);
-static void               run              (const gchar        *name,
-                                            gint                nparams,
-                                            const GimpParam    *param,
-                                            gint               *nreturn_vals,
-                                            GimpParam         **return_vals);
-
-static gboolean           load_dialog      (TIFF               *tif,
-                                            TiffSelectedPages  *pages);
-
-static gint32             load_image       (const gchar        *filename,
-                                            TIFF               *tif,
-                                            TiffSelectedPages  *pages,
-                                            gboolean           *resolution_loaded,
-                                            GError            **error);
-
-static GimpColorProfile * load_profile     (TIFF               *tif);
-
-static void               load_rgba        (TIFF               *tif,
-                                            ChannelData        *channel);
-static void               load_contiguous  (TIFF               *tif,
-                                            ChannelData        *channel,
-                                            const Babl         *type,
-                                            gushort             bps,
-                                            gushort             spp,
-                                            gboolean            is_bw,
-                                            gint                extra);
-static void               load_separate    (TIFF               *tif,
-                                            ChannelData        *channel,
-                                            const Babl         *type,
-                                            gushort             bps,
-                                            gushort             spp,
-                                            gboolean            is_bw,
-                                            gint                extra);
-static void               load_paths       (TIFF               *tif,
-                                            gint                image);
-
-static void               tiff_warning     (const gchar        *module,
-                                            const gchar        *fmt,
-                                            va_list             ap) G_GNUC_PRINTF (2, 0);
-static void               tiff_error       (const gchar        *module,
-                                            const gchar        *fmt,
-                                            va_list             ap) G_GNUC_PRINTF (2, 0);
-static TIFF             * tiff_open        (const gchar        *filename,
-                                            const gchar        *mode,
-                                            GError            **error);
+/* Declare some local functions */
+
+static GimpColorProfile * load_profile     (TIFF         *tif);
+
+static void               load_rgba        (TIFF         *tif,
+                                            ChannelData  *channel);
+static void               load_contiguous  (TIFF         *tif,
+                                            ChannelData  *channel,
+                                            const Babl   *type,
+                                            gushort       bps,
+                                            gushort       spp,
+                                            gboolean      is_bw,
+                                            gint          extra);
+static void               load_separate    (TIFF         *tif,
+                                            ChannelData  *channel,
+                                            const Babl   *type,
+                                            gushort       bps,
+                                            gushort       spp,
+                                            gboolean      is_bw,
+                                            gint          extra);
+static void               load_paths       (TIFF         *tif,
+                                            gint          image);
 
 static void               fill_bit2byte    (void);
-static void               convert_bit2byte (const guchar       *src,
-                                            guchar             *dest,
-                                            gint                width,
-                                            gint                height);
+static void               convert_bit2byte (const guchar *src,
+                                            guchar       *dest,
+                                            gint          width,
+                                            gint          height);
 
 
-const GimpPlugInInfo PLUG_IN_INFO =
-{
-  NULL,  /* init_proc  */
-  NULL,  /* quit_proc  */
-  query, /* query_proc */
-  run,   /* run_proc   */
-};
-
 static TiffSaveVals tsvals =
 {
   COMPRESSION_NONE,    /*  compression    */
   TRUE,                /*  alpha handling */
 };
 
-static GimpPageSelectorTarget target = GIMP_PAGE_SELECTOR_TARGET_LAYERS;
-
-
-MAIN ()
-
-static void
-query (void)
-{
-  static const GimpParamDef load_args[] =
-  {
-    { GIMP_PDB_INT32,  "run-mode",     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
-    { GIMP_PDB_STRING, "filename",     "The name of the file to load" },
-    { GIMP_PDB_STRING, "raw-filename", "The name of the file to load" }
-  };
-  static const GimpParamDef load_return_vals[] =
-  {
-    { GIMP_PDB_IMAGE, "image", "Output image" }
-  };
-
-  gimp_install_procedure (LOAD_PROC,
-                          "loads files of the tiff file format",
-                          "FIXME: write help for tiff_load",
-                          "Spencer Kimball, Peter Mattis & Nick Lamb",
-                          "Nick Lamb <njl195 zepler org uk>",
-                          "1995-1996,1998-2003",
-                          N_("TIFF image"),
-                          NULL,
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (load_args),
-                          G_N_ELEMENTS (load_return_vals),
-                          load_args, load_return_vals);
-
-  gimp_register_file_handler_mime (LOAD_PROC, "image/tiff");
-  gimp_register_magic_load_handler (LOAD_PROC,
-                                    "tif,tiff",
-                                    "",
-                                    "0,string,II*\\0,0,string,MM\\0*");
-}
-
-static void
-run (const gchar      *name,
-     gint              nparams,
-     const GimpParam  *param,
-     gint             *nreturn_vals,
-     GimpParam       **return_vals)
-{
-  static GimpParam   values[2];
-  GimpRunMode        run_mode;
-  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
-  GError            *error  = NULL;
-
-  INIT_I18N ();
-  gegl_init (NULL, NULL);
-
-  run_mode = param[0].data.d_int32;
-
-  *nreturn_vals = 1;
-  *return_vals  = values;
-
-  values[0].type          = GIMP_PDB_STATUS;
-  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
-
-  TIFFSetWarningHandler (tiff_warning);
-  TIFFSetErrorHandler (tiff_error);
-
-  if (strcmp (name, LOAD_PROC) == 0)
-    {
-      const gchar *filename = param[1].data.d_string;
-      TIFF        *tif;
-
-      tif = tiff_open (filename, "r", &error);
-
-      if (tif)
-        {
-          TiffSelectedPages pages;
-
-          gimp_get_data (LOAD_PROC, &target);
-
-          pages.n_pages = pages.o_pages = TIFFNumberOfDirectories (tif);
-
-          if (pages.n_pages == 0)
-            {
-              g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                           _("TIFF '%s' does not contain any directories"),
-                           gimp_filename_to_utf8 (filename));
-
-              status = GIMP_PDB_EXECUTION_ERROR;
-            }
-          else
-            {
-              gboolean run_it = FALSE;
-              gint     i;
-
-              if (run_mode != GIMP_RUN_INTERACTIVE)
-                {
-                  pages.pages = g_new (gint, pages.n_pages);
-
-                  for (i = 0; i < pages.n_pages; i++)
-                    pages.pages[i] = i;
-
-                  run_it = TRUE;
-                }
-              else
-                {
-                  gimp_ui_init (PLUG_IN_BINARY, FALSE);
-                }
-
-              if (pages.n_pages == 1)
-                {
-                  target = GIMP_PAGE_SELECTOR_TARGET_LAYERS;
-                  pages.pages = g_new0 (gint, pages.n_pages);
-
-                  run_it = TRUE;
-                }
-
-              if ((! run_it) && (run_mode == GIMP_RUN_INTERACTIVE))
-                run_it = load_dialog (tif, &pages);
-
-              if (run_it)
-                {
-                  gint32   image;
-                  gboolean resolution_loaded = FALSE;
-
-                  gimp_set_data (LOAD_PROC, &target, sizeof (target));
-
-                  image = load_image (param[1].data.d_string, tif, &pages,
-                                      &resolution_loaded,
-                                      &error);
-
-                  g_free (pages.pages);
-
-                  if (image > 0)
-                    {
-                      GFile        *file;
-                      GimpMetadata *metadata;
-
-                      file = g_file_new_for_path (param[1].data.d_string);
-
-                      metadata = gimp_image_metadata_load_prepare (image,
-                                                                   "image/tiff",
-                                                                   file, NULL);
-
-                      if (metadata)
-                        {
-                          GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL;
-
-                          if (resolution_loaded)
-                            flags &= ~GIMP_METADATA_LOAD_RESOLUTION;
-
-                          gimp_image_metadata_load_finish (image, "image/tiff",
-                                                           metadata, flags,
-                                                           run_mode == GIMP_RUN_INTERACTIVE);
-
-                          g_object_unref (metadata);
-                        }
-
-                      g_object_unref (file);
-
-                      *nreturn_vals = 2;
-                      values[1].type         = GIMP_PDB_IMAGE;
-                      values[1].data.d_image = image;
-                    }
-                  else
-                    {
-                      status = GIMP_PDB_EXECUTION_ERROR;
-                    }
-                }
-              else
-                {
-                  status = GIMP_PDB_CANCEL;
-                }
-            }
-
-          TIFFClose (tif);
-        }
-      else
-        {
-          status = GIMP_PDB_EXECUTION_ERROR;
-        }
-    }
-  else
-    {
-      status = GIMP_PDB_CALLING_ERROR;
-    }
-
-  if (status != GIMP_PDB_SUCCESS && error)
-    {
-      *nreturn_vals = 2;
-      values[1].type          = GIMP_PDB_STRING;
-      values[1].data.d_string = error->message;
-    }
-
-  values[0].data.d_status = status;
-}
-
-static void
-tiff_warning (const gchar *module,
-              const gchar *fmt,
-              va_list      ap)
-{
-  int tag = 0;
-
-  if (! strcmp (fmt, "%s: unknown field with tag %d (0x%x) encountered"))
-    {
-      va_list ap_test;
-
-      G_VA_COPY (ap_test, ap);
-
-      va_arg (ap_test, const char *); /* ignore first arg */
-
-      tag  = va_arg (ap_test, int);
-    }
-  /* for older versions of libtiff? */
-  else if (! strcmp (fmt, "unknown field with tag %d (0x%x) ignored"))
-    {
-      va_list ap_test;
-
-      G_VA_COPY (ap_test, ap);
-
-      tag = va_arg (ap_test, int);
-    }
-
-  /* Workaround for: http://bugzilla.gnome.org/show_bug.cgi?id=131975
-   * Ignore the warnings about unregistered private tags (>= 32768).
-   */
-  if (tag >= 32768)
-    return;
-
-  /* Other unknown fields are only reported to stderr. */
-  if (tag > 0)
-    {
-      gchar *msg = g_strdup_vprintf (fmt, ap);
-
-      g_printerr ("%s\n", msg);
-      g_free (msg);
-
-      return;
-    }
-
-  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
-}
-
-static void
-tiff_error (const gchar *module,
-            const gchar *fmt,
-            va_list      ap)
-{
-  /* Workaround for: http://bugzilla.gnome.org/show_bug.cgi?id=132297
-   * Ignore the errors related to random access and JPEG compression
-   */
-  if (! strcmp (fmt, "Compression algorithm does not support random access"))
-    return;
-
-  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
-}
-
-static TIFF *
-tiff_open (const gchar  *filename,
-           const gchar  *mode,
-           GError      **error)
-{
-#ifdef G_OS_WIN32
-  gunichar2 *utf16_filename = g_utf8_to_utf16 (filename, -1, NULL, NULL, error);
-
-  if (utf16_filename)
-    {
-      TIFF *tif = TIFFOpenW (utf16_filename, mode);
-
-      g_free (utf16_filename);
-
-      return tif;
-    }
-
-  return NULL;
-#else
-  return TIFFOpen (filename, mode);
-#endif
-}
 
 /* returns a pointer into the TIFF */
 static const gchar *
@@ -448,8 +129,9 @@ tiff_get_page_name (TIFF *tif)
   return NULL;
 }
 
-static gboolean
+gboolean
 load_dialog (TIFF              *tif,
+             const gchar       *help_id,
              TiffSelectedPages *pages)
 {
   GtkWidget  *dialog;
@@ -460,7 +142,7 @@ load_dialog (TIFF              *tif,
 
   dialog = gimp_dialog_new (_("Import from TIFF"), PLUG_IN_ROLE,
                             NULL, 0,
-                            gimp_standard_help_func, LOAD_PROC,
+                            gimp_standard_help_func, help_id,
 
                             GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                             _("_Import"),     GTK_RESPONSE_OK,
@@ -487,7 +169,7 @@ load_dialog (TIFF              *tif,
 
   gimp_page_selector_set_n_pages (GIMP_PAGE_SELECTOR (selector),
                                   pages->n_pages);
-  gimp_page_selector_set_target (GIMP_PAGE_SELECTOR (selector), target);
+  gimp_page_selector_set_target (GIMP_PAGE_SELECTOR (selector), pages->target);
 
   for (i = 0; i < pages->n_pages; i++)
     {
@@ -513,26 +195,29 @@ load_dialog (TIFF              *tif,
   run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
 
   if (run)
-    target = gimp_page_selector_get_target (GIMP_PAGE_SELECTOR (selector));
-
-  pages->pages =
-    gimp_page_selector_get_selected_pages (GIMP_PAGE_SELECTOR (selector),
-                                           &pages->n_pages);
-
-  /* select all if none selected */
-  if (pages->n_pages == 0)
     {
-      gimp_page_selector_select_all (GIMP_PAGE_SELECTOR (selector));
+      pages->target =
+        gimp_page_selector_get_target (GIMP_PAGE_SELECTOR (selector));
 
       pages->pages =
         gimp_page_selector_get_selected_pages (GIMP_PAGE_SELECTOR (selector),
                                                &pages->n_pages);
+
+      /* select all if none selected */
+      if (pages->n_pages == 0)
+        {
+          gimp_page_selector_select_all (GIMP_PAGE_SELECTOR (selector));
+
+          pages->pages =
+            gimp_page_selector_get_selected_pages (GIMP_PAGE_SELECTOR (selector),
+                                                   &pages->n_pages);
+        }
     }
 
   return run;
 }
 
-static gint32
+gint32
 load_image (const gchar        *filename,
             TIFF               *tif,
             TiffSelectedPages  *pages,
@@ -991,7 +676,7 @@ load_image (const gchar        *filename,
             }
         }
 
-      if (target == GIMP_PAGE_SELECTOR_TARGET_LAYERS)
+      if (pages->target == GIMP_PAGE_SELECTOR_TARGET_LAYERS)
         {
           if (li == 0)
             {
@@ -1003,7 +688,7 @@ load_image (const gchar        *filename,
             }
         }
 
-      if ((target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) || (! image))
+      if ((pages->target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) || (! image))
         {
           image = gimp_image_new_with_precision (cols, rows, image_type,
                                                  image_precision);
@@ -1017,7 +702,7 @@ load_image (const gchar        *filename,
 
           gimp_image_undo_disable (image);
 
-          if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
+          if (pages->target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
             {
               gchar *fname = g_strdup_printf ("%s-%d", filename, ilayer);
 
@@ -1367,7 +1052,7 @@ load_image (const gchar        *filename,
 
       gimp_image_insert_layer (image, layer, -1, -1);
 
-      if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
+      if (pages->target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
         {
           gimp_image_undo_enable (image);
           gimp_image_clean_all (image);
@@ -1376,7 +1061,7 @@ load_image (const gchar        *filename,
       gimp_progress_update (1.0);
     }
 
-  if (target != GIMP_PAGE_SELECTOR_TARGET_IMAGES)
+  if (pages->target != GIMP_PAGE_SELECTOR_TARGET_IMAGES)
     {
       /* resize image to bounding box of all layers */
       gimp_image_resize (image,
diff --git a/plug-ins/file-tiff/file-tiff-load.h b/plug-ins/file-tiff/file-tiff-load.h
new file mode 100644
index 0000000..fb4b2b6
--- /dev/null
+++ b/plug-ins/file-tiff/file-tiff-load.h
@@ -0,0 +1,46 @@
+/* tiff loading for GIMP
+ *  -Peter Mattis
+ *
+ * The TIFF loading code has been completely revamped by Nick Lamb
+ * njl195 zepler org uk -- 18 May 1998
+ * And it now gains support for tiles (and doubtless a zillion bugs)
+ * njl195 zepler org uk -- 12 June 1999
+ * LZW patent fuss continues :(
+ * njl195 zepler org uk -- 20 April 2000
+ * The code for this filter is based on "tifftopnm" and "pnmtotiff",
+ *  2 programs that are a part of the netpbm package.
+ * khk khk net -- 13 May 2000
+ * Added support for ICCPROFILE tiff tag. If this tag is present in a
+ * TIFF file, then a parasite is created and vice versa.
+ * peter kirchgessner net -- 29 Oct 2002
+ * Progress bar only when run interactive
+ * Added support for layer offsets - pablo dangelo web de -- 7 Jan 2004
+ * Honor EXTRASAMPLES tag while loading images with alphachannel
+ * pablo dangelo web de -- 16 Jan 2004
+ */
+
+#ifndef __FILE_TIFF_LOAD_H__
+#define __FILE_TIFF_LOAD_H__
+
+
+typedef struct
+{
+  gint                    o_pages;
+  gint                    n_pages;
+  gint                   *pages;
+  GimpPageSelectorTarget  target;
+} TiffSelectedPages;
+
+
+gboolean   load_dialog (TIFF               *tif,
+                        const gchar        *help_id,
+                        TiffSelectedPages  *pages);
+
+gint32     load_image  (const gchar        *filename,
+                        TIFF               *tif,
+                        TiffSelectedPages  *pages,
+                        gboolean           *resolution_loaded,
+                        GError            **error);
+
+
+#endif /* __FILE_TIFF_LOAD_H__ */
diff --git a/plug-ins/file-tiff/file-tiff-save.c b/plug-ins/file-tiff/file-tiff-save.c
index c894d84..4ef6a86 100644
--- a/plug-ins/file-tiff/file-tiff-save.c
+++ b/plug-ins/file-tiff/file-tiff-save.c
@@ -52,469 +52,26 @@
 #include <libgimp/gimp.h>
 #include <libgimp/gimpui.h>
 
-#include "libgimp/stdplugins-intl.h"
-
-
-#define SAVE_PROC      "file-tiff-save"
-#define SAVE2_PROC     "file-tiff-save2"
-#define PLUG_IN_BINARY "file-tiff-save"
-#define PLUG_IN_ROLE   "gimp-file-tiff-save"
-
-
-typedef struct
-{
-  gint      compression;
-  gint      fillorder;
-  gboolean  save_transp_pixels;
-  gboolean  save_exif;
-  gboolean  save_xmp;
-  gboolean  save_iptc;
-  gboolean  save_thumbnail;
-} TiffSaveVals;
-
-typedef struct
-{
-  gint32        ID;
-  GimpDrawable *drawable;
-  GimpPixelRgn  pixel_rgn;
-  guchar       *pixels;
-  guchar       *pixel;
-} channel_data;
-
-
-/* Declare some local functions.
- */
-static void      query                  (void);
-static void      run                    (const gchar      *name,
-                                         gint              nparams,
-                                         const GimpParam  *param,
-                                         gint             *nreturn_vals,
-                                         GimpParam       **return_vals);
-
-static gboolean  image_is_monochrome    (gint32            image);
-
-static gboolean  save_paths             (TIFF             *tif,
-                                         gint32            image);
-static gboolean  save_image             (const gchar      *filename,
-                                         gint32            image,
-                                         gint32            drawable,
-                                         gint32            orig_image,
-                                         gint             *saved_bpp,
-                                         GError          **error);
-
-static gboolean  save_dialog            (gboolean          has_alpha,
-                                         gboolean          is_monochrome,
-                                         gboolean          is_indexed);
-
-static void      comment_entry_callback (GtkWidget        *widget,
-                                         gpointer          data);
-
-static void      byte2bit               (const guchar     *byteline,
-                                         gint              width,
-                                         guchar           *bitline,
-                                         gboolean          invert);
-
-static void      tiff_warning           (const gchar      *module,
-                                         const gchar      *fmt,
-                                         va_list           ap) G_GNUC_PRINTF (2, 0);
-static void      tiff_error             (const gchar      *module,
-                                         const gchar      *fmt,
-                                         va_list           ap) G_GNUC_PRINTF (2, 0);
-static TIFF    * tiff_open              (const gchar      *filename,
-                                         const gchar      *mode,
-                                         GError          **error);
-
-
-const GimpPlugInInfo PLUG_IN_INFO =
-{
-  NULL,  /* init_proc  */
-  NULL,  /* quit_proc  */
-  query, /* query_proc */
-  run,   /* run_proc   */
-};
-
-static TiffSaveVals tsvals =
-{
-  COMPRESSION_NONE,    /*  compression         */
-  TRUE,                /*  alpha handling      */
-  TRUE,                /*  save transp. pixels */
-  TRUE,                /*  save exif           */
-  TRUE,                /*  save xmp            */
-  TRUE,                /*  save iptc           */
-  TRUE                 /*  save thumbnail      */
-};
-
-static gchar *image_comment = NULL;
-
-
-MAIN ()
-
-static void
-query (void)
-{
-#define COMMON_SAVE_ARGS \
-    { GIMP_PDB_INT32,    "run-mode",     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },\
-    { GIMP_PDB_IMAGE,    "image",        "Input image" },\
-    { GIMP_PDB_DRAWABLE, "drawable",     "Drawable to save" },\
-    { GIMP_PDB_STRING,   "filename",     "The name of the file to save the image in" },\
-    { GIMP_PDB_STRING,   "raw-filename", "The name of the file to save the image in" },\
-    { GIMP_PDB_INT32,    "compression",  "Compression type: { NONE (0), LZW (1), PACKBITS (2), DEFLATE (3), 
JPEG (4), CCITT G3 Fax (5), CCITT G4 Fax (6) }" }
-
-  static const GimpParamDef save_args_old[] =
-  {
-    COMMON_SAVE_ARGS
-  };
-
-  static const GimpParamDef save_args[] =
-  {
-    COMMON_SAVE_ARGS,
-    { GIMP_PDB_INT32, "save-transp-pixels", "Keep the color data masked by an alpha channel intact" }
-  };
-
-  gimp_install_procedure (SAVE_PROC,
-                          "saves files in the tiff file format",
-                          "Saves files in the Tagged Image File Format.  "
-                          "The value for the saved comment is taken "
-                          "from the 'gimp-comment' parasite.",
-                          "Spencer Kimball & Peter Mattis",
-                          "Spencer Kimball & Peter Mattis",
-                          "1995-1996,2000-2003",
-                          N_("TIFF image"),
-                          "RGB*, GRAY*, INDEXED",
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (save_args_old), 0,
-                          save_args_old, NULL);
-
-  gimp_register_file_handler_mime (SAVE_PROC, "image/tiff");
-  gimp_register_save_handler (SAVE_PROC, "tif,tiff", "");
-
-  gimp_install_procedure (SAVE2_PROC,
-                          "saves files in the tiff file format",
-                          "Saves files in the Tagged Image File Format.  "
-                          "The value for the saved comment is taken "
-                          "from the 'gimp-comment' parasite.",
-                          "Spencer Kimball & Peter Mattis",
-                          "Spencer Kimball & Peter Mattis",
-                          "1995-1996,2000-2003",
-                          N_("TIFF image"),
-                          "RGB*, GRAY*, INDEXED",
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (save_args), 0,
-                          save_args, NULL);
-}
-
-static void
-run (const gchar      *name,
-     gint              nparams,
-     const GimpParam  *param,
-     gint             *nreturn_vals,
-     GimpParam       **return_vals)
-{
-  static GimpParam   values[2];
-  GimpRunMode        run_mode;
-  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
-  GError            *error  = NULL;
-
-  run_mode = param[0].data.d_int32;
-
-  INIT_I18N ();
-  gegl_init (NULL, NULL);
-
-  *nreturn_vals = 1;
-  *return_vals  = values;
-
-  values[0].type          = GIMP_PDB_STATUS;
-  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
-
-  TIFFSetWarningHandler (tiff_warning);
-  TIFFSetErrorHandler (tiff_error);
-
-  if ((strcmp (name, SAVE_PROC)  == 0) ||
-      (strcmp (name, SAVE2_PROC) == 0))
-    {
-      /* Plug-in is either file_tiff_save or file_tiff_save2 */
-
-      GimpMetadata          *metadata;
-      GimpMetadataSaveFlags  metadata_flags;
-      GimpParasite          *parasite;
-      gint32                 image      = param[1].data.d_int32;
-      gint32                 drawable   = param[2].data.d_int32;
-      gint32                 orig_image = image;
-      GimpExportReturn       export     = GIMP_EXPORT_CANCEL;
-
-      switch (run_mode)
-        {
-        case GIMP_RUN_INTERACTIVE:
-        case GIMP_RUN_WITH_LAST_VALS:
-          gimp_ui_init (PLUG_IN_BINARY, FALSE);
-
-          export = gimp_export_image (&image, &drawable, "TIFF",
-                                      GIMP_EXPORT_CAN_HANDLE_RGB     |
-                                      GIMP_EXPORT_CAN_HANDLE_GRAY    |
-                                      GIMP_EXPORT_CAN_HANDLE_INDEXED |
-                                      GIMP_EXPORT_CAN_HANDLE_ALPHA);
-
-          if (export == GIMP_EXPORT_CANCEL)
-            {
-              values[0].data.d_status = GIMP_PDB_CANCEL;
-              return;
-            }
-          break;
-        default:
-          break;
-        }
-
-      metadata = gimp_image_metadata_save_prepare (orig_image,
-                                                   "image/tiff",
-                                                   &metadata_flags);
-
-      tsvals.save_exif      = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
-      tsvals.save_xmp       = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
-      tsvals.save_iptc      = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
-      tsvals.save_thumbnail = (metadata_flags & GIMP_METADATA_SAVE_THUMBNAIL) != 0;
-
-      parasite = gimp_image_get_parasite (orig_image, "gimp-comment");
-      if (parasite)
-        {
-          image_comment = g_strndup (gimp_parasite_data (parasite),
-                                     gimp_parasite_data_size (parasite));
-          gimp_parasite_free (parasite);
-        }
-
-      switch (run_mode)
-        {
-        case GIMP_RUN_INTERACTIVE:
-          /*  Possibly retrieve data  */
-          gimp_get_data (SAVE_PROC, &tsvals);
-
-          parasite = gimp_image_get_parasite (orig_image, "tiff-save-options");
-          if (parasite)
-            {
-              const TiffSaveVals *pvals = gimp_parasite_data (parasite);
-
-              if (pvals->compression == COMPRESSION_DEFLATE)
-                tsvals.compression = COMPRESSION_ADOBE_DEFLATE;
-              else
-                tsvals.compression = pvals->compression;
-
-              tsvals.save_transp_pixels = pvals->save_transp_pixels;
-            }
-          gimp_parasite_free (parasite);
-
-          /*  First acquire information with a dialog  */
-          if (! save_dialog (gimp_drawable_has_alpha (drawable),
-                             image_is_monochrome (image),
-                             gimp_image_base_type (image) == GIMP_INDEXED))
-            status = GIMP_PDB_CANCEL;
-          break;
-
-        case GIMP_RUN_NONINTERACTIVE:
-          /*  Make sure all the arguments are there!  */
-          if (nparams == 6 || nparams == 7)
-            {
-              switch (param[5].data.d_int32)
-                {
-                case 0: tsvals.compression = COMPRESSION_NONE;          break;
-                case 1: tsvals.compression = COMPRESSION_LZW;           break;
-                case 2: tsvals.compression = COMPRESSION_PACKBITS;      break;
-                case 3: tsvals.compression = COMPRESSION_ADOBE_DEFLATE; break;
-                case 4: tsvals.compression = COMPRESSION_JPEG;          break;
-                case 5: tsvals.compression = COMPRESSION_CCITTFAX3;     break;
-                case 6: tsvals.compression = COMPRESSION_CCITTFAX4;     break;
-                default: status = GIMP_PDB_CALLING_ERROR; break;
-                }
-
-              if (nparams == 7)
-                tsvals.save_transp_pixels = param[6].data.d_int32;
-              else
-                tsvals.save_transp_pixels = TRUE;
-            }
-          else
-            {
-              status = GIMP_PDB_CALLING_ERROR;
-            }
-          break;
-
-        case GIMP_RUN_WITH_LAST_VALS:
-          /*  Possibly retrieve data  */
-          gimp_get_data (SAVE_PROC, &tsvals);
-
-          parasite = gimp_image_get_parasite (orig_image, "tiff-save-options");
-          if (parasite)
-            {
-              const TiffSaveVals *pvals = gimp_parasite_data (parasite);
+#include "file-tiff-io.h"
+#include "file-tiff-save.h"
 
-              tsvals.compression        = pvals->compression;
-              tsvals.save_transp_pixels = pvals->save_transp_pixels;
-            }
-          gimp_parasite_free (parasite);
-          break;
-
-        default:
-          break;
-        }
-
-      if (status == GIMP_PDB_SUCCESS)
-        {
-          gint saved_bpp;
-
-          if (save_image (param[3].data.d_string, image, drawable, orig_image,
-                          &saved_bpp, &error))
-            {
-              if (metadata)
-                {
-                  GFile *file;
-
-                  gimp_metadata_set_bits_per_sample (metadata, saved_bpp);
-
-                  if (tsvals.save_exif)
-                    metadata_flags |= GIMP_METADATA_SAVE_EXIF;
-                  else
-                    metadata_flags &= ~GIMP_METADATA_SAVE_EXIF;
-
-                  if (tsvals.save_xmp)
-                    metadata_flags |= GIMP_METADATA_SAVE_XMP;
-                  else
-                    metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
-
-                  if (tsvals.save_iptc)
-                    metadata_flags |= GIMP_METADATA_SAVE_IPTC;
-                  else
-                    metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
-
-                  /* never save metadata thumbnails for TIFF, see bug #729952 */
-                  metadata_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL;
-
-                  file = g_file_new_for_path (param[3].data.d_string);
-                  gimp_image_metadata_save_finish (image,
-                                                   "image/tiff",
-                                                   metadata, metadata_flags,
-                                                   file, NULL);
-                  g_object_unref (file);
-                }
-
-              /*  Store mvals data  */
-              gimp_set_data (SAVE_PROC, &tsvals, sizeof (TiffSaveVals));
-            }
-          else
-            {
-              status = GIMP_PDB_EXECUTION_ERROR;
-            }
-        }
-
-      if (export == GIMP_EXPORT_EXPORT)
-        gimp_image_delete (image);
-
-      if (metadata)
-        g_object_unref (metadata);
-    }
-  else
-    {
-      status = GIMP_PDB_CALLING_ERROR;
-    }
-
-  if (status != GIMP_PDB_SUCCESS && error)
-    {
-      *nreturn_vals = 2;
-      values[1].type          = GIMP_PDB_STRING;
-      values[1].data.d_string = error->message;
-    }
-
-  values[0].data.d_status = status;
-}
-
-static void
-tiff_warning (const gchar *module,
-              const gchar *fmt,
-              va_list      ap)
-{
-  va_list ap_test;
-
-  /* Workaround for: http://bugzilla.gnome.org/show_bug.cgi?id=131975 */
-  /* Ignore the warnings about unregistered private tags (>= 32768) */
-  if (! strcmp (fmt, "%s: unknown field with tag %d (0x%x) encountered"))
-    {
-      G_VA_COPY (ap_test, ap);
-      if (va_arg (ap_test, char *));  /* ignore first argument */
-      if (va_arg (ap_test, int) >= 32768)
-        return;
-    }
-  /* for older versions of libtiff? */
-  else if (! strcmp (fmt, "unknown field with tag %d (0x%x) ignored"))
-    {
-      G_VA_COPY (ap_test, ap);
-      if (va_arg (ap_test, int) >= 32768)
-        return;
-    }
-
-  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
-}
-
-static void
-tiff_error (const gchar *module,
-            const gchar *fmt,
-            va_list      ap)
-{
-  /* Workaround for: http://bugzilla.gnome.org/show_bug.cgi?id=132297 */
-  /* Ignore the errors related to random access and JPEG compression */
-  if (! strcmp (fmt, "Compression algorithm does not support random access"))
-    return;
-  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
-}
-
-static TIFF *
-tiff_open (const gchar  *filename,
-           const gchar  *mode,
-           GError      **error)
-{
-#ifdef G_OS_WIN32
-  gunichar2 *utf16_filename = g_utf8_to_utf16 (filename, -1, NULL, NULL, error);
-
-  if (utf16_filename)
-    {
-      TIFF *tif = TIFFOpenW (utf16_filename, mode);
-
-      g_free (utf16_filename);
-
-      return tif;
-    }
-
-  return NULL;
-#else
-  return TIFFOpen (filename, mode);
-#endif
-}
+#include "libgimp/stdplugins-intl.h"
 
-static gboolean
-image_is_monochrome (gint32 image)
-{
-  guchar   *colors;
-  gint      num_colors;
-  gboolean  monochrome = FALSE;
 
-  g_return_val_if_fail (image != -1, FALSE);
+#define PLUG_IN_ROLE "gimp-file-tiff-save"
 
-  colors = gimp_image_get_colormap (image, &num_colors);
 
-  if (colors)
-    {
-      if (num_colors == 2 || num_colors == 1)
-        {
-          const guchar  bw_map[] = { 0, 0, 0, 255, 255, 255 };
-          const guchar  wb_map[] = { 255, 255, 255, 0, 0, 0 };
+static gboolean  save_paths             (TIFF          *tif,
+                                         gint32         image);
 
-          if (memcmp (colors, bw_map, 3 * num_colors) == 0 ||
-              memcmp (colors, wb_map, 3 * num_colors) == 0)
-            {
-              monochrome = TRUE;
-            }
-        }
+static void      comment_entry_callback (GtkWidget     *widget,
+                                         gchar        **comment);
 
-      g_free (colors);
-    }
+static void      byte2bit               (const guchar  *byteline,
+                                         gint           width,
+                                         guchar        *bitline,
+                                         gboolean       invert);
 
-  return monochrome;
-}
 
 static void
 double_to_psd_fixed (gdouble  value,
@@ -697,11 +254,13 @@ save_paths (TIFF   *tif,
  * other special, indirect and consequential damages.
  */
 
-static gboolean
+gboolean
 save_image (const gchar  *filename,
+            TiffSaveVals *tsvals,
             gint32        image,
             gint32        layer,
             gint32        orig_image,  /* the export function might have */
+            const gchar  *image_comment,
             gint         *saved_bpp,
             GError      **error)       /* created a duplicate            */
 {
@@ -739,7 +298,7 @@ save_image (const gchar  *filename,
   gint           number_of_sub_IFDs = 1;
   toff_t         sub_IFDs_offsets[1] = { 0UL };
 
-  compression = tsvals.compression;
+  compression = tsvals->compression;
 
   /* Disabled because this isn't in older releases of libtiff, and it
      wasn't helping much anyway */
@@ -752,9 +311,6 @@ save_image (const gchar  *filename,
   tile_height = gimp_tile_height ();
   rowsperstrip = tile_height;
 
-  TIFFSetWarningHandler (tiff_warning);
-  TIFFSetErrorHandler (tiff_error);
-
   gimp_progress_init_printf (_("Saving '%s'"),
                              gimp_filename_to_utf8 (filename));
 
@@ -835,7 +391,7 @@ save_image (const gchar  *filename,
       samplesperpixel = 4;
       photometric     = PHOTOMETRIC_RGB;
       alpha           = TRUE;
-      if (tsvals.save_transp_pixels)
+      if (tsvals->save_transp_pixels)
         {
           format = babl_format_new (babl_model ("R'G'B'A"),
                                     type,
@@ -861,7 +417,7 @@ save_image (const gchar  *filename,
       samplesperpixel = 2;
       photometric     = PHOTOMETRIC_MINISBLACK;
       alpha           = TRUE;
-      if (tsvals.save_transp_pixels)
+      if (tsvals->save_transp_pixels)
         {
           format = babl_format_new (babl_model ("Y'A"),
                                     type,
@@ -986,7 +542,7 @@ save_image (const gchar  *filename,
 
   if (alpha)
     {
-      if (tsvals.save_transp_pixels)
+      if (tsvals->save_transp_pixels)
         extra_samples [0] = EXTRASAMPLE_UNASSALPHA;
       else
         extra_samples [0] = EXTRASAMPLE_ASSOCALPHA;
@@ -1050,8 +606,6 @@ save_image (const gchar  *filename,
             {
               g_message (_("The TIFF format only supports comments in\n"
                            "7bit ASCII encoding. No comment is saved."));
-
-              g_free (image_comment);
               image_comment = NULL;
 
               break;
@@ -1168,7 +722,7 @@ save_image (const gchar  *filename,
    * Exif saves the thumbnail as a second page. To avoid this, the
    * thumbnail must be saved with the functions of libtiff.
    */
-  if (tsvals.save_thumbnail)
+  if (tsvals->save_thumbnail)
     {
       GdkPixbuf *thumb_pixbuf;
       guchar    *thumb_pixels;
@@ -1252,10 +806,13 @@ save_image (const gchar  *filename,
   return status;
 }
 
-static gboolean
-save_dialog (gboolean has_alpha,
-             gboolean is_monochrome,
-             gboolean is_indexed)
+gboolean
+save_dialog (TiffSaveVals  *tsvals,
+             const gchar   *help_id,
+             gboolean       has_alpha,
+             gboolean       is_monochrome,
+             gboolean       is_indexed,
+             gchar        **image_comment)
 {
   GError      *error = NULL;
   GtkWidget   *dialog;
@@ -1270,7 +827,7 @@ save_dialog (gboolean has_alpha,
   gchar       *ui_file;
   gboolean     run;
 
-  dialog = gimp_export_dialog_new (_("TIFF"), PLUG_IN_BINARY, SAVE_PROC);
+  dialog = gimp_export_dialog_new (_("TIFF"), PLUG_IN_ROLE, help_id);
 
   builder = gtk_builder_new ();
   ui_file = g_build_filename (gimp_data_directory (),
@@ -1298,7 +855,7 @@ save_dialog (gboolean has_alpha,
 
   frame = gimp_int_radio_group_new (TRUE, _("Compression"),
                                     G_CALLBACK (gimp_radio_button_update),
-                                    &tsvals.compression, tsvals.compression,
+                                    &tsvals->compression, tsvals->compression,
 
                                     _("_None"),      COMPRESSION_NONE,          NULL,
                                     _("_LZW"),       COMPRESSION_LZW,           NULL,
@@ -1316,15 +873,15 @@ save_dialog (gboolean has_alpha,
 
   if (! is_monochrome)
     {
-      if (tsvals.compression == COMPRESSION_CCITTFAX3 ||
-          tsvals.compression == COMPRESSION_CCITTFAX4)
+      if (tsvals->compression == COMPRESSION_CCITTFAX3 ||
+          tsvals->compression == COMPRESSION_CCITTFAX4)
         {
           gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (cmp_g3),
                                            COMPRESSION_NONE);
         }
     }
 
-  if (is_indexed && tsvals.compression == COMPRESSION_JPEG)
+  if (is_indexed && tsvals->compression == COMPRESSION_JPEG)
     {
       gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (cmp_jpeg),
                                        COMPRESSION_NONE);
@@ -1335,46 +892,46 @@ save_dialog (gboolean has_alpha,
 
   toggle = GTK_WIDGET (gtk_builder_get_object (builder, "sv_alpha"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
-                                has_alpha && tsvals.save_transp_pixels);
+                                has_alpha && tsvals->save_transp_pixels);
   gtk_widget_set_sensitive (toggle, has_alpha);
   g_signal_connect (toggle, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
-                    &tsvals.save_transp_pixels);
+                    &tsvals->save_transp_pixels);
 
   entry = GTK_WIDGET (gtk_builder_get_object (builder, "commentfield"));
-  gtk_entry_set_text (GTK_ENTRY (entry), image_comment ? image_comment : "");
+  gtk_entry_set_text (GTK_ENTRY (entry), *image_comment ? *image_comment : "");
 
   g_signal_connect (entry, "changed",
                     G_CALLBACK (comment_entry_callback),
-                    NULL);
+                    image_comment);
 
   toggle = GTK_WIDGET (gtk_builder_get_object (builder, "sv_exif"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
-                                tsvals.save_exif);
+                                tsvals->save_exif);
   g_signal_connect (toggle, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
-                    &tsvals.save_exif);
+                    &tsvals->save_exif);
 
   toggle = GTK_WIDGET (gtk_builder_get_object (builder, "sv_xmp"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
-                                tsvals.save_xmp);
+                                tsvals->save_xmp);
   g_signal_connect (toggle, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
-                    &tsvals.save_xmp);
+                    &tsvals->save_xmp);
 
   toggle = GTK_WIDGET (gtk_builder_get_object (builder, "sv_iptc"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
-                                tsvals.save_iptc);
+                                tsvals->save_iptc);
   g_signal_connect (toggle, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
-                    &tsvals.save_iptc);
+                    &tsvals->save_iptc);
 
   toggle = GTK_WIDGET (gtk_builder_get_object (builder, "sv_thumbnail"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
-                                tsvals.save_thumbnail);
+                                tsvals->save_thumbnail);
   g_signal_connect (toggle, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
-                    &tsvals.save_thumbnail);
+                    &tsvals->save_thumbnail);
 
   gtk_widget_show (dialog);
 
@@ -1386,13 +943,13 @@ save_dialog (gboolean has_alpha,
 }
 
 static void
-comment_entry_callback (GtkWidget *widget,
-                        gpointer   data)
+comment_entry_callback (GtkWidget  *widget,
+                        gchar     **comment)
 {
   const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget));
 
-  g_free (image_comment);
-  image_comment = g_strdup (text);
+  g_free (*comment);
+  *comment = g_strdup (text);
 }
 
 /* Convert n bytes of 0/1 to a line of bits */
diff --git a/plug-ins/file-tiff/file-tiff-save.h b/plug-ins/file-tiff/file-tiff-save.h
new file mode 100644
index 0000000..e82a33a
--- /dev/null
+++ b/plug-ins/file-tiff/file-tiff-save.h
@@ -0,0 +1,55 @@
+/* tiff saving for GIMP
+ *  -Peter Mattis
+ *
+ * The TIFF loading code has been completely revamped by Nick Lamb
+ * njl195 zepler org uk -- 18 May 1998
+ * And it now gains support for tiles (and doubtless a zillion bugs)
+ * njl195 zepler org uk -- 12 June 1999
+ * LZW patent fuss continues :(
+ * njl195 zepler org uk -- 20 April 2000
+ * The code for this filter is based on "tifftopnm" and "pnmtotiff",
+ *  2 programs that are a part of the netpbm package.
+ * khk khk net -- 13 May 2000
+ * Added support for ICCPROFILE tiff tag. If this tag is present in a
+ * TIFF file, then a parasite is created and vice versa.
+ * peter kirchgessner net -- 29 Oct 2002
+ * Progress bar only when run interactive
+ * Added support for layer offsets - pablo dangelo web de -- 7 Jan 2004
+ * Honor EXTRASAMPLES tag while loading images with alphachannel
+ * pablo dangelo web de -- 16 Jan 2004
+ */
+
+#ifndef __FILE_TIFF_SAVE_H__
+#define __FILE_TIFF_SAVE_H__
+
+
+typedef struct
+{
+  gint      compression;
+  gint      fillorder;
+  gboolean  save_transp_pixels;
+  gboolean  save_exif;
+  gboolean  save_xmp;
+  gboolean  save_iptc;
+  gboolean  save_thumbnail;
+} TiffSaveVals;
+
+
+gboolean  save_image  (const gchar  *filename,
+                       TiffSaveVals *tsvals,
+                       gint32        image,
+                       gint32        drawable,
+                       gint32        orig_image,
+                       const gchar  *image_comment,
+                       gint         *saved_bpp,
+                       GError      **error);
+
+gboolean  save_dialog (TiffSaveVals *tsvals,
+                       const gchar  *help_id,
+                       gboolean      has_alpha,
+                       gboolean      is_monochrome,
+                       gboolean      is_indexed,
+                       gchar       **image_comment);
+
+
+#endif /* __FILE_TIFF_SAVE_H__ */
diff --git a/plug-ins/file-tiff/file-tiff.c b/plug-ins/file-tiff/file-tiff.c
new file mode 100644
index 0000000..66c31c5
--- /dev/null
+++ b/plug-ins/file-tiff/file-tiff.c
@@ -0,0 +1,554 @@
+/* tiff loading for GIMP
+ *  -Peter Mattis
+ *
+ * The TIFF loading code has been completely revamped by Nick Lamb
+ * njl195 zepler org uk -- 18 May 1998
+ * And it now gains support for tiles (and doubtless a zillion bugs)
+ * njl195 zepler org uk -- 12 June 1999
+ * LZW patent fuss continues :(
+ * njl195 zepler org uk -- 20 April 2000
+ * The code for this filter is based on "tifftopnm" and "pnmtotiff",
+ *  2 programs that are a part of the netpbm package.
+ * khk khk net -- 13 May 2000
+ * Added support for ICCPROFILE tiff tag. If this tag is present in a
+ * TIFF file, then a parasite is created and vice versa.
+ * peter kirchgessner net -- 29 Oct 2002
+ * Progress bar only when run interactive
+ * Added support for layer offsets - pablo dangelo web de -- 7 Jan 2004
+ * Honor EXTRASAMPLES tag while loading images with alphachannel
+ * pablo dangelo web de -- 16 Jan 2004
+ */
+
+/*
+ * tifftopnm.c - converts a Tagged Image File to a portable anymap
+ *
+ * Derived by Jef Poskanzer from tif2ras.c, which is:
+ *
+ * Copyright (c) 1990 by Sun Microsystems, Inc.
+ *
+ * Author: Patrick J. Naughton
+ * naughton wind sun com
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind.  The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof.  In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ */
+
+#include "config.h"
+
+#include <tiffio.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#include "file-tiff-io.h"
+#include "file-tiff-load.h"
+#include "file-tiff-save.h"
+
+#include "libgimp/stdplugins-intl.h"
+
+
+#define LOAD_PROC      "file-tiff-load"
+#define SAVE_PROC      "file-tiff-save"
+#define SAVE2_PROC     "file-tiff-save2"
+#define PLUG_IN_BINARY "file-tiff"
+
+
+static void       query               (void);
+static void       run                 (const gchar      *name,
+                                       gint              nparams,
+                                       const GimpParam  *param,
+                                       gint             *nreturn_vals,
+                                       GimpParam       **return_vals);
+
+static gboolean   image_is_monochrome (gint32            image);
+
+
+const GimpPlugInInfo PLUG_IN_INFO =
+{
+  NULL,  /* init_proc  */
+  NULL,  /* quit_proc  */
+  query, /* query_proc */
+  run,   /* run_proc   */
+};
+
+static TiffSaveVals tsvals =
+{
+  COMPRESSION_NONE,    /*  compression         */
+  TRUE,                /*  alpha handling      */
+  TRUE,                /*  save transp. pixels */
+  TRUE,                /*  save exif           */
+  TRUE,                /*  save xmp            */
+  TRUE,                /*  save iptc           */
+  TRUE                 /*  save thumbnail      */
+};
+
+static gchar *image_comment = NULL;
+
+
+MAIN ()
+
+
+static void
+query (void)
+{
+  static const GimpParamDef load_args[] =
+  {
+    { GIMP_PDB_INT32,  "run-mode",     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
+    { GIMP_PDB_STRING, "filename",     "The name of the file to load" },
+    { GIMP_PDB_STRING, "raw-filename", "The name of the file to load" }
+  };
+  static const GimpParamDef load_return_vals[] =
+  {
+    { GIMP_PDB_IMAGE, "image", "Output image" }
+  };
+
+#define COMMON_SAVE_ARGS \
+    { GIMP_PDB_INT32,    "run-mode",     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },\
+    { GIMP_PDB_IMAGE,    "image",        "Input image" },\
+    { GIMP_PDB_DRAWABLE, "drawable",     "Drawable to save" },\
+    { GIMP_PDB_STRING,   "filename",     "The name of the file to save the image in" },\
+    { GIMP_PDB_STRING,   "raw-filename", "The name of the file to save the image in" },\
+    { GIMP_PDB_INT32,    "compression",  "Compression type: { NONE (0), LZW (1), PACKBITS (2), DEFLATE (3), 
JPEG (4), CCITT G3 Fax (5), CCITT G4 Fax (6) }" }
+
+  static const GimpParamDef save_args_old[] =
+  {
+    COMMON_SAVE_ARGS
+  };
+
+  static const GimpParamDef save_args[] =
+  {
+    COMMON_SAVE_ARGS,
+    { GIMP_PDB_INT32, "save-transp-pixels", "Keep the color data masked by an alpha channel intact" }
+  };
+
+  gimp_install_procedure (LOAD_PROC,
+                          "loads files of the tiff file format",
+                          "FIXME: write help for tiff_load",
+                          "Spencer Kimball, Peter Mattis & Nick Lamb",
+                          "Nick Lamb <njl195 zepler org uk>",
+                          "1995-1996,1998-2003",
+                          N_("TIFF image"),
+                          NULL,
+                          GIMP_PLUGIN,
+                          G_N_ELEMENTS (load_args),
+                          G_N_ELEMENTS (load_return_vals),
+                          load_args, load_return_vals);
+
+  gimp_register_file_handler_mime (LOAD_PROC, "image/tiff");
+  gimp_register_magic_load_handler (LOAD_PROC,
+                                    "tif,tiff",
+                                    "",
+                                    "0,string,II*\\0,0,string,MM\\0*");
+
+  gimp_install_procedure (SAVE_PROC,
+                          "saves files in the tiff file format",
+                          "Saves files in the Tagged Image File Format.  "
+                          "The value for the saved comment is taken "
+                          "from the 'gimp-comment' parasite.",
+                          "Spencer Kimball & Peter Mattis",
+                          "Spencer Kimball & Peter Mattis",
+                          "1995-1996,2000-2003",
+                          N_("TIFF image"),
+                          "RGB*, GRAY*, INDEXED",
+                          GIMP_PLUGIN,
+                          G_N_ELEMENTS (save_args_old), 0,
+                          save_args_old, NULL);
+
+  gimp_register_file_handler_mime (SAVE_PROC, "image/tiff");
+  gimp_register_save_handler (SAVE_PROC, "tif,tiff", "");
+
+  gimp_install_procedure (SAVE2_PROC,
+                          "saves files in the tiff file format",
+                          "Saves files in the Tagged Image File Format.  "
+                          "The value for the saved comment is taken "
+                          "from the 'gimp-comment' parasite.",
+                          "Spencer Kimball & Peter Mattis",
+                          "Spencer Kimball & Peter Mattis",
+                          "1995-1996,2000-2003",
+                          N_("TIFF image"),
+                          "RGB*, GRAY*, INDEXED",
+                          GIMP_PLUGIN,
+                          G_N_ELEMENTS (save_args), 0,
+                          save_args, NULL);
+}
+
+static void
+run (const gchar      *name,
+     gint              nparams,
+     const GimpParam  *param,
+     gint             *nreturn_vals,
+     GimpParam       **return_vals)
+{
+  static GimpParam   values[2];
+  GimpRunMode        run_mode;
+  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
+  GError            *error  = NULL;
+
+  INIT_I18N ();
+  gegl_init (NULL, NULL);
+
+  run_mode = param[0].data.d_int32;
+
+  *nreturn_vals = 1;
+  *return_vals  = values;
+
+  values[0].type          = GIMP_PDB_STATUS;
+  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+
+  if (strcmp (name, LOAD_PROC) == 0)
+    {
+      const gchar *filename = param[1].data.d_string;
+      TIFF        *tif;
+
+      tif = tiff_open (filename, "r", &error);
+
+      if (tif)
+        {
+          TiffSelectedPages pages;
+
+          pages.target = GIMP_PAGE_SELECTOR_TARGET_LAYERS;
+
+          gimp_get_data (LOAD_PROC, &pages.target);
+
+          pages.n_pages = pages.o_pages = TIFFNumberOfDirectories (tif);
+
+          if (pages.n_pages == 0)
+            {
+              g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                           _("TIFF '%s' does not contain any directories"),
+                           gimp_filename_to_utf8 (filename));
+
+              status = GIMP_PDB_EXECUTION_ERROR;
+            }
+          else
+            {
+              gboolean run_it = FALSE;
+              gint     i;
+
+              if (run_mode != GIMP_RUN_INTERACTIVE)
+                {
+                  pages.pages = g_new (gint, pages.n_pages);
+
+                  for (i = 0; i < pages.n_pages; i++)
+                    pages.pages[i] = i;
+
+                  run_it = TRUE;
+                }
+              else
+                {
+                  gimp_ui_init (PLUG_IN_BINARY, FALSE);
+                }
+
+              if (pages.n_pages == 1)
+                {
+                  pages.pages  = g_new0 (gint, pages.n_pages);
+                  pages.target = GIMP_PAGE_SELECTOR_TARGET_LAYERS;
+
+                  run_it = TRUE;
+                }
+
+              if ((! run_it) && (run_mode == GIMP_RUN_INTERACTIVE))
+                run_it = load_dialog (tif, LOAD_PROC, &pages);
+
+              if (run_it)
+                {
+                  gint32   image;
+                  gboolean resolution_loaded = FALSE;
+
+                  gimp_set_data (LOAD_PROC,
+                                 &pages.target, sizeof (pages.target));
+
+                  image = load_image (param[1].data.d_string, tif, &pages,
+                                      &resolution_loaded,
+                                      &error);
+
+                  g_free (pages.pages);
+
+                  if (image > 0)
+                    {
+                      GFile        *file;
+                      GimpMetadata *metadata;
+
+                      file = g_file_new_for_path (param[1].data.d_string);
+
+                      metadata = gimp_image_metadata_load_prepare (image,
+                                                                   "image/tiff",
+                                                                   file, NULL);
+
+                      if (metadata)
+                        {
+                          GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL;
+
+                          if (resolution_loaded)
+                            flags &= ~GIMP_METADATA_LOAD_RESOLUTION;
+
+                          gimp_image_metadata_load_finish (image, "image/tiff",
+                                                           metadata, flags,
+                                                           run_mode == GIMP_RUN_INTERACTIVE);
+
+                          g_object_unref (metadata);
+                        }
+
+                      g_object_unref (file);
+
+                      *nreturn_vals = 2;
+                      values[1].type         = GIMP_PDB_IMAGE;
+                      values[1].data.d_image = image;
+                    }
+                  else
+                    {
+                      status = GIMP_PDB_EXECUTION_ERROR;
+                    }
+                }
+              else
+                {
+                  status = GIMP_PDB_CANCEL;
+                }
+            }
+
+          TIFFClose (tif);
+        }
+      else
+        {
+          status = GIMP_PDB_EXECUTION_ERROR;
+        }
+    }
+  else if ((strcmp (name, SAVE_PROC)  == 0) ||
+           (strcmp (name, SAVE2_PROC) == 0))
+    {
+      /* Plug-in is either file_tiff_save or file_tiff_save2 */
+
+      GimpMetadata          *metadata;
+      GimpMetadataSaveFlags  metadata_flags;
+      GimpParasite          *parasite;
+      gint32                 image      = param[1].data.d_int32;
+      gint32                 drawable   = param[2].data.d_int32;
+      gint32                 orig_image = image;
+      GimpExportReturn       export     = GIMP_EXPORT_CANCEL;
+
+      switch (run_mode)
+        {
+        case GIMP_RUN_INTERACTIVE:
+        case GIMP_RUN_WITH_LAST_VALS:
+          gimp_ui_init (PLUG_IN_BINARY, FALSE);
+
+          export = gimp_export_image (&image, &drawable, "TIFF",
+                                      GIMP_EXPORT_CAN_HANDLE_RGB     |
+                                      GIMP_EXPORT_CAN_HANDLE_GRAY    |
+                                      GIMP_EXPORT_CAN_HANDLE_INDEXED |
+                                      GIMP_EXPORT_CAN_HANDLE_ALPHA);
+
+          if (export == GIMP_EXPORT_CANCEL)
+            {
+              values[0].data.d_status = GIMP_PDB_CANCEL;
+              return;
+            }
+          break;
+        default:
+          break;
+        }
+
+      metadata = gimp_image_metadata_save_prepare (orig_image,
+                                                   "image/tiff",
+                                                   &metadata_flags);
+
+      tsvals.save_exif      = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
+      tsvals.save_xmp       = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
+      tsvals.save_iptc      = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
+      tsvals.save_thumbnail = (metadata_flags & GIMP_METADATA_SAVE_THUMBNAIL) != 0;
+
+      parasite = gimp_image_get_parasite (orig_image, "gimp-comment");
+      if (parasite)
+        {
+          image_comment = g_strndup (gimp_parasite_data (parasite),
+                                     gimp_parasite_data_size (parasite));
+          gimp_parasite_free (parasite);
+        }
+
+      switch (run_mode)
+        {
+        case GIMP_RUN_INTERACTIVE:
+          /*  Possibly retrieve data  */
+          gimp_get_data (SAVE_PROC, &tsvals);
+
+          parasite = gimp_image_get_parasite (orig_image, "tiff-save-options");
+          if (parasite)
+            {
+              const TiffSaveVals *pvals = gimp_parasite_data (parasite);
+
+              if (pvals->compression == COMPRESSION_DEFLATE)
+                tsvals.compression = COMPRESSION_ADOBE_DEFLATE;
+              else
+                tsvals.compression = pvals->compression;
+
+              tsvals.save_transp_pixels = pvals->save_transp_pixels;
+            }
+          gimp_parasite_free (parasite);
+
+          /*  First acquire information with a dialog  */
+          if (! save_dialog (&tsvals,
+                             SAVE_PROC,
+                             gimp_drawable_has_alpha (drawable),
+                             image_is_monochrome (image),
+                             gimp_image_base_type (image) == GIMP_INDEXED,
+                             &image_comment))
+            {
+              status = GIMP_PDB_CANCEL;
+            }
+          break;
+
+        case GIMP_RUN_NONINTERACTIVE:
+          /*  Make sure all the arguments are there!  */
+          if (nparams == 6 || nparams == 7)
+            {
+              switch (param[5].data.d_int32)
+                {
+                case 0: tsvals.compression = COMPRESSION_NONE;          break;
+                case 1: tsvals.compression = COMPRESSION_LZW;           break;
+                case 2: tsvals.compression = COMPRESSION_PACKBITS;      break;
+                case 3: tsvals.compression = COMPRESSION_ADOBE_DEFLATE; break;
+                case 4: tsvals.compression = COMPRESSION_JPEG;          break;
+                case 5: tsvals.compression = COMPRESSION_CCITTFAX3;     break;
+                case 6: tsvals.compression = COMPRESSION_CCITTFAX4;     break;
+                default: status = GIMP_PDB_CALLING_ERROR; break;
+                }
+
+              if (nparams == 7)
+                tsvals.save_transp_pixels = param[6].data.d_int32;
+              else
+                tsvals.save_transp_pixels = TRUE;
+            }
+          else
+            {
+              status = GIMP_PDB_CALLING_ERROR;
+            }
+          break;
+
+        case GIMP_RUN_WITH_LAST_VALS:
+          /*  Possibly retrieve data  */
+          gimp_get_data (SAVE_PROC, &tsvals);
+
+          parasite = gimp_image_get_parasite (orig_image, "tiff-save-options");
+          if (parasite)
+            {
+              const TiffSaveVals *pvals = gimp_parasite_data (parasite);
+
+              tsvals.compression        = pvals->compression;
+              tsvals.save_transp_pixels = pvals->save_transp_pixels;
+            }
+          gimp_parasite_free (parasite);
+          break;
+
+        default:
+          break;
+        }
+
+      if (status == GIMP_PDB_SUCCESS)
+        {
+          gint saved_bpp;
+
+          if (save_image (param[3].data.d_string, &tsvals,
+                          image, drawable, orig_image, image_comment,
+                          &saved_bpp, &error))
+            {
+              if (metadata)
+                {
+                  GFile *file;
+
+                  gimp_metadata_set_bits_per_sample (metadata, saved_bpp);
+
+                  if (tsvals.save_exif)
+                    metadata_flags |= GIMP_METADATA_SAVE_EXIF;
+                  else
+                    metadata_flags &= ~GIMP_METADATA_SAVE_EXIF;
+
+                  if (tsvals.save_xmp)
+                    metadata_flags |= GIMP_METADATA_SAVE_XMP;
+                  else
+                    metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
+
+                  if (tsvals.save_iptc)
+                    metadata_flags |= GIMP_METADATA_SAVE_IPTC;
+                  else
+                    metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
+
+                  /* never save metadata thumbnails for TIFF, see bug #729952 */
+                  metadata_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL;
+
+                  file = g_file_new_for_path (param[3].data.d_string);
+                  gimp_image_metadata_save_finish (image,
+                                                   "image/tiff",
+                                                   metadata, metadata_flags,
+                                                   file, NULL);
+                  g_object_unref (file);
+                }
+
+              /*  Store mvals data  */
+              gimp_set_data (SAVE_PROC, &tsvals, sizeof (TiffSaveVals));
+            }
+          else
+            {
+              status = GIMP_PDB_EXECUTION_ERROR;
+            }
+        }
+
+      if (export == GIMP_EXPORT_EXPORT)
+        gimp_image_delete (image);
+
+      if (metadata)
+        g_object_unref (metadata);
+    }
+  else
+    {
+      status = GIMP_PDB_CALLING_ERROR;
+    }
+
+  if (status != GIMP_PDB_SUCCESS && error)
+    {
+      *nreturn_vals = 2;
+      values[1].type          = GIMP_PDB_STRING;
+      values[1].data.d_string = error->message;
+    }
+
+  values[0].data.d_status = status;
+}
+
+static gboolean
+image_is_monochrome (gint32 image)
+{
+  guchar   *colors;
+  gint      num_colors;
+  gboolean  monochrome = FALSE;
+
+  g_return_val_if_fail (image != -1, FALSE);
+
+  colors = gimp_image_get_colormap (image, &num_colors);
+
+  if (colors)
+    {
+      if (num_colors == 2 || num_colors == 1)
+        {
+          const guchar  bw_map[] = { 0, 0, 0, 255, 255, 255 };
+          const guchar  wb_map[] = { 255, 255, 255, 0, 0, 0 };
+
+          if (memcmp (colors, bw_map, 3 * num_colors) == 0 ||
+              memcmp (colors, wb_map, 3 * num_colors) == 0)
+            {
+              monochrome = TRUE;
+            }
+        }
+
+      g_free (colors);
+    }
+
+  return monochrome;
+}
diff --git a/po-plug-ins/POTFILES.in b/po-plug-ins/POTFILES.in
index 081a81c..fbef0ec 100644
--- a/po-plug-ins/POTFILES.in
+++ b/po-plug-ins/POTFILES.in
@@ -117,6 +117,7 @@ plug-ins/file-psd/psd-thumb-load.c
 plug-ins/file-psd/psd-util.c
 plug-ins/file-psd/psd.c
 plug-ins/file-sgi/sgi.c
+plug-ins/file-tiff/file-tiff.c
 plug-ins/file-tiff/file-tiff-load.c
 plug-ins/file-tiff/file-tiff-save.c
 plug-ins/flame/flame.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]