[gimp/gimp-2-10] Add naive support for CMYK u8 PSD files
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] Add naive support for CMYK u8 PSD files
- Date: Fri, 21 Feb 2020 11:34:10 +0000 (UTC)
commit 9faef1b7ad5779a9cba21ef9345ad75daab6fe9f
Author: Massimo Valentini <mvalentini src gnome org>
Date: Tue Dec 1 11:30:22 2015 +0100
Add naive support for CMYK u8 PSD files
plug-ins/file-psd/psd-image-res-load.c | 16 +++-
plug-ins/file-psd/psd-load.c | 137 ++++++++++++++++++++++++++++++++-
plug-ins/file-psd/psd.h | 4 +
3 files changed, 150 insertions(+), 7 deletions(-)
---
diff --git a/plug-ins/file-psd/psd-image-res-load.c b/plug-ins/file-psd/psd-image-res-load.c
index 7949c6ca52..23dec2871e 100644
--- a/plug-ins/file-psd/psd-image-res-load.c
+++ b/plug-ins/file-psd/psd-image-res-load.c
@@ -196,6 +196,7 @@ static gint load_resource_1033 (const PSDimageres *res_a,
GError **error);
static gint load_resource_1039 (const PSDimageres *res_a,
+ PSDimage *img_a,
gint32 image_id,
FILE *f,
GError **error);
@@ -368,7 +369,7 @@ load_image_resource (PSDimageres *res_a,
break;
case PSD_ICC_PROFILE:
- if (! load_resource_1039 (res_a, image_id, f, error))
+ if (! load_resource_1039 (res_a, img_a, image_id, f, error))
*profile_loaded = TRUE;
break;
@@ -1105,6 +1106,7 @@ load_resource_1033 (const PSDimageres *res_a,
static gint
load_resource_1039 (const PSDimageres *res_a,
+ PSDimage *img_a,
gint32 image_id,
FILE *f,
GError **error)
@@ -1128,8 +1130,16 @@ load_resource_1039 (const PSDimageres *res_a,
NULL);
if (profile)
{
- gimp_image_set_color_profile (image_id, profile);
- g_object_unref (profile);
+ if (img_a->color_mode == PSD_CMYK &&
+ gimp_color_profile_is_cmyk (profile))
+ {
+ img_a->cmyk_profile = profile;
+ }
+ else
+ {
+ gimp_image_set_color_profile (image_id, profile);
+ g_object_unref (profile);
+ }
}
g_free (icc_profile);
diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c
index cc1487c05e..fefae1708c 100644
--- a/plug-ins/file-psd/psd-load.c
+++ b/plug-ins/file-psd/psd-load.c
@@ -126,6 +126,8 @@ load_image (const gchar *filename,
gint32 image_id = -1;
GError *error = NULL;
+ img_a.cmyk_transform = img_a.cmyk_transform_alpha = NULL;
+ img_a.cmyk_profile = NULL;
/* ----- Open PSD file ----- */
if (g_stat (filename, &st) == -1)
return -1;
@@ -329,6 +331,7 @@ read_header_block (PSDimage *img_a,
&& img_a->color_mode != PSD_INDEXED
&& img_a->color_mode != PSD_RGB
&& img_a->color_mode != PSD_MULTICHANNEL
+ && img_a->color_mode != PSD_CMYK
&& img_a->color_mode != PSD_DUOTONE)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
@@ -337,6 +340,17 @@ read_header_block (PSDimage *img_a,
return -1;
}
+ if (img_a->color_mode == PSD_CMYK)
+ {
+ if (img_a->bps != 8)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Unsupported color mode: %s"),
+ get_psd_color_mode_name (img_a->color_mode));
+ return -1;
+ }
+ }
+
/* Warning for unsupported bit depth */
switch (img_a->bps)
{
@@ -994,6 +1008,7 @@ create_gimp_image (PSDimage *img_a,
img_a->base_type = GIMP_INDEXED;
break;
+ case PSD_CMYK:
case PSD_RGB:
img_a->base_type = GIMP_RGB;
break;
@@ -1017,7 +1032,10 @@ create_gimp_image (PSDimage *img_a,
case 8:
case 1:
- precision = GIMP_PRECISION_U8_GAMMA;
+ if (img_a->color_mode == PSD_CMYK)
+ precision = GIMP_PRECISION_FLOAT_GAMMA;
+ else
+ precision = GIMP_PRECISION_U8_GAMMA;
break;
default:
@@ -1112,6 +1130,72 @@ add_image_resources (gint32 image_id,
return 0;
}
+static guchar *
+psd_convert_cmyk_to_srgb (PSDimage *img_a,
+ guchar *dst,
+ guchar *src,
+ gint width,
+ gint height,
+ gboolean alpha)
+{
+ if (img_a->cmyk_profile)
+ {
+ if (alpha)
+ {
+ if (! img_a->cmyk_transform_alpha)
+ {
+ GimpColorProfile *srgb = gimp_color_profile_new_rgb_srgb ();
+
+ img_a->cmyk_transform_alpha = gimp_color_transform_new (img_a->cmyk_profile, babl_format
("cmykA u8"),
+ srgb, babl_format ("R'G'B'A float"),
+ 0, 0);
+
+ g_object_unref (srgb);
+ }
+
+ gimp_color_transform_process_pixels (img_a->cmyk_transform_alpha,
+ babl_format ("cmykA u8"),
+ src,
+ babl_format ("R'G'B'A float"),
+ dst,
+ width * height);
+ }
+ else
+ {
+ if (! img_a->cmyk_transform)
+ {
+ GimpColorProfile *srgb = gimp_color_profile_new_rgb_srgb ();
+
+ img_a->cmyk_transform = gimp_color_transform_new (img_a->cmyk_profile, babl_format ("cmyk u8"),
+ srgb, babl_format ("R'G'B' float"),
+ 0, 0);
+
+ g_object_unref (srgb);
+ }
+
+ gimp_color_transform_process_pixels (img_a->cmyk_transform_alpha,
+ babl_format ("cmyk u8"),
+ src,
+ babl_format ("R'G'B' float"),
+ dst,
+ width * height);
+ }
+ }
+ else
+ {
+ const Babl *fish;
+
+ if (alpha)
+ fish = babl_fish ("cmykA u8", "R'G'B'A float");
+ else
+ fish = babl_fish ("cmyk u8", "R'G'B' float");
+
+ babl_process (fish, src, dst, width * height);
+ }
+
+ return (guchar*) dst;
+}
+
static gint
add_layers (gint32 image_id,
PSDimage *img_a,
@@ -1545,6 +1629,48 @@ add_layers (gint32 image_id,
gint src_step = bps;
gint dst_step = bps * layer_channels;
+ if (img_a->color_mode == PSD_CMYK)
+ {
+ guchar *cmyk = g_new (guchar, layer_channels * iter->length);
+
+ for (cidx = 0; cidx < layer_channels; ++cidx)
+ {
+ gint b, y, x;
+
+ if (roi->x == 0 && roi->y == 0)
+ IFDBG(3) g_debug ("Start channel %d", channel_idx[cidx]);
+
+ for (b = 0; b < bps; ++b)
+ {
+ guint8 *dst = &cmyk[cidx * bps + b];
+
+ for (y = 0; y < roi->height; y++)
+ {
+ const guint8 *src;
+
+ src = (const guint8 *)
+ &lyr_chn[channel_idx[cidx]]->data[
+ ((roi->y + y) * l_w +
+ roi->x) * bps +
+ b];
+
+ for (x = 0; x < roi->width; ++x)
+ {
+ *dst = *src;
+
+ src += src_step;
+ dst += dst_step;
+ }
+ }
+ }
+ }
+
+ psd_convert_cmyk_to_srgb (img_a, dst0, cmyk, roi->width, roi->height, alpha);
+
+ g_free (cmyk);
+ continue;
+ }
+
for (cidx = 0; cidx < layer_channels; ++cidx)
{
gint b;
@@ -1864,11 +1990,14 @@ add_merged_image (gint32 image_id,
gimp_image_insert_layer (image_id, layer_id, -1, 0);
buffer = gimp_drawable_get_buffer (layer_id);
+ if (img_a->color_mode == PSD_CMYK)
+ img_a->color_mode = PSD_RGB;
+
gegl_buffer_set (buffer,
GEGL_RECTANGLE (0, 0,
gegl_buffer_get_width (buffer),
gegl_buffer_get_height (buffer)),
- 0, get_layer_format (img_a, img_a->transparency),
+ 0, get_layer_format (img_a, (base_channels % 2) == 0),
pixels, GEGL_AUTO_ROWSTRIDE);
/* Merged image data is blended against white. Unblend it. */
@@ -2378,7 +2507,7 @@ get_layer_format (PSDimage *img_a,
case 8:
case 1:
- format = babl_format ("R'G'B' u8");
+ format = babl_format (img_a->color_mode == PSD_CMYK ? "R'G'B' float" : "R'G'B' u8");
break;
default:
@@ -2400,7 +2529,7 @@ get_layer_format (PSDimage *img_a,
case 8:
case 1:
- format = babl_format ("R'G'B'A u8");
+ format = babl_format (img_a->color_mode == PSD_CMYK ? "R'G'B'A float" : "R'G'B'A u8");
break;
default:
diff --git a/plug-ins/file-psd/psd.h b/plug-ins/file-psd/psd.h
index 50f8349a5f..724609dd09 100644
--- a/plug-ins/file-psd/psd.h
+++ b/plug-ins/file-psd/psd.h
@@ -673,6 +673,10 @@ typedef struct
guint32 *alpha_id; /* Alpha channel ids (tattoos) */
guint16 alpha_id_count; /* Number of alpha channel id items */
guint16 quick_mask_id; /* Channel number containing quick mask */
+
+ GimpColorProfile *cmyk_profile;
+ gpointer cmyk_transform;
+ gpointer cmyk_transform_alpha;
} PSDimage;
/* Public functions */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]