mirror of https://github.com/GNOME/gimp.git
plug-ins: merge the file-tiff-load and file-tiff-save plug-ins
so they can share duplicated code.
This commit is contained in:
parent
52f4e993c0
commit
c64a104155
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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 */
|
||||
|
||||
/* 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 GimpColorProfile * load_profile (TIFF *tif);
|
||||
|
||||
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);
|
||||
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,
|
||||
|
|
|
@ -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__ */
|
|
@ -52,469 +52,26 @@
|
|||
#include <libgimp/gimp.h>
|
||||
#include <libgimp/gimpui.h>
|
||||
|
||||
#include "file-tiff-io.h"
|
||||
#include "file-tiff-save.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"
|
||||
#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;
|
||||
static gboolean save_paths (TIFF *tif,
|
||||
gint32 image);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint32 ID;
|
||||
GimpDrawable *drawable;
|
||||
GimpPixelRgn pixel_rgn;
|
||||
guchar *pixels;
|
||||
guchar *pixel;
|
||||
} channel_data;
|
||||
static void comment_entry_callback (GtkWidget *widget,
|
||||
gchar **comment);
|
||||
|
||||
static void byte2bit (const guchar *byteline,
|
||||
gint width,
|
||||
guchar *bitline,
|
||||
gboolean invert);
|
||||
|
||||
/* 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);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue