diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2015-02-20 15:05:51 -0800 |
---|---|---|
committer | Michael Vrhel <michael.vrhel@artifex.com> | 2015-02-20 22:50:46 -0800 |
commit | 6ab5713f556bde0be38fa411e2eb1d25eb73e2c5 (patch) | |
tree | 42bc9fb37527a5b915c7688f90474256da608648 | |
parent | 033cf566b74c7e12bfb82d9b63a7bc680c51c5f8 (diff) | |
download | ghostpdl-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.c | 61 | ||||
-rw-r--r-- | gs/base/gscolor2.h | 1 | ||||
-rw-r--r-- | gs/psi/zcolor.c | 19 |
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; |