summaryrefslogtreecommitdiff
path: root/gs
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2010-04-28 21:43:24 +0000
committerMichael Vrhel <michael.vrhel@artifex.com>2010-04-28 21:43:24 +0000
commitf509e55e0962e90d0a4e31061575859eaf9f0094 (patch)
treea21b7e778dbe6e69e588833e1fdf571e8e1cea02 /gs
parentdc7446fca824642c71002157650cf4a421feb3fc (diff)
With this commit we now have icc color management for CMYK components when they are members of a DeviceN color space. To understand why this is needed, consider the example where I have a device with CMYK + O and I have a DeviceN color in the document that is specified for any set of these colorants, and suppose that I let them pass through without any color management. This is probably not the desired effect since I could have a DeviceN color fill that had 10% C, 20% M 0% Y 0% K and 0% O. I would like this to look the same as a CMYK color that will be color managed and specified with 10% C, 20% M 0% Y 0% K. Hence the CMYK values should go through the same color management as a stand alone CMYK value. This feature has been requested to me by several customers in their feedback of the icc development.
git-svn-id: http://svn.ghostscript.com/ghostscript/branches/icc_work@11147 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs')
-rw-r--r--gs/base/gxcmap.c88
-rw-r--r--gs/base/lib.mak3
2 files changed, 84 insertions, 7 deletions
diff --git a/gs/base/gxcmap.c b/gs/base/gxcmap.c
index 29cb91606..32268d547 100644
--- a/gs/base/gxcmap.c
+++ b/gs/base/gxcmap.c
@@ -28,7 +28,9 @@
#include "gxdither.h"
#include "gxcdevn.h"
#include "string_.h"
-#include "gsnamecl.h" /* Custom color call back define */
+#include "gsiccmanage.h"
+#include "gdevdevn.h"
+#include "gsicccache.h"
/* Structure descriptor */
public_st_device_color();
@@ -1162,6 +1164,56 @@ cmap_separation_direct(frac all, gx_device_color * pdc, const gs_imager_state *
cmap_separation_halftoned(all, pdc, pis, dev, select);
}
+/* Routines for handling CM of CMYK components of a DeviceN color space */
+static bool
+devicen_has_cmyk(gx_device * dev)
+{
+ gs_devn_params *devn_params;
+ devn_params = dev_proc(dev, ret_devn_params)(dev);
+
+ if (devn_params == NULL) {
+ return false;
+ }
+ return(devn_params->num_std_colorant_names == 4);
+}
+
+static int
+devicen_icc_cmyk(frac cm_comps[], const gs_imager_state * pis)
+{
+ gsicc_link_t *icc_link;
+ gsicc_rendering_param_t rendering_params;
+ unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS];
+ unsigned short psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
+ int k;
+ unsigned short *psrc_temp;
+
+ /* Define the rendering intents. */
+ rendering_params.black_point_comp = BP_ON;
+ rendering_params.object_type = GS_PATH_TAG;
+ rendering_params.rendering_intent = pis->renderingintent;
+ /* Sigh, frac to full 16 bit. Need to clean this up */
+ for (k = 0; k < 4; k++){
+ psrc[k] = frac2cv(cm_comps[k]);
+ }
+ icc_link = gsicc_get_link_profile(pis, pis->icc_manager->default_cmyk,
+ pis->icc_manager->device_profile,
+ &rendering_params, pis->memory, false);
+ /* Transform the color */
+ if (icc_link->is_identity) {
+ psrc_temp = &(psrc[0]);
+ } else {
+ /* Transform the color */
+ psrc_temp = &(psrc_cm[0]);
+ gscms_transform_color(icc_link, psrc, psrc_temp, 2, NULL);
+ }
+ /* This needs to be optimized */
+ for (k = 0; k < 4; k++){
+ cm_comps[k] = float2frac(((float) psrc_temp[k])/65535.0);
+ }
+ /* Release the link */
+ gsicc_release_link(icc_link);
+ return(0);
+}
/* ------ DeviceN color mapping */
@@ -1176,12 +1228,17 @@ cmap_devicen_halftoned(const frac * pcc,
{
int i, ncomps = dev->color_info.num_components;
frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ int code;
/* map to the color model */
for (i=0; i < ncomps; i++)
cm_comps[i] = 0;
map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps);
-
+ /* See comments in cmap_devicen_direct for details on below operations */
+ if (devicen_has_cmyk(dev) &&
+ pis->icc_manager->device_profile->data_cs == gsCMYK) {
+ code = devicen_icc_cmyk(cm_comps, pis);
+ }
/* apply the transfer function(s); convert to color values */
if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
for (i = 0; i < ncomps; i++)
@@ -1193,7 +1250,6 @@ cmap_devicen_halftoned(const frac * pcc,
(frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
/* We need to finish halftoning */
-
if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht,
&pis->screen_phase[select]) == 1)
gx_color_load_select(pdc, pis, dev, select);
@@ -1212,12 +1268,34 @@ cmap_devicen_direct(const frac * pcc,
frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
gx_color_index color;
+ int code;
+ /* See the comment below */
/* map to the color model */
for (i=0; i < ncomps; i++)
cm_comps[i] = 0;
map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps);;
-
+ /* Check if we have the standard colorants. If yes, then we will apply
+ ICC color management to those colorants. To understand why, consider
+ the example where I have a Device with CMYK + O and I have a
+ DeviceN color in the document that is specified for any set of
+ these colorants, and suppose that I let them pass through
+ witout any color management. This is probably not the
+ desired effect since I could have a DeviceN color fill that had 10% C,
+ 20% M 0% Y 0% K and 0% O. I would like this to look the same
+ as a CMYK color that will be color managed and specified with 10% C,
+ 20% M 0% Y 0% K. Hence the CMYK values should go through the same
+ color management as a stand alone CMYK value. */
+ if (devicen_has_cmyk(dev) &&
+ pis->icc_manager->device_profile->data_cs == gsCMYK) {
+ /* We need to do a CMYK to CMYK conversion here. This will always
+ use the default CMYK profile and the device's output profile.
+ We probably need to add some checking here
+ and possibly permute the colorants, much as is done on the input
+ side for the case when we add DeviceN icc source profiles for use
+ in PDF and PS data. */
+ code = devicen_icc_cmyk(cm_comps, pis);
+ }
/* apply the transfer function(s); convert to color values */
if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
for (i = 0; i < ncomps; i++)
@@ -1227,10 +1305,8 @@ cmap_devicen_direct(const frac * pcc,
for (i = 0; i < ncomps; i++)
cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
(frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
-
/* encode as a color index */
color = dev_proc(dev, encode_color)(dev, cv);
-
/* check if the encoding was successful; we presume failure is rare */
if (color != gx_no_color_index)
color_set_pure(pdc, color);
diff --git a/gs/base/lib.mak b/gs/base/lib.mak
index 7923187e5..54506eae5 100644
--- a/gs/base/lib.mak
+++ b/gs/base/lib.mak
@@ -594,7 +594,8 @@ $(GLOBJ)gxcmap.$(OBJ) : $(GLSRC)gxcmap.c $(GXERR)\
$(gsccolor_h)\
$(gxalpha_h) $(gxcspace_h) $(gxfarith_h) $(gxfrac_h)\
$(gxdcconv_h) $(gxdevice_h) $(gxcmap_h) $(gsnamecl_h) $(gxlum_h)\
- $(gzstate_h) $(gxdither_h) $(gxcdevn_h) $(string__h)
+ $(gzstate_h) $(gxdither_h) $(gxcdevn_h) $(string__h)\
+ $(gsiccmanage_h) $(gdevdevn_h) $(gsicccache_h)
$(GLCC) $(GLO_)gxcmap.$(OBJ) $(C_) $(GLSRC)gxcmap.c
$(GLOBJ)gxcpath.$(OBJ) : $(GLSRC)gxcpath.c $(GXERR)\