summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2015-02-23 12:18:01 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2015-02-23 15:56:12 -0800
commit1dca5f29bf59d3071021a3ba4b7378e60d0e7a10 (patch)
treece291b8290b88a54a39e6b558ae0e6dfd1eaab27
parent46b59d18a8f4d204e83327e135c17657caefde3a (diff)
downloadghostpdl-1dca5f29bf59d3071021a3ba4b7378e60d0e7a10.tar.gz
Fixes for named color support
A few minor fixes for named color support including the detection of the None colorant in the DeviceN list of colorants. Making sure that the equivalent CMYK color is correctly computed. Make sure that all the colorants in the device are cleared out prior to setting the ones associated with the device profile in the example code given in gsicc_transform_named_color.
-rw-r--r--gs/base/gsequivc.c27
-rw-r--r--gs/base/gsequivc.h4
-rw-r--r--gs/base/gsicc_cache.c79
-rw-r--r--gs/base/gxcmap.c61
4 files changed, 127 insertions, 44 deletions
diff --git a/gs/base/gsequivc.c b/gs/base/gsequivc.c
index 2fbb1f622..5008e0efc 100644
--- a/gs/base/gsequivc.c
+++ b/gs/base/gsequivc.c
@@ -199,7 +199,6 @@ update_ICC_spot_equivalent_cmyk_colors(gx_device * pdev,
}
}
-
static void
update_DeviceN_spot_equivalent_cmyk_colors(gx_device * pdev,
const gs_state * pgs, const gs_color_space * pcs,
@@ -291,6 +290,9 @@ update_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs,
int code;
code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
+ if (code < 0)
+ return;
+
/* If all of the color_info is valid then there is nothing to do. */
if (pparams->all_color_info_valid)
return;
@@ -332,7 +334,7 @@ update_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs,
static void
save_spot_equivalent_cmyk_color(int sep_num,
- equivalent_cmyk_color_params * pparams, frac cmyk[4])
+ equivalent_cmyk_color_params * pparams, const frac cmyk[4])
{
pparams->color[sep_num].c = cmyk[0];
pparams->color[sep_num].m = cmyk[1];
@@ -433,11 +435,19 @@ cmap_separation_capture_cmyk_color(frac all, gx_device_color * pdc,
dmprintf(pis->memory, "cmap_separation_capture_cmyk_color - this routine should not be executed\n");
}
+/* The call to this is actually going to occur if we happen to be using a
+ named color profile and doing a replacement. Since the destination profile
+ will have been CMYK based during the swap out to find the equivalent color, we can
+ go ahead and just grab the cmyk portion */
static void
cmap_devicen_capture_cmyk_color(const frac * pcc, gx_device_color * pdc,
const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
{
- dmprintf(pis->memory, "cmap_devicen_capture_cmyk_color - this routine should not be executed\n");
+ equivalent_cmyk_color_params * pparams =
+ ((color_capture_device *)dev)->pequiv_cmyk_colors;
+ int sep_num = ((color_capture_device *)dev)->sep_num;
+
+ save_spot_equivalent_cmyk_color(sep_num, pparams, pcc);
}
/*
@@ -453,7 +463,6 @@ capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs,
color_capture_device temp_device = { 0 };
gx_device_color dev_color;
gsicc_rendering_param_t render_cond;
- int code;
cmm_dev_profile_t *dev_profile;
cmm_profile_t *curr_output_profile;
cmm_dev_profile_t temp_profile = { /* Initialize to 0's/NULL's */
@@ -467,7 +476,7 @@ capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs,
{ 0 } /* rc_header */
};
- code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
+ dev_proc(pdev, get_profile)(pdev, &dev_profile);
gsicc_extract_profile(pdev->graphics_type_tag,
dev_profile, &(curr_output_profile), &render_cond);
/*
@@ -521,3 +530,11 @@ capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs,
pcs->type->remap_color (pcc, pcs, &dev_color, &temp_state,
(gx_device *)&temp_device, gs_color_select_texture);
}
+
+/* Used for detecting if we are trying to find the equivalant color during
+ named color replacement */
+bool
+named_color_equivalent_cmyk_colors(const gs_imager_state * pis)
+{
+ return pis->cmap_procs == &cmap_capture_cmyk_color;
+}
diff --git a/gs/base/gsequivc.h b/gs/base/gsequivc.h
index b5dd1c689..ebd50fb49 100644
--- a/gs/base/gsequivc.h
+++ b/gs/base/gsequivc.h
@@ -61,4 +61,8 @@ void capture_spot_equivalent_cmyk_colors(gx_device * pdev,
const gs_color_space * pcs, int sep_num,
equivalent_cmyk_color_params * pparams);
+/* Used in named color replacement to detect that we are doing the equivalent
+ computation */
+bool named_color_equivalent_cmyk_colors(const gs_imager_state * pis);
+
#endif /* define gsequivc_INCLUDED */
diff --git a/gs/base/gsicc_cache.c b/gs/base/gsicc_cache.c
index ffd5163dc..d0c118e02 100644
--- a/gs/base/gsicc_cache.c
+++ b/gs/base/gsicc_cache.c
@@ -1123,7 +1123,8 @@ gsicc_named_profile_release(void *ptr)
}
}
-/* Function returns -1 if name not found. Otherwise transform the color. */
+/* Function returns -1 if a name is not found. Otherwise it will transform
+ the named colors and return 0 */
int
gsicc_transform_named_color(const float tint_values[],
gsicc_namedcolor_t color_names[],
@@ -1137,6 +1138,7 @@ gsicc_transform_named_color(const float tint_values[],
unsigned int num_entries;
cmm_profile_t *named_profile;
gsicc_namedcolortable_t *namedcolor_table;
+ int num_nonnone_names;
int k,j,n;
float lab[3];
char *buffptr;
@@ -1258,33 +1260,47 @@ gsicc_transform_named_color(const float tint_values[],
}
/* Go through each of our spot names, getting the color value for
each one. */
+ num_nonnone_names = num_names;
for (n = 0; n < num_names; n++) {
- /* Search our structure for the color name */
+ /* Search our structure for the color name. Ignore the None
+ colorant names. All is a special case that someone may
+ want to detect and do some special handling for. In this
+ particular example we would punt with All and let the default
+ methods handle it */
found_match = false;
- for (k = 0; k < num_entries; k++) {
- if (color_names[n].name_size ==
- namedcolor_table->named_color[k].name_size) {
- if( strncmp((const char *) namedcolor_table->named_color[k].colorant_name,
- (const char *) color_names[n].colorant_name, color_names[n].name_size) == 0) {
- found_match = true;
- break;
+
+ if (strncmp("None", (const char *)color_names[n].colorant_name,
+ color_names[n].name_size) == 0) {
+ num_nonnone_names--;
+ } else {
+ /* Colorant was not None */
+ for (k = 0; k < num_entries; k++) {
+ if (color_names[n].name_size ==
+ namedcolor_table->named_color[k].name_size) {
+ if (strncmp((const char *)namedcolor_table->named_color[k].colorant_name,
+ (const char *)color_names[n].colorant_name, color_names[n].name_size) == 0) {
+ found_match = true;
+ break;
+ }
}
}
- }
- if (found_match) {
- indices[n] = k;
- } else {
- /* We do not know this colorant, return -1 */
- return -1;
+ if (found_match) {
+ indices[n] = k;
+ } else {
+ /* We do not know this colorant, return -1 */
+ return -1;
+ }
}
}
+ if (num_nonnone_names < 1)
+ return -1; /* No non-None colorants. */
/* We have all the colorants. Lets go through and see if we can
make something that looks like a merge of the various ones */
/* Apply tint, blend LAB values. Note that we may have wanted to
check if we even want to do this. It is possible that the
device directly supports this particular colorant. One may
want to check the alt tint transform boolean */
- for (n = 0; n < num_names; n++) {
+ for (n = 0; n < num_nonnone_names; n++) {
for (j = 0; j < 3; j++) {
temp = (float) namedcolor_table->named_color[indices[n]].lab[j] * tint_values[n]
+ (float) white_lab[j] * (1.0 - tint_values[n]);
@@ -1302,11 +1318,20 @@ gsicc_transform_named_color(const float tint_values[],
psrc[2] = (psrc[2] + temp_lab[2]) / 2; /* b* */
}
}
- /* Push LAB value through CMM to get device values */
+ /* Push LAB value through CMM to get CMYK device values */
+ /* Note that there are several options here. You could us an NCLR
+ icc profile to compute the device colors that you want. For,
+ example if the output device had an NCLR profile.
+ However, what you MUST do here is set ALL the device values.
+ Hence, below we initialize all of them to zero and in this
+ particular example, set only the ones that were output from
+ the device profile */
if ( gs_output_profile != NULL ) {
curr_output_profile = gs_output_profile;
} else {
- /* Use the device profile */
+ /* Use the device profile. Note if one was not set for the
+ device, the default CMYK profile is used. Note that
+ if we specified and NCLR profile it will be used here */
code = dev_proc(dev, get_profile)(dev, &dev_profile);
gsicc_extract_profile(dev->graphics_type_tag,
dev_profile, &(curr_output_profile),
@@ -1324,17 +1349,28 @@ gsicc_transform_named_color(const float tint_values[],
(icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2);
}
gsicc_release_link(icc_link);
- for ( k = 0; k < curr_output_profile->num_comps; k++){
+
+ /* Clear out ALL the color values */
+ for (k = 0; k < dev->color_info.num_components; k++){
+ device_values[k] = 0;
+ }
+ /* Set only the values that came from the profile. By default
+ this would generally be just CMYK values. For the equivalent
+ color computation case it certainly will be. If someone
+ specified an NCLR profile it could be more. Note that if an
+ NCLR profile is being used we will want to make sure the colorant
+ order is correct */
+ for (k = 0; k < curr_output_profile->num_comps; k++){
device_values[k] = psrc_temp[k];
}
return 0;
}
}
- return -1;
+ return -1; /* Color not found */
}
/* Used by gs to notify the ICC manager that we are done with this link for now */
-/* This may release elements waiting on a icc_link_cache slot */
+/* This may release elements waiting on an icc_link_cache slot */
void
gsicc_release_link(gsicc_link_t *icclink)
{
@@ -1387,7 +1423,6 @@ gsicc_release_link(gsicc_link_t *icclink)
}
/* Used to initialize the buffer description prior to color conversion */
-
void
gsicc_init_buffer(gsicc_bufferdesc_t *buffer_desc, unsigned char num_chan, unsigned char bytes_per_chan,
bool has_alpha, bool alpha_first, bool is_planar, int plane_stride, int row_stride,
diff --git a/gs/base/gxcmap.c b/gs/base/gxcmap.c
index 2123136ae..a43f16d39 100644
--- a/gs/base/gxcmap.c
+++ b/gs/base/gxcmap.c
@@ -655,25 +655,52 @@ gs_color_select_t select)
"gx_remap_named_color");
if (code == 0) {
- /* Named color was found and set. Finish the job */
- for (k = 0; k < num_des_comps; k++){
+ /* Named color was found and set. Note that gsicc_transform_named_color
+ MUST set ALL the colorant values AND they must be in the proper
+ order already. If we have specified the colorants with
+ -sICCOutputColors (i.e. if you are using an NCLR output profile) then
+ we should be good. If not or if instead one used SeparationColorNames and
+ SeparationOrder to set up the device, then we need to make a copy
+ of the imager state and make sure that we set color_component_map is
+ properly set up for the gx_remap_concrete_devicen proc. */
+ for (k = 0; k < num_des_comps; k++)
conc[k] = float2frac(((float)device_values[k]) / 65535.0);
+
+ /* If we are looking to create the equivalent CMYK value then no need
+ to worry about NCLR profiles or about altering the colorant map */
+ if (!named_color_equivalent_cmyk_colors(pis)) {
+ /* We need to apply transfer functions, possibily halftone and
+ encode the color for the device. To get proper mapping of the
+ colors to the device positions, you MUST specify -sICCOutputColors
+ which will enumerate the positions of the colorants and enable
+ proper color management for the CMYK portions IF you are using
+ an NCLR output profile. */
+ code = dev_proc(dev, get_profile)(dev, &dev_profile);
+ /* Check if the profile is DeviceN (NCLR) */
+ if (dev_profile->device_profile[0]->data_cs == gsNCHANNEL) {
+ if (dev_profile->spotnames == NULL)
+ return false;
+ if (!dev_profile->spotnames->equiv_cmyk_set) {
+ /* Note that if the improper NCLR profile is used, then the
+ composite preview will be wrong. */
+ code = gsicc_set_devicen_equiv_colors(dev, pis, dev_profile->device_profile[0]);
+ dev_profile->spotnames->equiv_cmyk_set = true;
+ }
+ gx_remap_concrete_devicen(conc, pdc, pis, dev, select);
+ } else {
+ gs_imager_state temp_state = *((const gs_imager_state *)pis);
+
+ /* No NCLR profile with spot names. So set up the
+ color_component_map in the imager state. Again, note that
+ gsicc_transform_named_color must have set ALL the device
+ colors */
+ for (i = 0; i < temp_state.color_component_map.num_colorants; i++)
+ temp_state.color_component_map.color_map[i] = i;
+ gx_remap_concrete_devicen(conc, pdc, &temp_state, dev, select);
+ }
+ } else {
+ gx_remap_concrete_devicen(conc, pdc, pis, dev, select);
}
- /* We need to apply transfer functions, possibily halftone and
- encode the color for the device. To get proper mapping of the
- colors to the device positions, you MUST specify -sICCOutputColors
- which will enumerate the positions of the colorants and enable
- proper color management for the CMYK portions */
- code = dev_proc(dev, get_profile)(dev, &dev_profile);
- if (dev_profile->spotnames == NULL)
- return false;
- if (!dev_profile->spotnames->equiv_cmyk_set) {
- /* Note that if the improper N-CLR profile is used, then the
- composite preview will be wrong. */
- code = gsicc_set_devicen_equiv_colors(dev, pis, dev_profile->device_profile[0]);
- dev_profile->spotnames->equiv_cmyk_set = true;
- }
- gx_remap_concrete_devicen(conc, pdc, pis, dev, select);
/* Save original color space and color info into dev color */
i = any_abs(i);
for (i--; i >= 0; i--)