[gimp/alxsa-duotone-psd-export] plug-ins: Enable export of original Duotone data
- From: Alx Sa <sawyeralex src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/alxsa-duotone-psd-export] plug-ins: Enable export of original Duotone data
- Date: Sun, 24 Jul 2022 16:36:36 +0000 (UTC)
commit e0aa5b31f6829a3fa9727d8b23054697c8ea6e5c
Author: Alx Sa <cmyk student gmail com>
Date: Sun Jul 24 16:36:35 2022 +0000
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.
plug-ins/file-psd/psd-load.c | 48 +++++++++++++++++++
plug-ins/file-psd/psd-load.h | 12 +++--
plug-ins/file-psd/psd-save.c | 112 ++++++++++++++++++++++++++++++++++++++-----
plug-ins/file-psd/psd-save.h | 10 ++--
plug-ins/file-psd/psd.c | 48 +++++++++++++++++--
5 files changed, 207 insertions(+), 23 deletions(-)
---
diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c
index 3ead2ff199..816d015bf4 100644
--- a/plug-ins/file-psd/psd-load.c
+++ b/plug-ins/file-psd/psd-load.c
@@ -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"
@@ -3221,3 +3222,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);
+}
diff --git a/plug-ins/file-psd/psd-load.h b/plug-ins/file-psd/psd-load.h
index 565f9ef750..cd49d95cfd 100644
--- a/plug-ins/file-psd/psd-load.h
+++ b/plug-ins/file-psd/psd-load.h
@@ -22,11 +22,13 @@
#define __PSD_LOAD_H__
-GimpImage * load_image (GFile *file,
- gboolean merged_image_only,
- gboolean *resolution_loaded,
- gboolean *profile_loaded,
- GError **error);
+GimpImage * load_image (GFile *file,
+ gboolean merged_image_only,
+ gboolean *resolution_loaded,
+ gboolean *profile_loaded,
+ GError **error);
+
+void load_dialog (void);
#endif /* __PSD_LOAD_H__ */
diff --git a/plug-ins/file-psd/psd-save.c b/plug-ins/file-psd/psd-save.c
index 4419e75c1c..279bbc0a46 100644
--- a/plug-ins/file-psd/psd-save.c
+++ b/plug-ins/file-psd/psd-save.c
@@ -132,10 +132,12 @@ 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);
@@ -524,7 +526,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 +548,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");
- write_gint16 (output, gimpBaseTypeToPsdMode (PSDImageData.baseType), "mode");
+ 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;
+ 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:
@@ -1754,12 +1779,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 +1809,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,8 +1876,8 @@ 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_header (output, image, config_duotone);
+ save_color_mode_data (output, image, config_duotone);
save_resources (output, image);
/* PSD format does not support layers in indexed images */
@@ -2025,3 +2073,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;
+}
diff --git a/plug-ins/file-psd/psd-save.h b/plug-ins/file-psd/psd-save.h
index a55792ea8b..26d735df74 100644
--- a/plug-ins/file-psd/psd-save.h
+++ b/plug-ins/file-psd/psd-save.h
@@ -19,9 +19,13 @@
#define __PSD_SAVE_H__
-gboolean save_image (GFile *file,
- GimpImage *image,
- GError **error);
+gboolean save_image (GFile *file,
+ GimpImage *image,
+ GObject *config,
+ GError **error);
+gboolean save_dialog (GimpImage *image,
+ GimpProcedure *procedure,
+ GObject *config);
#endif /* __PSD_SAVE_H__ */
diff --git a/plug-ins/file-psd/psd.c b/plug-ins/file-psd/psd.c
index 4e5b60e2f6..14e63872ac 100644
--- a/plug-ins/file-psd/psd.c
+++ b/plug-ins/file-psd/psd.c
@@ -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)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]