plug-ins: port file-tiff-save to GimpProcedureConfig

Implement the GUI using prop widgets and remove the glade file.
Change loading to attach the right parasite so the save procedure
finds the fake "last values".
This commit is contained in:
Michael Natterer 2020-05-18 00:13:21 +02:00
parent afe98c5c70
commit 9054ab5dc5
10 changed files with 510 additions and 657 deletions

View File

@ -34,6 +34,7 @@ libexec_PROGRAMS = file-tiff
file_tiff_SOURCES = \ file_tiff_SOURCES = \
file-tiff.c \ file-tiff.c \
file-tiff.h \
file-tiff-io.c \ file-tiff-io.c \
file-tiff-io.h \ file-tiff-io.h \
file-tiff-load.c \ file-tiff-load.c \

View File

@ -52,6 +52,7 @@
#include <libgimp/gimp.h> #include <libgimp/gimp.h>
#include <libgimp/gimpui.h> #include <libgimp/gimpui.h>
#include "file-tiff.h"
#include "file-tiff-io.h" #include "file-tiff-io.h"
#include "file-tiff-load.h" #include "file-tiff-load.h"
@ -61,13 +62,6 @@
#define PLUG_IN_ROLE "gimp-file-tiff-load" #define PLUG_IN_ROLE "gimp-file-tiff-load"
typedef struct
{
gint compression;
gint fillorder;
gboolean save_transp_pixels;
} TiffSaveVals;
typedef struct typedef struct
{ {
GimpDrawable *drawable; GimpDrawable *drawable;
@ -124,13 +118,6 @@ static gboolean load_dialog (TIFF *tif,
DefaultExtra *default_extra); DefaultExtra *default_extra);
static TiffSaveVals tsvals =
{
COMPRESSION_NONE, /* compression */
TRUE, /* alpha handling */
};
/* returns a pointer into the TIFF */ /* returns a pointer into the TIFF */
static const gchar * static const gchar *
tiff_get_page_name (TIFF *tif) tiff_get_page_name (TIFF *tif)
@ -157,13 +144,14 @@ load_image (GFile *file,
TIFF *tif; TIFF *tif;
TiffSelectedPages pages; TiffSelectedPages pages;
GList *images_list = NULL; GList *images_list = NULL;
DefaultExtra default_extra = GIMP_TIFF_LOAD_UNASSALPHA; DefaultExtra default_extra = GIMP_TIFF_LOAD_UNASSALPHA;
gint first_image_type = GIMP_RGB; gint first_image_type = GIMP_RGB;
gint min_row = G_MAXINT; gint min_row = G_MAXINT;
gint min_col = G_MAXINT; gint min_col = G_MAXINT;
gint max_row = 0; gint max_row = 0;
gint max_col = 0; gint max_col = 0;
gboolean save_transp_pixels = FALSE;
gint li; gint li;
*image = NULL; *image = NULL;
@ -328,7 +316,7 @@ load_image (GFile *file,
gboolean is_bw; gboolean is_bw;
gint i; gint i;
gboolean worst_case = FALSE; gboolean worst_case = FALSE;
TiffSaveVals save_vals; gint gimp_compression = GIMP_COMPRESSION_NONE;
const gchar *name; const gchar *name;
TIFFSetDirectory (tif, pages.pages[li]); TIFFSetDirectory (tif, pages.pages[li]);
@ -481,13 +469,13 @@ load_image (GFile *file,
if (extra > 0 && (extra_types[0] == EXTRASAMPLE_ASSOCALPHA)) if (extra > 0 && (extra_types[0] == EXTRASAMPLE_ASSOCALPHA))
{ {
alpha = TRUE; alpha = TRUE;
tsvals.save_transp_pixels = FALSE; save_transp_pixels = FALSE;
extra--; extra--;
} }
else if (extra > 0 && (extra_types[0] == EXTRASAMPLE_UNASSALPHA)) else if (extra > 0 && (extra_types[0] == EXTRASAMPLE_UNASSALPHA))
{ {
alpha = TRUE; alpha = TRUE;
tsvals.save_transp_pixels = TRUE; save_transp_pixels = TRUE;
extra--; extra--;
} }
else if (extra > 0 && (extra_types[0] == EXTRASAMPLE_UNSPECIFIED)) else if (extra > 0 && (extra_types[0] == EXTRASAMPLE_UNSPECIFIED))
@ -504,11 +492,11 @@ load_image (GFile *file,
{ {
case GIMP_TIFF_LOAD_ASSOCALPHA: case GIMP_TIFF_LOAD_ASSOCALPHA:
alpha = TRUE; alpha = TRUE;
tsvals.save_transp_pixels = FALSE; save_transp_pixels = FALSE;
break; break;
case GIMP_TIFF_LOAD_UNASSALPHA: case GIMP_TIFF_LOAD_UNASSALPHA:
alpha = TRUE; alpha = TRUE;
tsvals.save_transp_pixels = TRUE; save_transp_pixels = TRUE;
break; break;
default: /* GIMP_TIFF_LOAD_CHANNEL */ default: /* GIMP_TIFF_LOAD_CHANNEL */
alpha = FALSE; alpha = FALSE;
@ -531,11 +519,11 @@ load_image (GFile *file,
{ {
case GIMP_TIFF_LOAD_ASSOCALPHA: case GIMP_TIFF_LOAD_ASSOCALPHA:
alpha = TRUE; alpha = TRUE;
tsvals.save_transp_pixels = FALSE; save_transp_pixels = FALSE;
break; break;
case GIMP_TIFF_LOAD_UNASSALPHA: case GIMP_TIFF_LOAD_UNASSALPHA:
alpha = TRUE; alpha = TRUE;
tsvals.save_transp_pixels = TRUE; save_transp_pixels = TRUE;
break; break;
default: /* GIMP_TIFF_LOAD_CHANNEL */ default: /* GIMP_TIFF_LOAD_CHANNEL */
alpha = FALSE; alpha = FALSE;
@ -574,7 +562,7 @@ load_image (GFile *file,
if (alpha) if (alpha)
{ {
if (tsvals.save_transp_pixels) if (save_transp_pixels)
{ {
if (profile_linear) if (profile_linear)
{ {
@ -639,7 +627,7 @@ load_image (GFile *file,
if (alpha) if (alpha)
{ {
if (tsvals.save_transp_pixels) if (save_transp_pixels)
{ {
if (profile_linear) if (profile_linear)
{ {
@ -749,7 +737,7 @@ load_image (GFile *file,
} }
} }
save_vals.compression = compression; gimp_compression = tiff_compression_to_gimp_compression (compression);
} }
if (worst_case) if (worst_case)
@ -841,14 +829,33 @@ load_image (GFile *file,
/* attach parasites */ /* attach parasites */
{ {
GimpParasite *parasite; GString *string;
const gchar *img_desc; GimpConfigWriter *writer;
GimpParasite *parasite;
const gchar *img_desc;
parasite = gimp_parasite_new ("tiff-save-options", 0, /* construct the save parasite manually instead of simply
sizeof (save_vals), &save_vals); * creating and saving a save config object, because we want
* it to contain only some properties
*/
string = g_string_new (NULL);
writer = gimp_config_writer_new_from_string (string);
gimp_config_writer_open (writer, "compression");
gimp_config_writer_printf (writer, "%d", gimp_compression);
gimp_config_writer_close (writer);
gimp_config_writer_finish (writer, NULL, NULL);
parasite = gimp_parasite_new ("GimpProcedureConfig-file-tiff-save-last",
GIMP_PARASITE_PERSISTENT,
string->len + 1, string->str);
gimp_image_attach_parasite (*image, parasite); gimp_image_attach_parasite (*image, parasite);
gimp_parasite_free (parasite); gimp_parasite_free (parasite);
g_string_free (string, TRUE);
/* Attach a parasite containing the image description. /* Attach a parasite containing the image description.
* Pretend to be a gimp comment so other plugins will use this * Pretend to be a gimp comment so other plugins will use this
* description as an image comment where appropriate. * description as an image comment where appropriate.

View File

@ -53,6 +53,7 @@
#include <libgimp/gimp.h> #include <libgimp/gimp.h>
#include <libgimp/gimpui.h> #include <libgimp/gimpui.h>
#include "file-tiff.h"
#include "file-tiff-io.h" #include "file-tiff-io.h"
#include "file-tiff-save.h" #include "file-tiff-save.h"
@ -69,16 +70,12 @@ static gboolean save_paths (TIFF *tif,
gint offset_x, gint offset_x,
gint offset_y); gint offset_y);
static void comment_entry_callback (GtkWidget *widget,
gchar **comment);
static void byte2bit (const guchar *byteline, static void byte2bit (const guchar *byteline,
gint width, gint width,
guchar *bitline, guchar *bitline,
gboolean invert); gboolean invert);
static void save_thumbnail (TiffSaveVals *tsvals, static void save_thumbnail (GimpImage *image,
GimpImage *image,
TIFF *tif); TIFF *tif);
@ -269,18 +266,18 @@ save_paths (TIFF *tif,
*/ */
static gboolean static gboolean
save_layer (TIFF *tif, save_layer (TIFF *tif,
TiffSaveVals *tsvals, GObject *config,
const Babl *space, const Babl *space,
GimpImage *image, GimpImage *image,
GimpLayer *layer, GimpLayer *layer,
gint32 page, gint32 page,
gint32 num_pages, gint32 num_pages,
GimpImage *orig_image, /* the export function might */ GimpImage *orig_image, /* the export function might
/* have created a duplicate */ * have created a duplicate */
gint *saved_bpp, gint *saved_bpp,
gboolean out_linear, gboolean out_linear,
GError **error) GError **error)
{ {
gboolean status = FALSE; gboolean status = FALSE;
gushort red[256]; gushort red[256];
@ -319,8 +316,15 @@ save_layer (TIFF *tif,
gdouble yresolution; gdouble yresolution;
gushort save_unit = RESUNIT_INCH; gushort save_unit = RESUNIT_INCH;
gint offset_x, offset_y; gint offset_x, offset_y;
gint config_compression;
gboolean config_save_transp_pixels;
compression = tsvals->compression; g_object_get (config,
"compression", &config_compression,
"save-transparent-pixels", &config_save_transp_pixels,
NULL);
compression = gimp_compression_to_tiff_compression (config_compression);
layer_name = gimp_item_get_name (GIMP_ITEM (layer)); layer_name = gimp_item_get_name (GIMP_ITEM (layer));
@ -456,7 +460,7 @@ save_layer (TIFF *tif,
samplesperpixel = 4; samplesperpixel = 4;
photometric = PHOTOMETRIC_RGB; photometric = PHOTOMETRIC_RGB;
alpha = TRUE; alpha = TRUE;
if (tsvals->save_transp_pixels) if (config_save_transp_pixels)
{ {
if (out_linear) if (out_linear)
{ {
@ -508,7 +512,7 @@ save_layer (TIFF *tif,
samplesperpixel = 2; samplesperpixel = 2;
photometric = PHOTOMETRIC_MINISBLACK; photometric = PHOTOMETRIC_MINISBLACK;
alpha = TRUE; alpha = TRUE;
if (tsvals->save_transp_pixels) if (config_save_transp_pixels)
{ {
if (out_linear) if (out_linear)
{ {
@ -649,7 +653,7 @@ save_layer (TIFF *tif,
if (alpha) if (alpha)
{ {
if (tsvals->save_transp_pixels || if (config_save_transp_pixels ||
/* Associated alpha, hence premultiplied components is /* Associated alpha, hence premultiplied components is
* meaningless for palette images with transparency in TIFF * meaningless for palette images with transparency in TIFF
* format, since alpha is set per pixel, not per color (so a * format, since alpha is set per pixel, not per color (so a
@ -780,9 +784,8 @@ out:
} }
static void static void
save_thumbnail (TiffSaveVals *tsvals, save_thumbnail (GimpImage *image,
GimpImage *image, TIFF *tif)
TIFF *tif)
{ {
/* now switch IFD and write thumbnail /* now switch IFD and write thumbnail
* *
@ -793,83 +796,81 @@ save_thumbnail (TiffSaveVals *tsvals,
* Exif saves the thumbnail as a second page. To avoid this, the * Exif saves the thumbnail as a second page. To avoid this, the
* thumbnail must be saved with the functions of libtiff. * thumbnail must be saved with the functions of libtiff.
*/ */
if (tsvals->save_thumbnail)
{ GdkPixbuf *thumb_pixbuf;
GdkPixbuf *thumb_pixbuf; guchar *thumb_pixels;
guchar *thumb_pixels; guchar *buf;
guchar *buf; gint image_width;
gint image_width; gint image_height;
gint image_height; gint thumbw;
gint thumbw; gint thumbh;
gint thumbh; gint x, y;
gint x, y;
#define EXIF_THUMBNAIL_SIZE 256 #define EXIF_THUMBNAIL_SIZE 256
image_width = gimp_image_width (image); image_width = gimp_image_width (image);
image_height = gimp_image_height (image); image_height = gimp_image_height (image);
if (image_width > image_height) if (image_width > image_height)
{ {
thumbw = EXIF_THUMBNAIL_SIZE; thumbw = EXIF_THUMBNAIL_SIZE;
thumbh = EXIF_THUMBNAIL_SIZE * image_height / image_width; thumbh = EXIF_THUMBNAIL_SIZE * image_height / image_width;
}
else
{
thumbh = EXIF_THUMBNAIL_SIZE;
thumbw = EXIF_THUMBNAIL_SIZE * image_width / image_height;
}
thumb_pixbuf = gimp_image_get_thumbnail (image, thumbw, thumbh,
GIMP_PIXBUF_KEEP_ALPHA);
thumb_pixels = gdk_pixbuf_get_pixels (thumb_pixbuf);
TIFFSetField (tif, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, thumbw);
TIFFSetField (tif, TIFFTAG_IMAGELENGTH, thumbh);
TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, thumbh);
TIFFSetField (tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField (tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, 3);
buf = _TIFFmalloc (thumbw * 3);
for (y = 0; y < thumbh; y++)
{
guchar *p = buf;
for (x = 0; x < thumbw; x++)
{
*p++ = *thumb_pixels++; /* r */
*p++ = *thumb_pixels++; /* g */
*p++ = *thumb_pixels++; /* b */
thumb_pixels++;
}
TIFFWriteScanline (tif, buf, y, 0);
}
_TIFFfree (buf);
TIFFWriteDirectory (tif);
g_object_unref (thumb_pixbuf);
} }
else
{
thumbh = EXIF_THUMBNAIL_SIZE;
thumbw = EXIF_THUMBNAIL_SIZE * image_width / image_height;
}
thumb_pixbuf = gimp_image_get_thumbnail (image, thumbw, thumbh,
GIMP_PIXBUF_KEEP_ALPHA);
thumb_pixels = gdk_pixbuf_get_pixels (thumb_pixbuf);
TIFFSetField (tif, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, thumbw);
TIFFSetField (tif, TIFFTAG_IMAGELENGTH, thumbh);
TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, thumbh);
TIFFSetField (tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField (tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, 3);
buf = _TIFFmalloc (thumbw * 3);
for (y = 0; y < thumbh; y++)
{
guchar *p = buf;
for (x = 0; x < thumbw; x++)
{
*p++ = *thumb_pixels++; /* r */
*p++ = *thumb_pixels++; /* g */
*p++ = *thumb_pixels++; /* b */
thumb_pixels++;
}
TIFFWriteScanline (tif, buf, y, 0);
}
_TIFFfree (buf);
TIFFWriteDirectory (tif);
g_object_unref (thumb_pixbuf);
} }
static void static void
save_metadata (GFile *file, save_metadata (GFile *file,
TiffSaveVals *tsvals, GObject *config,
GimpImage *image, GimpImage *image,
GimpMetadata *metadata, GimpMetadata *metadata,
GimpMetadataSaveFlags metadata_flags, gint saved_bpp)
gint saved_bpp)
{ {
gchar **exif_tags; gchar **exif_tags;
gboolean save_thumbnail;
/* See bug 758909: clear TIFFTAG_MIN/MAXSAMPLEVALUE because /* See bug 758909: clear TIFFTAG_MIN/MAXSAMPLEVALUE because
* exiv2 saves them with wrong type and the original values * exiv2 saves them with wrong type and the original values
@ -877,7 +878,8 @@ save_metadata (GFile *file,
* we also clear some other tags that were only meaningful * we also clear some other tags that were only meaningful
* for the original imported image. * for the original imported image.
*/ */
static const gchar *exif_tags_to_remove[] = { static const gchar *exif_tags_to_remove[] =
{
"Exif.Image.0x0118", "Exif.Image.0x0118",
"Exif.Image.0x0119", "Exif.Image.0x0119",
"Exif.Image.0x011d", "Exif.Image.0x011d",
@ -894,7 +896,7 @@ save_metadata (GFile *file,
"Exif.Image.StripByteCounts", "Exif.Image.StripByteCounts",
"Exif.Image.StripOffsets" "Exif.Image.StripOffsets"
}; };
static const guint n_keys = G_N_ELEMENTS(exif_tags_to_remove); static const guint n_keys = G_N_ELEMENTS (exif_tags_to_remove);
for (int k = 0; k < n_keys; k++) for (int k = 0; k < n_keys; k++)
{ {
@ -903,7 +905,7 @@ save_metadata (GFile *file,
} }
/* get rid of all the EXIF tags for anything but the first sub image. */ /* get rid of all the EXIF tags for anything but the first sub image. */
exif_tags = gexiv2_metadata_get_exif_tags (GEXIV2_METADATA(metadata)); exif_tags = gexiv2_metadata_get_exif_tags (GEXIV2_METADATA (metadata));
for (char **tag = exif_tags; *tag; tag++) for (char **tag = exif_tags; *tag; tag++)
{ {
if (g_str_has_prefix (*tag, "Exif.Image") if (g_str_has_prefix (*tag, "Exif.Image")
@ -914,50 +916,34 @@ save_metadata (GFile *file,
gimp_metadata_set_bits_per_sample (metadata, saved_bpp); gimp_metadata_set_bits_per_sample (metadata, saved_bpp);
if (tsvals->save_exif) g_object_get (config,
metadata_flags |= GIMP_METADATA_SAVE_EXIF; "save-thumbnail", &save_thumbnail,
else NULL);
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 */ /* never save metadata thumbnails for TIFF, see bug #729952 */
metadata_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL; g_object_set (config,
"save-thumbnail", FALSE,
NULL);
if (tsvals->save_profile) gimp_procedure_config_save_metadata (GIMP_PROCEDURE_CONFIG (config),
metadata_flags |= GIMP_METADATA_SAVE_COLOR_PROFILE; image, file);
else
metadata_flags &= ~GIMP_METADATA_SAVE_COLOR_PROFILE;
gimp_image_metadata_save_finish (image, g_object_set (config,
"image/tiff", "save-thumbnail", save_thumbnail,
metadata, metadata_flags, NULL);
file, NULL);
} }
gboolean gboolean
save_image (GFile *file, save_image (GFile *file,
TiffSaveVals *tsvals, GimpImage *image,
GimpImage *image, GimpImage *orig_image, /* the export function might
GimpImage *orig_image, /* the export function */ * have created a duplicate */
/* might have created */ GObject *config,
/* a duplicate */ GimpMetadata *metadata,
const gchar *image_comment, GError **error)
gint *saved_bpp,
GimpMetadata *metadata,
GimpMetadataSaveFlags metadata_flags,
GError **error)
{ {
const Babl *space = NULL;
TIFF *tif; TIFF *tif;
const Babl *space = NULL;
gboolean status = FALSE; gboolean status = FALSE;
gboolean out_linear = FALSE; gboolean out_linear = FALSE;
gint number_of_sub_IFDs = 1; gint number_of_sub_IFDs = 1;
@ -965,6 +951,16 @@ save_image (GFile *file,
gint32 num_layers; gint32 num_layers;
gint32 current_layer = 0; gint32 current_layer = 0;
GList *layers; GList *layers;
gint saved_bpp;
gchar *config_comment;
gboolean config_save_profile;
gboolean config_save_thumbnail;
g_object_get (config,
"comment", &config_comment,
"save-color-profile", &config_save_profile,
"save-thumbnail", &config_save_thumbnail,
NULL);
layers = gimp_image_list_layers (image); layers = gimp_image_list_layers (image);
layers = g_list_reverse (layers); layers = g_list_reverse (layers);
@ -987,42 +983,31 @@ save_image (GFile *file,
TIFFSetField (tif, TIFFTAG_DOCUMENTNAME, g_file_get_path (file)); TIFFSetField (tif, TIFFTAG_DOCUMENTNAME, g_file_get_path (file));
/* The TIFF spec explicitly says ASCII for the image description. */ if (config_comment && *config_comment)
if (image_comment)
{ {
const gchar *c = image_comment; const gchar *c = config_comment;
gint len; gint len;
/* The TIFF spec explicitly says ASCII for the image description. */
for (len = strlen (c); len; c++, len--) for (len = strlen (c); len; c++, len--)
{ {
if ((guchar) *c > 127) if ((guchar) *c > 127)
{ {
g_message (_("The TIFF format only supports comments in\n" g_message (_("The TIFF format only supports comments in\n"
"7bit ASCII encoding. No comment is saved.")); "7bit ASCII encoding. No comment is saved."));
image_comment = NULL; g_free (config_comment);
config_comment = NULL;
break; break;
} }
} }
}
/* do we have a comment? If so, create a new parasite to hold it, if (config_comment)
* and attach it to the image. The attach function automatically TIFFSetField (tif, TIFFTAG_IMAGEDESCRIPTION, config_comment);
* detaches a previous incarnation of the parasite. */
if (image_comment && *image_comment)
{
GimpParasite *parasite;
TIFFSetField (tif, TIFFTAG_IMAGEDESCRIPTION, image_comment);
parasite = gimp_parasite_new ("gimp-comment",
GIMP_PARASITE_PERSISTENT,
strlen (image_comment) + 1, image_comment);
gimp_image_attach_parasite (orig_image, parasite);
gimp_parasite_free (parasite);
} }
#ifdef TIFFTAG_ICCPROFILE #ifdef TIFFTAG_ICCPROFILE
if (tsvals->save_profile) if (config_save_profile)
{ {
GimpColorProfile *profile; GimpColorProfile *profile;
const guint8 *icc_data; const guint8 *icc_data;
@ -1058,22 +1043,22 @@ save_image (GFile *file,
#endif #endif
/* we put the whole file's thumbnail into the first IFD (i.e., page) */ /* we put the whole file's thumbnail into the first IFD (i.e., page) */
if (tsvals->save_thumbnail) if (config_save_thumbnail)
TIFFSetField (tif, TIFFTAG_SUBIFD, number_of_sub_IFDs, sub_IFDs_offsets); TIFFSetField (tif, TIFFTAG_SUBIFD, number_of_sub_IFDs, sub_IFDs_offsets);
/* write last layer as first page. */ /* write last layer as first page. */
if (! save_layer (tif, tsvals, space, image, if (! save_layer (tif, config, space, image,
g_list_nth_data (layers, current_layer), g_list_nth_data (layers, current_layer),
current_layer, num_layers, current_layer, num_layers,
orig_image, saved_bpp, out_linear, error)) orig_image, &saved_bpp, out_linear, error))
{ {
goto out; goto out;
} }
current_layer++; current_layer++;
/* write thumbnail */ /* write thumbnail */
if (tsvals->save_thumbnail) if (config_save_thumbnail)
save_thumbnail (tsvals, image, tif); save_thumbnail (image, tif);
/* close file so we can safely let exiv2 work on it to write metadata. /* close file so we can safely let exiv2 work on it to write metadata.
* this can be simplified once multi page TIFF is supported by exiv2 * this can be simplified once multi page TIFF is supported by exiv2
@ -1082,7 +1067,7 @@ save_image (GFile *file,
TIFFClose (tif); TIFFClose (tif);
tif = NULL; tif = NULL;
if (metadata) if (metadata)
save_metadata (file, tsvals, image, metadata, metadata_flags, *saved_bpp); save_metadata (file, config, image, metadata, saved_bpp);
/* write the remaining layers */ /* write the remaining layers */
if (num_layers > 1) if (num_layers > 1)
@ -1104,7 +1089,7 @@ save_image (GFile *file,
{ {
gint tmp_saved_bpp; gint tmp_saved_bpp;
if (! save_layer (tif, tsvals, space, image, if (! save_layer (tif, config, space, image,
g_list_nth_data (layers, current_layer), g_list_nth_data (layers, current_layer),
current_layer, num_layers, orig_image, current_layer, num_layers, orig_image,
&tmp_saved_bpp, out_linear, error)) &tmp_saved_bpp, out_linear, error))
@ -1112,7 +1097,7 @@ save_image (GFile *file,
goto out; goto out;
} }
if (tmp_saved_bpp != *saved_bpp) if (tmp_saved_bpp != saved_bpp)
{ {
/* this should never happen. if it does, decide if it's /* this should never happen. if it does, decide if it's
* really an error. * really an error.
@ -1143,179 +1128,204 @@ out:
return status; return status;
} }
static gboolean
combo_sensitivity_func (gint value,
gpointer data)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (data));
if (gimp_int_store_lookup_by_value (model, value, &iter))
{
gpointer insensitive;
gtk_tree_model_get (model, &iter,
GIMP_INT_STORE_USER_DATA, &insensitive,
-1);
return ! GPOINTER_TO_INT (insensitive);
}
return TRUE;
}
static void
combo_set_item_sensitive (GtkWidget *widget,
gint value,
gboolean sensitive)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
if (gimp_int_store_lookup_by_value (model, value, &iter))
{
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
GIMP_INT_STORE_USER_DATA,
! GINT_TO_POINTER (sensitive),
-1);
}
}
gboolean gboolean
save_dialog (TiffSaveVals *tsvals, save_dialog (GimpImage *image,
const gchar *help_id, GimpProcedure *procedure,
GObject *config,
gboolean has_alpha, gboolean has_alpha,
gboolean is_monochrome, gboolean is_monochrome,
gboolean is_indexed, gboolean is_indexed,
gboolean is_multi_layer, gboolean is_multi_layer)
gchar **image_comment)
{ {
GError *error = NULL; GtkWidget *dialog;
GtkWidget *dialog; GtkWidget *main_vbox;
GtkWidget *vbox; GtkWidget *grid;
GtkWidget *frame; GtkListStore *store;
GtkWidget *entry; GtkWidget *combo;
GtkWidget *toggle; GtkWidget *button;
GtkWidget *cmp_g3; GtkWidget *frame;
GtkWidget *cmp_g4; GtkWidget *entry;
GtkWidget *cmp_jpeg; GimpCompression compression;
GtkBuilder *builder; gint row = 0;
gchar *ui_file; gboolean run;
gboolean run;
dialog = gimp_export_dialog_new (_("TIFF"), PLUG_IN_ROLE, help_id); dialog = gimp_procedure_dialog_new (procedure,
GIMP_PROCEDURE_CONFIG (config),
_("Export Image as TIFF"));
builder = gtk_builder_new (); main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
ui_file = g_build_filename (gimp_data_directory (), gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
"ui", "plug-ins", "plug-in-file-tiff.ui", gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
NULL); main_vbox, TRUE, TRUE, 0);
if (! gtk_builder_add_from_file (builder, ui_file, &error)) gtk_widget_show (main_vbox);
{
gchar *display_name = g_filename_display_name (ui_file);
g_printerr (_("Error loading UI file '%s': %s"), grid = gtk_grid_new ();
display_name, error ? error->message : _("Unknown error")); gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_box_pack_start (GTK_BOX (main_vbox), grid, FALSE, FALSE, 0);
gtk_widget_show (grid);
g_free (display_name); store =
} gimp_int_store_new (_("None"), GIMP_COMPRESSION_NONE,
_("LZW"), GIMP_COMPRESSION_LZW,
_("Pack Bits"), GIMP_COMPRESSION_PACKBITS,
_("Deflate"), GIMP_COMPRESSION_ADOBE_DEFLATE,
_("JPEG"), GIMP_COMPRESSION_JPEG,
_("CCITT Group 3 fax"), GIMP_COMPRESSION_CCITTFAX3,
_("CCITT Group 4 fax"), GIMP_COMPRESSION_CCITTFAX4,
NULL);
g_free (ui_file); combo = gimp_prop_int_combo_box_new (config, "compression",
GIMP_INT_STORE (store));
g_object_unref (store);
vbox = GTK_WIDGET (gtk_builder_get_object (builder, "tiff_export_vbox")); gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
_("_Compression:"), 0.0, 0.5,
combo, 1);
gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)), gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (combo),
vbox, FALSE, FALSE, 0); combo_sensitivity_func,
gtk_widget_show (vbox); combo, NULL);
vbox = GTK_WIDGET (gtk_builder_get_object (builder, "radio_button_box")); combo_set_item_sensitive (combo, GIMP_COMPRESSION_CCITTFAX3, is_monochrome);
combo_set_item_sensitive (combo, GIMP_COMPRESSION_CCITTFAX4, is_monochrome);
combo_set_item_sensitive (combo, GIMP_COMPRESSION_JPEG, ! is_indexed);
frame = gimp_int_radio_group_new (TRUE, _("Compression"), g_object_get (config,
G_CALLBACK (gimp_radio_button_update), "compression", &compression,
&tsvals->compression, NULL, tsvals->compression, NULL);
_("_None"), COMPRESSION_NONE, NULL,
_("_LZW"), COMPRESSION_LZW, NULL,
_("_Pack Bits"), COMPRESSION_PACKBITS, NULL,
_("_Deflate"), COMPRESSION_ADOBE_DEFLATE, NULL,
_("_JPEG"), COMPRESSION_JPEG, &cmp_jpeg,
_("CCITT Group _3 fax"), COMPRESSION_CCITTFAX3, &cmp_g3,
_("CCITT Group _4 fax"), COMPRESSION_CCITTFAX4, &cmp_g4,
NULL);
gtk_widget_set_sensitive (cmp_g3, is_monochrome);
gtk_widget_set_sensitive (cmp_g4, is_monochrome);
gtk_widget_set_sensitive (cmp_jpeg, ! is_indexed);
if (! is_monochrome) if (! is_monochrome)
{ {
if (tsvals->compression == COMPRESSION_CCITTFAX3 || if (compression == GIMP_COMPRESSION_CCITTFAX3 ||
tsvals->compression == COMPRESSION_CCITTFAX4) compression == GIMP_COMPRESSION_CCITTFAX4)
{ {
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (cmp_g3), compression = GIMP_COMPRESSION_NONE;
COMPRESSION_NONE);
} }
} }
if (is_indexed && tsvals->compression == COMPRESSION_JPEG) if (is_indexed && compression == GIMP_COMPRESSION_JPEG)
{ {
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (cmp_jpeg), compression = GIMP_COMPRESSION_NONE;
COMPRESSION_NONE);
} }
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); g_object_set (config,
gtk_widget_show (frame); "compression", compression,
NULL);
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-alpha"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
has_alpha && (tsvals->save_transp_pixels || is_indexed));
gtk_widget_set_sensitive (toggle, has_alpha && ! is_indexed);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_transp_pixels);
entry = GTK_WIDGET (gtk_builder_get_object (builder, "commentfield"));
gtk_entry_set_text (GTK_ENTRY (entry), *image_comment ? *image_comment : "");
g_signal_connect (entry, "changed",
G_CALLBACK (comment_entry_callback),
image_comment);
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-exif"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
tsvals->save_exif);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_exif);
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-xmp"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
tsvals->save_xmp);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_xmp);
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-iptc"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
tsvals->save_iptc);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_iptc);
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-thumbnail"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
tsvals->save_thumbnail);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_thumbnail);
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-color-profile"));
#ifdef TIFFTAG_ICCPROFILE
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
tsvals->save_profile);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_profile);
#else
gtk_widget_hide (toggle);
#endif
toggle = GTK_WIDGET (gtk_builder_get_object (builder, "save-layers"));
if (is_multi_layer) if (is_multi_layer)
{
button = gimp_prop_check_button_new (config, "save-layers",
_("Save layers"));
}
else
{ {
/* If single-layer TIFF, set the toggle insensitive and show it as /* If single-layer TIFF, set the toggle insensitive and show it as
* unchecked though I don't actually change the tsvals value to * unchecked though I don't actually change the tsvals value to
* keep storing previously chosen value. * keep storing previously chosen value.
*/ */
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), button = gtk_check_button_new_with_mnemonic (_("Save layers"));
tsvals->save_layers); gtk_widget_set_sensitive (button, FALSE);
g_signal_connect (toggle, "toggled", gtk_widget_show (button);
G_CALLBACK (gimp_toggle_button_update),
&tsvals->save_layers);
} }
gtk_widget_set_sensitive (toggle, is_multi_layer);
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
if (has_alpha && ! is_indexed)
{
button = gimp_prop_check_button_new (config, "save-transparent-pixels",
_("Save color values from transparent pisels"));
}
else
{
button = gtk_check_button_new_with_mnemonic (_("Save color values from transparent pixels"));
gtk_widget_set_sensitive (button, FALSE);
gtk_widget_show (button);
}
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
button = gimp_prop_check_button_new (config, "save-exif",
_("Save Exif data"));
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
button = gimp_prop_check_button_new (config, "save-xmp",
_("Save XMP data"));
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
button = gimp_prop_check_button_new (config, "save-iptc",
_("Save IPTC data"));
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
button = gimp_prop_check_button_new (config, "save-thumbnail",
_("Save thumbnail"));
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
#ifdef TIFFTAG_ICCPROFILE
button = gimp_prop_check_button_new (config, "save-color-profile",
_("Save color profile"));
gtk_grid_attach (GTK_GRID (grid), button, 0, row++, 2, 1);
#endif
frame = gimp_frame_new (_("Comment"));
gtk_grid_attach (GTK_GRID (grid), frame, 0, row++, 2, 1);
gtk_widget_show (frame);
entry = gimp_prop_entry_new (config, "comment", -1);
gtk_container_add (GTK_CONTAINER (frame), entry);
gtk_widget_show (entry);
gtk_widget_show (dialog); gtk_widget_show (dialog);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK); run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
return run; return run;
} }
static void
comment_entry_callback (GtkWidget *widget,
gchar **comment)
{
const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget));
g_free (*comment);
*comment = g_strdup (text);
}
/* Convert n bytes of 0/1 to a line of bits */ /* Convert n bytes of 0/1 to a line of bits */
static void static void
byte2bit (const guchar *byteline, byte2bit (const guchar *byteline,

View File

@ -23,37 +23,20 @@
#define __FILE_TIFF_SAVE_H__ #define __FILE_TIFF_SAVE_H__
typedef struct gboolean save_image (GFile *file,
{ GimpImage *image,
gint compression; GimpImage *orig_image,
gint fillorder; GObject *config,
gboolean save_transp_pixels; GimpMetadata *metadata,
gboolean save_exif; GError **error);
gboolean save_xmp;
gboolean save_iptc;
gboolean save_thumbnail;
gboolean save_profile;
gboolean save_layers;
} TiffSaveVals;
gboolean save_dialog (GimpImage *image,
gboolean save_image (GFile *file, GimpProcedure *procedure,
TiffSaveVals *tsvals, GObject *config,
GimpImage *image, gboolean has_alpha,
GimpImage *orig_image, gboolean is_monochrome,
const gchar *image_comment, gboolean is_indexed,
gint *saved_bpp, gboolean is_multi_layer);
GimpMetadata *metadata,
GimpMetadataSaveFlags metadata_flags,
GError **error);
gboolean save_dialog (TiffSaveVals *tsvals,
const gchar *help_id,
gboolean has_alpha,
gboolean is_monochrome,
gboolean is_indexed,
gboolean is_multi_layer,
gchar **image_comment);
#endif /* __FILE_TIFF_SAVE_H__ */ #endif /* __FILE_TIFF_SAVE_H__ */

View File

@ -49,6 +49,7 @@
#include <libgimp/gimp.h> #include <libgimp/gimp.h>
#include <libgimp/gimpui.h> #include <libgimp/gimpui.h>
#include "file-tiff.h"
#include "file-tiff-load.h" #include "file-tiff-load.h"
#include "file-tiff-save.h" #include "file-tiff-save.h"
@ -106,22 +107,6 @@ G_DEFINE_TYPE (Tiff, tiff, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (TIFF_TYPE) GIMP_MAIN (TIFF_TYPE)
static TiffSaveVals tsvals =
{
COMPRESSION_NONE, /* compression */
TRUE, /* alpha handling */
FALSE, /* save transp. pixels */
FALSE, /* save exif */
FALSE, /* save xmp */
FALSE, /* save iptc */
TRUE, /* save thumbnail */
TRUE, /* save profile */
TRUE /* save layer */
};
static gchar *image_comment = NULL;
static void static void
tiff_class_init (TiffClass *klass) tiff_class_init (TiffClass *klass)
{ {
@ -216,12 +201,54 @@ tiff_create_procedure (GimpPlugIn *plug_in,
0, 6, 0, 0, 6, 0,
G_PARAM_READWRITE); G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "save-transp-pixels", GIMP_PROC_ARG_BOOLEAN (procedure, "save-transparent-pixels",
"Save transp pixels", "Save transparent pixels",
"Keep the color data masked by an alpha channel " "Keep the color data masked by an alpha channel "
"intact (do not store premultiplied components)", "intact (do not store premultiplied components)",
TRUE, TRUE,
G_PARAM_READWRITE); G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_STRING (procedure, "comment",
"Comment",
"Image comment",
gimp_get_default_comment (),
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-layers",
"Save Layers",
"Save Layers",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-exif",
"Save Exif",
"Save Exif",
gimp_export_exif (),
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-xmp",
"Save XMP",
"Save XMP",
gimp_export_xmp (),
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-iptc",
"Save IPTC",
"Save IPTC",
gimp_export_iptc (),
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-thumbnail",
"Save thumbnail",
"Save thumbnail",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "save-color-profile",
"Save profile",
"Save color profile",
gimp_export_color_profile (),
G_PARAM_READWRITE);
} }
return procedure; return procedure;
@ -296,17 +323,22 @@ tiff_save (GimpProcedure *procedure,
const GimpValueArray *args, const GimpValueArray *args,
gpointer run_data) gpointer run_data)
{ {
GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpProcedureConfig *config;
GimpMetadata *metadata; GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpMetadataSaveFlags metadata_flags; GimpExportReturn export = GIMP_EXPORT_CANCEL;
GimpParasite *parasite; GimpMetadata *metadata;
GimpImage *orig_image = image; GimpImage *orig_image;
GimpExportReturn export = GIMP_EXPORT_CANCEL; GError *error = NULL;
GError *error = NULL;
INIT_I18N (); INIT_I18N ();
gegl_init (NULL, NULL); gegl_init (NULL, NULL);
config = gimp_procedure_create_config (procedure);
metadata = gimp_procedure_config_begin_export (config, image, run_mode,
args, "image/tiff");
orig_image = image;
switch (run_mode) switch (run_mode)
{ {
case GIMP_RUN_INTERACTIVE: case GIMP_RUN_INTERACTIVE:
@ -317,90 +349,17 @@ tiff_save (GimpProcedure *procedure,
break; break;
} }
/* Override the defaults with preferences. */ if (run_mode == GIMP_RUN_INTERACTIVE)
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;
tsvals.save_profile = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
parasite = gimp_image_get_parasite (orig_image, "gimp-comment");
if (parasite)
{ {
image_comment = g_strndup (gimp_parasite_data (parasite), if (! save_dialog (orig_image, procedure, G_OBJECT (config),
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,
n_drawables == 1 ? gimp_drawable_has_alpha (drawables[0]) : TRUE, n_drawables == 1 ? gimp_drawable_has_alpha (drawables[0]) : TRUE,
image_is_monochrome (image), image_is_monochrome (image),
gimp_image_base_type (image) == GIMP_INDEXED, gimp_image_base_type (image) == GIMP_INDEXED,
image_is_multi_layer (image), image_is_multi_layer (image)))
&image_comment))
{ {
return gimp_procedure_new_return_values (procedure, GIMP_PDB_CANCEL, return gimp_procedure_new_return_values (procedure, GIMP_PDB_CANCEL,
NULL); NULL);
} }
break;
case GIMP_RUN_NONINTERACTIVE:
switch (GIMP_VALUES_GET_INT (args, 0))
{
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;
}
tsvals.save_transp_pixels = GIMP_VALUES_GET_BOOLEAN (args, 1);
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;
} }
switch (run_mode) switch (run_mode)
@ -409,68 +368,75 @@ tiff_save (GimpProcedure *procedure,
case GIMP_RUN_WITH_LAST_VALS: case GIMP_RUN_WITH_LAST_VALS:
{ {
GimpExportCapabilities capabilities; GimpExportCapabilities capabilities;
GimpCompression compression;
gboolean save_layers;
if (tsvals.compression == COMPRESSION_CCITTFAX3 || g_object_get (config,
tsvals.compression == COMPRESSION_CCITTFAX4) "compression", &compression,
/* G3/G4 are fax compressions. They only support monochrome "save-layers", &save_layers,
* images without alpha support. NULL);
*/
capabilities = GIMP_EXPORT_CAN_HANDLE_INDEXED; if (compression == GIMP_COMPRESSION_CCITTFAX3 ||
compression == GIMP_COMPRESSION_CCITTFAX4)
{
/* G3/G4 are fax compressions. They only support
* monochrome images without alpha support.
*/
capabilities = GIMP_EXPORT_CAN_HANDLE_INDEXED;
}
else else
capabilities = GIMP_EXPORT_CAN_HANDLE_RGB | {
GIMP_EXPORT_CAN_HANDLE_GRAY | capabilities = (GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_INDEXED | GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_ALPHA; GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
}
if (tsvals.save_layers && image_is_multi_layer (image)) if (save_layers && image_is_multi_layer (image))
capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS; capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS;
export = gimp_export_image (&image, &n_drawables, &drawables, "TIFF", capabilities); export = gimp_export_image (&image, &n_drawables, &drawables, "TIFF",
capabilities);
if (export == GIMP_EXPORT_CANCEL) if (export == GIMP_EXPORT_CANCEL)
return gimp_procedure_new_return_values (procedure, GIMP_PDB_CANCEL, return gimp_procedure_new_return_values (procedure, GIMP_PDB_CANCEL,
NULL); NULL);
} }
break; break;
default: default:
break; break;
} }
#if 0
/* FIXME */
if (n_drawables != 1 && tsvals.save_layers) if (n_drawables != 1 && tsvals.save_layers)
{ {
g_set_error (&error, G_FILE_ERROR, 0, g_set_error (&error, G_FILE_ERROR, 0,
_("\"Save layers\" option not set while trying to export multiple layers.")); _("\"Save layers\" option not set while trying to export multiple layers."));
return gimp_procedure_new_return_values (procedure, status = GIMP_PDB_CALLING_ERROR;
GIMP_PDB_CALLING_ERROR,
error);
} }
#endif
if (status == GIMP_PDB_SUCCESS) if (status == GIMP_PDB_SUCCESS)
{ {
gint saved_bpp; if (! save_image (file, image, orig_image, G_OBJECT (config), metadata,
&error))
if (save_image (file, &tsvals, image, orig_image, image_comment,
&saved_bpp, metadata, metadata_flags, &error))
{
/* Store mvals data */
gimp_set_data (SAVE_PROC, &tsvals, sizeof (TiffSaveVals));
}
else
{ {
status = GIMP_PDB_EXECUTION_ERROR; status = GIMP_PDB_EXECUTION_ERROR;
} }
} }
gimp_procedure_config_end_export (config, image, file, status);
g_object_unref (config);
if (export == GIMP_EXPORT_EXPORT) if (export == GIMP_EXPORT_EXPORT)
{ {
gimp_image_delete (image); gimp_image_delete (image);
g_free (drawables); g_free (drawables);
} }
if (metadata)
g_object_unref (metadata);
return gimp_procedure_new_return_values (procedure, status, error); return gimp_procedure_new_return_values (procedure, status, error);
} }
@ -514,3 +480,39 @@ image_is_multi_layer (GimpImage *image)
return (n_layers > 1); return (n_layers > 1);
} }
gint
gimp_compression_to_tiff_compression (GimpCompression compression)
{
switch (compression)
{
case GIMP_COMPRESSION_NONE: return COMPRESSION_NONE;
case GIMP_COMPRESSION_LZW: return COMPRESSION_LZW;
case GIMP_COMPRESSION_PACKBITS: return COMPRESSION_PACKBITS;
case GIMP_COMPRESSION_ADOBE_DEFLATE: return COMPRESSION_ADOBE_DEFLATE;
case GIMP_COMPRESSION_JPEG: return COMPRESSION_JPEG;
case GIMP_COMPRESSION_CCITTFAX3: return COMPRESSION_CCITTFAX3;
case GIMP_COMPRESSION_CCITTFAX4: return COMPRESSION_CCITTFAX4;
}
return COMPRESSION_NONE;
}
GimpCompression
tiff_compression_to_gimp_compression (gint compression)
{
switch (compression)
{
case COMPRESSION_NONE: return GIMP_COMPRESSION_NONE;
case COMPRESSION_LZW: return GIMP_COMPRESSION_LZW;
case COMPRESSION_PACKBITS: return GIMP_COMPRESSION_PACKBITS;
case COMPRESSION_DEFLATE: return GIMP_COMPRESSION_ADOBE_DEFLATE;
case COMPRESSION_ADOBE_DEFLATE: return GIMP_COMPRESSION_ADOBE_DEFLATE;
case COMPRESSION_OJPEG: return GIMP_COMPRESSION_JPEG;
case COMPRESSION_JPEG: return GIMP_COMPRESSION_JPEG;
case COMPRESSION_CCITTFAX3: return GIMP_COMPRESSION_CCITTFAX3;
case COMPRESSION_CCITTFAX4: return GIMP_COMPRESSION_CCITTFAX4;
}
return GIMP_COMPRESSION_NONE;
}

View File

@ -0,0 +1,25 @@
/* tiff for GIMP
* -Peter Mattis
*/
#ifndef __FILE_TIFF_H__
#define __FILE_TIFF_H__
typedef enum
{
GIMP_COMPRESSION_NONE,
GIMP_COMPRESSION_LZW,
GIMP_COMPRESSION_PACKBITS,
GIMP_COMPRESSION_ADOBE_DEFLATE,
GIMP_COMPRESSION_JPEG,
GIMP_COMPRESSION_CCITTFAX3,
GIMP_COMPRESSION_CCITTFAX4
} GimpCompression;
gint gimp_compression_to_tiff_compression (GimpCompression compression);
GimpCompression tiff_compression_to_gimp_compression (gint compression);
#endif /* __FILE_TIFF_H__ */

View File

@ -1,7 +1,6 @@
uidatadir = $(gimpdatadir)/ui/plug-ins uidatadir = $(gimpdatadir)/ui/plug-ins
uidata_DATA = \ uidata_DATA = \
plug-in-file-tiff.ui \
plug-in-metadata-editor.ui \ plug-in-metadata-editor.ui \
plug-in-metadata-editor-calendar.ui \ plug-in-metadata-editor-calendar.ui \
plug-in-metadata-viewer.ui plug-in-metadata-viewer.ui

View File

@ -1,5 +1,4 @@
plugin_ui = [ plugin_ui = [
'plug-in-file-tiff.ui',
'plug-in-metadata-editor-calendar.ui', 'plug-in-metadata-editor-calendar.ui',
'plug-in-metadata-editor.ui', 'plug-in-metadata-editor.ui',
'plug-in-metadata-viewer.ui', 'plug-in-metadata-viewer.ui',

View File

@ -1,172 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkBox" id="tiff_export_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">11</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkBox" id="radio_button_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="padding">3</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="save-layers">
<property name="label" translatable="yes">Save _layers</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="save-alpha">
<property name="label" translatable="yes">Save color _values from transparent pixels</property>
<property name="tooltip_text" translatable="yes">Colors are not stored premultiplied by the associated alpha</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="save-exif">
<property name="label" translatable="yes">S_ave Exif data</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="save-xmp">
<property name="label" translatable="yes">Save _XMP data</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="save-iptc">
<property name="label" translatable="yes">Save _IPTC data</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="save-thumbnail">
<property name="label" translatable="yes">Save _thumbnail</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="save-color-profile">
<property name="label" translatable="yes">Save color _profile</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkEntry" id="commentfield">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">6</property>
<property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="commentlabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Comment&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="padding">3</property>
<property name="position">12</property>
</packing>
</child>
</object>
</interface>

View File

@ -144,7 +144,6 @@ plug-ins/gimpressionist/utils.c
plug-ins/goat-exercises/goat-exercise-c.c plug-ins/goat-exercises/goat-exercise-c.c
plug-ins/goat-exercises/goat-exercise-py3.py plug-ins/goat-exercises/goat-exercise-py3.py
plug-ins/goat-exercises/goat-exercise-vala.vala plug-ins/goat-exercises/goat-exercise-vala.vala
[type: gettext/glade]plug-ins/ui/plug-in-file-tiff.ui
[type: gettext/glade]plug-ins/ui/plug-in-metadata-editor.ui [type: gettext/glade]plug-ins/ui/plug-in-metadata-editor.ui
[type: gettext/glade]plug-ins/ui/plug-in-metadata-viewer.ui [type: gettext/glade]plug-ins/ui/plug-in-metadata-viewer.ui
plug-ins/gradient-flare/gradient-flare.c plug-ins/gradient-flare/gradient-flare.c