mirror of https://github.com/GNOME/gimp.git
plug-ins: Enable export of original Duotone data
Optionally includes the previously saved Duotone color space data on PSD export. New load dialogue alerts user if duotone data was imported. New export dialogue appears if the image is still grayscale and the parasite exists. If selected, the mode is set to PSD_DUOTONE in the header and the original duotone data is written in the color space section.
This commit is contained in:
parent
6b3d69a3c5
commit
a3fb3ca110
|
@ -26,6 +26,7 @@
|
|||
#include <glib/gstdio.h>
|
||||
#include <zlib.h>
|
||||
#include <libgimp/gimp.h>
|
||||
#include <libgimp/gimpui.h>
|
||||
|
||||
#include "psd.h"
|
||||
#include "psd-util.h"
|
||||
|
@ -3268,3 +3269,50 @@ get_mask_format (PSDimage *img_a)
|
|||
|
||||
return format;
|
||||
}
|
||||
|
||||
void
|
||||
load_dialog (void)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *label;
|
||||
GtkWidget *vbox;
|
||||
gchar *label_text;
|
||||
|
||||
dialog = gimp_dialog_new (_("PSD Compatibility Notice"),
|
||||
"psd-compatibility-notice",
|
||||
NULL, 0, NULL, NULL,
|
||||
_("_OK"), GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
|
||||
gimp_window_set_transient (GTK_WINDOW (dialog));
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
|
||||
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
|
||||
vbox, TRUE, TRUE, 0);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
/* Duotone import notification */
|
||||
label_text = g_strdup_printf ("<b>%s</b>\n%s", _("Duotone Import"),
|
||||
_("Image will be imported as Grayscale.\n"
|
||||
"Duotone color space data has been saved\n"
|
||||
"and can be reapplied on export."));
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), label_text);
|
||||
|
||||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_yalign (GTK_LABEL (label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
g_free (label_text);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
/* run the dialog */
|
||||
gimp_dialog_run (GIMP_DIALOG (dialog));
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
|
|
@ -28,5 +28,7 @@ GimpImage * load_image (GFile *file,
|
|||
gboolean *profile_loaded,
|
||||
GError **error);
|
||||
|
||||
void load_dialog (void);
|
||||
|
||||
|
||||
#endif /* __PSD_LOAD_H__ */
|
||||
|
|
|
@ -132,13 +132,16 @@ static const gchar * psd_lmode_layer (GimpLayer *layer,
|
|||
static void reshuffle_cmap_write (guchar *mapGimp);
|
||||
|
||||
static void save_header (GOutputStream *output,
|
||||
GimpImage *image);
|
||||
GimpImage *image,
|
||||
gboolean export_duotone);
|
||||
|
||||
static void save_color_mode_data (GOutputStream *output,
|
||||
GimpImage *image);
|
||||
GimpImage *image,
|
||||
gboolean export_duotone);
|
||||
|
||||
static void save_resources (GOutputStream *output,
|
||||
GimpImage *image);
|
||||
GimpImage *image,
|
||||
gboolean export_duotone);
|
||||
|
||||
static void save_layer_and_mask (GOutputStream *output,
|
||||
GimpImage *image);
|
||||
|
@ -524,7 +527,8 @@ reshuffle_cmap_write (guchar *mapGimp)
|
|||
|
||||
static void
|
||||
save_header (GOutputStream *output,
|
||||
GimpImage *image)
|
||||
GimpImage *image,
|
||||
gboolean export_duotone)
|
||||
{
|
||||
IFDBG(1) g_debug ("Function: save_header\n"
|
||||
"\tRows: %d\n"
|
||||
|
@ -545,20 +549,42 @@ save_header (GOutputStream *output,
|
|||
write_gint32 (output, PSDImageData.image_height, "rows");
|
||||
write_gint32 (output, PSDImageData.image_width, "columns");
|
||||
write_gint16 (output, 8 * get_bpc (image), "depth");
|
||||
if (export_duotone)
|
||||
write_gint16 (output, PSD_DUOTONE, "mode");
|
||||
else
|
||||
write_gint16 (output, gimpBaseTypeToPsdMode (PSDImageData.baseType), "mode");
|
||||
}
|
||||
|
||||
static void
|
||||
save_color_mode_data (GOutputStream *output,
|
||||
GimpImage *image)
|
||||
GimpImage *image,
|
||||
gboolean export_duotone)
|
||||
{
|
||||
guchar *cmap;
|
||||
guchar *cmap_modified;
|
||||
gint i;
|
||||
gint32 nColors;
|
||||
GimpParasite *parasite = NULL;
|
||||
|
||||
IFDBG(1) g_debug ("Function: save_color_mode_data");
|
||||
|
||||
parasite = gimp_image_get_parasite (image, PSD_PARASITE_DUOTONE_DATA);
|
||||
if (export_duotone && parasite)
|
||||
{
|
||||
const guchar *parasite_data;
|
||||
guint32 parasite_size;
|
||||
|
||||
IFDBG(1) g_debug ("\tImage type: DUOTONE");
|
||||
|
||||
parasite_data = (const guchar *) gimp_parasite_get_data (parasite, ¶site_size);
|
||||
|
||||
write_gint32 (output, parasite_size, "color data length");
|
||||
xfwrite (output, parasite_data, parasite_size, "colormap");
|
||||
|
||||
gimp_parasite_free (parasite);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (PSDImageData.baseType)
|
||||
{
|
||||
case GIMP_INDEXED:
|
||||
|
@ -607,7 +633,8 @@ save_color_mode_data (GOutputStream *output,
|
|||
|
||||
static void
|
||||
save_resources (GOutputStream *output,
|
||||
GimpImage *image)
|
||||
GimpImage *image,
|
||||
gboolean export_duotone)
|
||||
{
|
||||
GList *iter;
|
||||
gint i;
|
||||
|
@ -885,8 +912,9 @@ save_resources (GOutputStream *output,
|
|||
|
||||
/* --------------- Write ICC profile data ------------------- */
|
||||
{
|
||||
GimpColorProfile *profile;
|
||||
GimpColorProfile *profile = NULL;
|
||||
|
||||
if (! export_duotone)
|
||||
profile = gimp_image_get_effective_color_profile (image);
|
||||
|
||||
if (profile)
|
||||
|
@ -1754,12 +1782,19 @@ clear_image_data (void)
|
|||
gboolean
|
||||
save_image (GFile *file,
|
||||
GimpImage *image,
|
||||
GObject *config,
|
||||
GError **error)
|
||||
{
|
||||
GOutputStream *output;
|
||||
GeglBuffer *buffer;
|
||||
GList *iter;
|
||||
GError *local_error = NULL;
|
||||
GimpParasite *parasite = NULL;
|
||||
gboolean config_duotone;
|
||||
|
||||
g_object_get (config,
|
||||
"duotone", &config_duotone,
|
||||
NULL);
|
||||
|
||||
IFDBG(1) g_debug ("Function: save_image");
|
||||
|
||||
|
@ -1777,6 +1812,22 @@ save_image (GFile *file,
|
|||
gimp_progress_init_printf (_("Exporting '%s'"),
|
||||
gimp_file_get_utf8_name (file));
|
||||
|
||||
/* If image is not grayscale or lacks Duotone color space parasite,
|
||||
* turn off "Export as Duotone".
|
||||
*/
|
||||
parasite = gimp_image_get_parasite (image, PSD_PARASITE_DUOTONE_DATA);
|
||||
if (parasite)
|
||||
{
|
||||
if (gimp_image_get_base_type (image) != GIMP_GRAY)
|
||||
config_duotone = FALSE;
|
||||
|
||||
gimp_parasite_free (parasite);
|
||||
}
|
||||
else
|
||||
{
|
||||
config_duotone = FALSE;
|
||||
}
|
||||
|
||||
get_image_data (image);
|
||||
|
||||
/* Need to check each of the layers size individually also */
|
||||
|
@ -1828,9 +1879,9 @@ save_image (GFile *file,
|
|||
IFDBG(1) g_debug ("\tFile '%s' has been opened",
|
||||
gimp_file_get_utf8_name (file));
|
||||
|
||||
save_header (output, image);
|
||||
save_color_mode_data (output, image);
|
||||
save_resources (output, image);
|
||||
save_header (output, image, config_duotone);
|
||||
save_color_mode_data (output, image, config_duotone);
|
||||
save_resources (output, image, config_duotone);
|
||||
|
||||
/* PSD format does not support layers in indexed images */
|
||||
|
||||
|
@ -2025,3 +2076,45 @@ image_get_all_layers (GimpImage *image,
|
|||
|
||||
return psd_layers;
|
||||
}
|
||||
|
||||
gboolean
|
||||
save_dialog (GimpImage *image,
|
||||
GimpProcedure *procedure,
|
||||
GObject *config)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *duotone_notice;
|
||||
gboolean run;
|
||||
|
||||
dialog = gimp_procedure_dialog_new (procedure,
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
_("Export Image as PSD"));
|
||||
|
||||
/* Profile label */
|
||||
duotone_notice = gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"duotone-notice",
|
||||
_("Duotone color space information "
|
||||
"from the original\nimported image "
|
||||
"will be used."));
|
||||
gtk_label_set_xalign (GTK_LABEL (duotone_notice), 0.0);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (duotone_notice), PANGO_ELLIPSIZE_END);
|
||||
gimp_label_set_attributes (GTK_LABEL (duotone_notice),
|
||||
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
|
||||
-1);
|
||||
|
||||
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"duotone-frame", "duotone", FALSE,
|
||||
"duotone-notice");
|
||||
|
||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"duotone-frame",
|
||||
NULL);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
return run;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
|
||||
gboolean save_image (GFile *file,
|
||||
GimpImage *image,
|
||||
GObject *config,
|
||||
GError **error);
|
||||
|
||||
gboolean save_dialog (GimpImage *image,
|
||||
GimpProcedure *procedure,
|
||||
GObject *config);
|
||||
|
||||
#endif /* __PSD_SAVE_H__ */
|
||||
|
|
|
@ -223,6 +223,13 @@ psd_create_procedure (GimpPlugIn *plug_in,
|
|||
"image/x-psd");
|
||||
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
|
||||
"psd");
|
||||
|
||||
GIMP_PROC_ARG_BOOLEAN (procedure, "duotone",
|
||||
"Export as _Duotone",
|
||||
"Export as a Duotone PSD file if Duotone color space information "
|
||||
"was attached to the image when originally imported.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
|
||||
return procedure;
|
||||
|
@ -240,6 +247,7 @@ psd_load (GimpProcedure *procedure,
|
|||
gboolean profile_loaded = FALSE;
|
||||
GimpImage *image;
|
||||
GimpMetadata *metadata;
|
||||
GimpParasite *parasite = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
gegl_init (NULL, NULL);
|
||||
|
@ -266,6 +274,17 @@ psd_load (GimpProcedure *procedure,
|
|||
GIMP_PDB_EXECUTION_ERROR,
|
||||
error);
|
||||
|
||||
/* If image was Duotone, notify user of compatibility */
|
||||
if (run_mode == GIMP_RUN_INTERACTIVE)
|
||||
{
|
||||
parasite = gimp_image_get_parasite (image, PSD_PARASITE_DUOTONE_DATA);
|
||||
if (parasite)
|
||||
{
|
||||
load_dialog ();
|
||||
gimp_parasite_free (parasite);
|
||||
}
|
||||
}
|
||||
|
||||
metadata = gimp_image_metadata_load_prepare (image, "image/x-psd",
|
||||
file, NULL);
|
||||
if (metadata)
|
||||
|
@ -338,14 +357,21 @@ psd_save (GimpProcedure *procedure,
|
|||
const GimpValueArray *args,
|
||||
gpointer run_data)
|
||||
{
|
||||
GimpProcedureConfig *config;
|
||||
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
||||
GimpMetadata *metadata;
|
||||
GimpMetadataSaveFlags metadata_flags;
|
||||
GimpExportReturn export = GIMP_EXPORT_IGNORE;
|
||||
GimpParasite *parasite = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
config = gimp_procedure_create_config (procedure);
|
||||
metadata = gimp_image_metadata_save_prepare (image,
|
||||
"image/x-psd",
|
||||
&metadata_flags);
|
||||
|
||||
switch (run_mode)
|
||||
{
|
||||
case GIMP_RUN_INTERACTIVE:
|
||||
|
@ -369,11 +395,25 @@ psd_save (GimpProcedure *procedure,
|
|||
break;
|
||||
}
|
||||
|
||||
metadata = gimp_image_metadata_save_prepare (image,
|
||||
"image/x-psd",
|
||||
&metadata_flags);
|
||||
if (run_mode == GIMP_RUN_INTERACTIVE)
|
||||
{
|
||||
/* Only show dialog if image is grayscale and duotone color space
|
||||
* information was attached from the original image imported
|
||||
*/
|
||||
parasite = gimp_image_get_parasite (image, PSD_PARASITE_DUOTONE_DATA);
|
||||
if (parasite)
|
||||
{
|
||||
if (gimp_image_get_base_type (image) == GIMP_GRAY)
|
||||
{
|
||||
if (! save_dialog (image, procedure, G_OBJECT (config)))
|
||||
return gimp_procedure_new_return_values (procedure, GIMP_PDB_CANCEL,
|
||||
NULL);
|
||||
}
|
||||
gimp_parasite_free (parasite);
|
||||
}
|
||||
}
|
||||
|
||||
if (save_image (file, image, &error))
|
||||
if (save_image (file, image, G_OBJECT (config), &error))
|
||||
{
|
||||
if (metadata)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue