summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2015-02-20 15:05:51 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2015-02-20 22:50:46 -0800
commit6ab5713f556bde0be38fa411e2eb1d25eb73e2c5 (patch)
tree42bc9fb37527a5b915c7688f90474256da608648
parent033cf566b74c7e12bfb82d9b63a7bc680c51c5f8 (diff)
downloadghostpdl-6ab5713f556bde0be38fa411e2eb1d25eb73e2c5.tar.gz
Use different remap proc for indexed color space when dealing with named colors
Currently the Index color space uses gx_default_remap_color for its remap procedure. This is a problem for when we are dealing with an index color whose base space is DeviceN and we are doing named color replacement in our color management. To fix this, we introduce a different version of the Indexed color space that is installed with a different remap proc for the case when we have a index color space whose base space is DeviceN or Separation AND we have specified a named color ICC profile.
-rw-r--r--gs/base/gscolor2.c61
-rw-r--r--gs/base/gscolor2.h1
-rw-r--r--gs/psi/zcolor.c19
3 files changed, 78 insertions, 3 deletions
diff --git a/gs/base/gscolor2.c b/gs/base/gscolor2.c
index 1c9452d2f..64874e845 100644
--- a/gs/base/gscolor2.c
+++ b/gs/base/gscolor2.c
@@ -185,6 +185,7 @@ gs_private_st_composite(st_color_space_Indexed, gs_color_space,
static cs_proc_restrict_color(gx_restrict_Indexed);
static cs_proc_concrete_space(gx_concrete_space_Indexed);
static cs_proc_concretize_color(gx_concretize_Indexed);
+static cs_proc_remap_color(gx_remap_IndexedNamed);
static cs_proc_install_cspace(gx_install_Indexed);
static cs_proc_set_overprint(gx_set_overprint_Indexed);
static cs_proc_final(gx_final_Indexed);
@@ -204,6 +205,24 @@ const gs_color_space_type gs_color_space_type_Indexed = {
gx_cspace_is_linear_default, gx_polarity_Indexed
};
+/* To keep things vectorized and avoid an if test during the remap proc we
+ have another set of procedures to use for indexed color spaces when
+ someone has specified a named color profile and the base space of the
+ index color space is DeviceN or Separation */
+const gs_color_space_type gs_color_space_type_Indexed_Named = {
+ gs_color_space_index_Indexed, false, false,
+ &st_color_space_Indexed, gx_num_components_1,
+ gx_init_paint_1, gx_restrict_Indexed,
+ gx_concrete_space_Indexed,
+ gx_concretize_Indexed, NULL,
+ gx_remap_IndexedNamed,
+ gx_install_Indexed,
+ gx_set_overprint_Indexed,
+ gx_final_Indexed, gx_no_adjust_color_count,
+ gx_serialize_Indexed,
+ gx_cspace_is_linear_default, gx_polarity_Indexed
+};
+
/* GC procedures. */
static uint
@@ -477,7 +496,6 @@ static int
gx_concretize_Indexed(const gs_client_color * pc, const gs_color_space * pcs,
frac * pconc, const gs_imager_state * pis, gx_device *dev)
{
-
gs_client_color cc;
const gs_color_space *pbcs =
(const gs_color_space *)pcs->base_space;
@@ -488,6 +506,47 @@ gx_concretize_Indexed(const gs_client_color * pc, const gs_color_space * pcs,
return (*pbcs->type->concretize_color) (&cc, pbcs, pconc, pis, dev);
}
+/* We should only be here for cases where the base space is DeviceN or Sep and
+ we are doing named color replacement. */
+static int
+gx_remap_IndexedNamed(const gs_client_color * pcc, const gs_color_space * pcs,
+gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
+gs_color_select_t select)
+{
+ frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
+ const gs_color_space *pconcs;
+ int i = pcs->type->num_components(pcs);
+ gs_client_color cc;
+ bool mapped;
+ int code = gs_indexed_limit_and_lookup(pcc, pcs, &cc);
+
+ if (code < 0)
+ return code;
+
+ pconcs = cs_concrete_space(pcs, pis);
+ /* Now see if we can do the named color replacement */
+ mapped = gx_remap_named_color(&cc, pconcs, pdc, pis, dev, select);
+
+ if (!mapped) {
+ /* Named color remap failed perhaps due to colorant not found. Do the
+ old approach of concretize of the base space and remap concrete color */
+ const gs_color_space *pbcs =
+ (const gs_color_space *)pcs->base_space;
+
+ code = (*pbcs->type->concretize_color) (&cc, pbcs, conc, pis, dev);
+ if (code < 0)
+ return code;
+ code = (*pconcs->type->remap_concrete_color)(conc, pconcs, pdc, pis, dev, select);
+ }
+
+ /* Save original color space and color info into dev color */
+ i = any_abs(i);
+ for (i--; i >= 0; i--)
+ pdc->ccolor.paint.values[i] = pcc->paint.values[i];
+ pdc->ccolor_valid = true;
+ return code;
+}
+
/* Look up an index in an Indexed color space. */
int
gs_cspace_indexed_lookup(const gs_color_space *pcs, int index,
diff --git a/gs/base/gscolor2.h b/gs/base/gscolor2.h
index 2060aa210..d4d0c1806 100644
--- a/gs/base/gscolor2.h
+++ b/gs/base/gscolor2.h
@@ -46,6 +46,7 @@ gs_indexed_limit_and_lookup(const gs_client_color * pc,const gs_color_space *pcs
/* Declare the Indexed color space type. */
extern const gs_color_space_type gs_color_space_type_Indexed;
+extern const gs_color_space_type gs_color_space_type_Indexed_Named;
/* CIE-specific routines */
#ifndef gs_cie_render_DEFINED
diff --git a/gs/psi/zcolor.c b/gs/psi/zcolor.c
index 75af8d40f..2206f6db5 100644
--- a/gs/psi/zcolor.c
+++ b/gs/psi/zcolor.c
@@ -4260,6 +4260,7 @@ static int setindexedspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
ref hival, lookup;
gs_color_space *pcs;
gs_color_space *pcs_base;
+ gs_color_space_index base_type;
if (i_ctx_p->language_level < 2)
return_error(e_undefined);
@@ -4273,6 +4274,7 @@ static int setindexedspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
cspace_old = istate->colorspace[0];
pcs_base = gs_currentcolorspace(igs);
+ base_type = gs_color_space_get_index(pcs_base);
code = array_get(imemory, r, 3, &lookup);
if (code < 0)
@@ -4293,7 +4295,15 @@ static int setindexedspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
*/
if (r_size(&lookup) < num_values)
return_error(e_rangecheck);
- pcs = gs_cspace_alloc(imemory, &gs_color_space_type_Indexed);
+ /* If we have a named color profile and the base space is DeviceN or
+ Separation use a different set of procedures to ensure the named
+ color remapping code is used */
+ if (igs->icc_manager->device_named != NULL &&
+ (base_type == gs_color_space_index_Separation ||
+ base_type == gs_color_space_index_DeviceN))
+ pcs = gs_cspace_alloc(imemory, &gs_color_space_type_Indexed_Named);
+ else
+ pcs = gs_cspace_alloc(imemory, &gs_color_space_type_Indexed);
if (!pcs) {
return_error(e_VMerror);
}
@@ -4324,7 +4334,12 @@ static int setindexedspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
pcs_base, indexed_cont);
if (code < 0)
return code;
- pcs = gs_cspace_alloc(imemory, &gs_color_space_type_Indexed);
+ if (igs->icc_manager->device_named != NULL &&
+ (base_type == gs_color_space_index_Separation ||
+ base_type == gs_color_space_index_DeviceN))
+ pcs = gs_cspace_alloc(imemory, &gs_color_space_type_Indexed_Named);
+ else
+ pcs = gs_cspace_alloc(imemory, &gs_color_space_type_Indexed);
pcs->base_space = pcs_base;
rc_increment_cs(pcs_base);
pcs->params.indexed.use_proc = 1;