diff options
Diffstat (limited to 'base/gxcmap.c')
-rw-r--r-- | base/gxcmap.c | 404 |
1 files changed, 185 insertions, 219 deletions
diff --git a/base/gxcmap.c b/base/gxcmap.c index cba4908e..a3c2443a 100644 --- a/base/gxcmap.c +++ b/base/gxcmap.c @@ -15,6 +15,7 @@ /* Color mapping for Ghostscript */ +#include "assert_.h" #include "gx.h" #include "gserrors.h" #include "gsccolor.h" @@ -27,6 +28,7 @@ #include "gxcmap.h" #include "gxlum.h" #include "gzstate.h" +#include "gzht.h" #include "gxdither.h" #include "gxcdevn.h" #include "string_.h" @@ -209,32 +211,32 @@ gx_backwards_compatible_gray_encode(gx_device *dev, /* -------- Default color space to color model conversion routines -------- */ void -gray_cs_to_gray_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_gray_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = gray; } static void -rgb_cs_to_gray_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_gray_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { out[0] = color_rgb_to_gray(r, g, b, NULL); } static void -cmyk_cs_to_gray_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_gray_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { out[0] = color_cmyk_to_gray(c, m, y, k, NULL); } static void -gray_cs_to_rgb_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_rgb_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = out[1] = out[2] = gray; } void -rgb_cs_to_rgb_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_rgb_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { out[0] = r; @@ -243,20 +245,20 @@ rgb_cs_to_rgb_cm(gx_device * dev, const gs_gstate *pgs, } static void -cmyk_cs_to_rgb_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_rgb_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { color_cmyk_to_rgb(c, m, y, k, NULL, out, dev->memory); } static void -gray_cs_to_rgbk_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_rgbk_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = out[1] = out[2] = frac_0; out[3] = gray; } static void -rgb_cs_to_rgbk_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_rgbk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { if ((r == g) && (g == b)) { @@ -272,7 +274,7 @@ rgb_cs_to_rgbk_cm(gx_device * dev, const gs_gstate *pgs, } static void -cmyk_cs_to_rgbk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_rgbk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { frac rgb[3]; if ((c == frac_0) && (m == frac_0) && (y == frac_0)) { @@ -286,7 +288,7 @@ cmyk_cs_to_rgbk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) } static void -gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) +gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[]) { out[0] = out[1] = out[2] = frac_0; out[3] = frac_1 - gray; @@ -308,7 +310,7 @@ gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) * often they are { pop 0 }. */ static void -rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, +rgb_cs_to_cmyk_cm(const gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { if (pgs != 0) @@ -325,7 +327,7 @@ rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, } void -cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +cmyk_cs_to_cmyk_cm(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { out[0] = c; out[1] = m; @@ -356,31 +358,40 @@ static const gx_cm_color_map_procs DeviceRGBK_procs = { * to color model conversion routines. */ const gx_cm_color_map_procs * -gx_default_DevGray_get_color_mapping_procs(const gx_device * dev) +gx_default_DevGray_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceGray_procs; } const gx_cm_color_map_procs * -gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev) +gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceRGB_procs; } const gx_cm_color_map_procs * -gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev) +gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceCMYK_procs; } const gx_cm_color_map_procs * -gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev) +gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { + *tdev = dev; return &DeviceRGBK_procs; } const gx_cm_color_map_procs * -gx_error_get_color_mapping_procs(const gx_device * dev) +gx_error_get_color_mapping_procs(const gx_device * dev, + const gx_device ** tdev) { /* * We should never get here. If we do then we do not have a "get_color_mapping_procs" @@ -392,14 +403,14 @@ gx_error_get_color_mapping_procs(const gx_device * dev) dev->dname); switch (dev->color_info.num_components) { case 1: /* DeviceGray or DeviceInvertGray */ - return gx_default_DevGray_get_color_mapping_procs(dev); + return gx_default_DevGray_get_color_mapping_procs(dev, tdev); case 3: - return gx_default_DevRGB_get_color_mapping_procs(dev); + return gx_default_DevRGB_get_color_mapping_procs(dev, tdev); case 4: default: /* Unknown color model - punt with CMYK */ - return gx_default_DevCMYK_get_color_mapping_procs(dev); + return gx_default_DevCMYK_get_color_mapping_procs(dev, tdev); } } @@ -497,13 +508,7 @@ static cmap_proc_rgb(cmap_rgb_direct); #define cmap_cmyk_halftoned cmap_cmyk_direct static cmap_proc_cmyk(cmap_cmyk_direct); -static cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned); -static cmap_proc_rgb_alpha(cmap_rgb_alpha_direct); - /* Procedure names are only guaranteed unique to 23 characters.... */ -static cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned); -static cmap_proc_rgb_alpha(cmap_rgb_alpha_direct); - static cmap_proc_separation(cmap_separation_halftoned); static cmap_proc_separation(cmap_separation_direct); @@ -517,7 +522,6 @@ static const gx_color_map_procs cmap_few = { cmap_gray_halftoned, cmap_rgb_halftoned, cmap_cmyk_halftoned, - cmap_rgb_alpha_halftoned, cmap_separation_halftoned, cmap_devicen_halftoned, cmap_halftoned_is_halftoned @@ -526,7 +530,6 @@ static const gx_color_map_procs cmap_many = { cmap_gray_direct, cmap_rgb_direct, cmap_cmyk_direct, - cmap_rgb_alpha_direct, cmap_separation_direct, cmap_devicen_direct, cmap_direct_is_halftoned @@ -888,6 +891,32 @@ gx_remap_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs, return 0; } +/* ------ Utility for selecting the dev_ht from the pgs using the dev->graphics_type_tag ----- */ + +static gs_HT_objtype_t +tag_to_HT_objtype[8] = { HT_OBJTYPE_DEFAULT, + HT_OBJTYPE_TEXT, /* GS_TEXT_TAG = 0x1 */ + HT_OBJTYPE_IMAGE, /* GS_IMAGE_TAG = 0x2 */ + HT_OBJTYPE_DEFAULT, + HT_OBJTYPE_VECTOR, /* GS_VECTOR_TAG = 0x4 */ + HT_OBJTYPE_DEFAULT, HT_OBJTYPE_DEFAULT, HT_OBJTYPE_DEFAULT + }; + +/* Return the selected dev_ht[] or the pgs->dev_ht[HT_OBJTYPE_DEFAULT] */ +gx_device_halftone * +gx_select_dev_ht(const gs_gstate *pgs) +{ + gs_HT_objtype_t objtype; + + /* This function only works with 3 bits currently. Flag here in case we add object types */ + assert(HT_OBJTYPE_COUNT == 4); + + objtype = tag_to_HT_objtype[pgs->device->graphics_type_tag & 7]; + if (pgs->dev_ht[objtype] == NULL) + objtype = HT_OBJTYPE_DEFAULT; + return pgs->dev_ht[objtype]; +} + /* ------ Render Gray color. ------ */ static void @@ -896,24 +925,21 @@ cmap_gray_halftoned(frac gray, gx_device_color * pdc, { uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_gray_subclass(scm, gray, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_gray(cmdev, gray, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) for (i = 0; i < ncomps; i++) cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ i = dev->color_info.black_component; if (i < ncomps) cm_comps[i] = frac_1 - gx_map_color_frac(pgs, @@ -924,7 +950,7 @@ cmap_gray_halftoned(frac gray, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -937,16 +963,15 @@ cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_gray_subclass(scm, gray, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_gray(cmdev, gray, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); for (i = 0; i < ncomps; i++) cv[i] = frac2cv(cm_comps[i]); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) @@ -956,9 +981,7 @@ cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, cv[i] = frac2cv(cm_comps[i]); } else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ i = dev->color_info.black_component; if (i < ncomps) cm_comps[i] = frac_1 - gx_map_color_frac(pgs, @@ -981,7 +1004,7 @@ cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -994,11 +1017,12 @@ cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc, { uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_rgb(cmdev, pgs, r, g, b, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count != 0) { @@ -1012,7 +1036,7 @@ cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1025,11 +1049,12 @@ cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_rgb(cmdev, pgs, r, g, b, cm_comps); /* apply the transfer function(s); convert to color values */ if (pgs->effective_transfer_non_identity_count == 0) { @@ -1056,7 +1081,7 @@ cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1076,11 +1101,12 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, cmm_dev_profile_t *dev_profile; gsicc_colorbuffer_t src_space = gsUNDEFINED; bool gray_to_k; - subclass_color_mappings scm; + const gx_device *cmdev; + const gx_cm_color_map_procs *cmprocs; /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_cmyk_subclass(scm, c, m, y, k, cm_comps); + cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); + cmprocs->map_cmyk(cmdev, c, m, y, k, cm_comps); /* apply the transfer function(s); convert to color values */ if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { @@ -1115,7 +1141,7 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, /* duplicating most of the code of this procedure. */ if (gx_device_must_halftone(dev)) { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); return; } @@ -1133,111 +1159,13 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, color_set_pure(pdc, color); else { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } } return; } -static void -cmap_rgb_alpha_halftoned(frac r, frac g, frac b, frac alpha, - gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, - gs_color_select_t select) -{ - uchar i, ncomps = dev->color_info.num_components; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - subclass_color_mappings scm; - - /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); - - /* pre-multiply to account for the alpha weighting */ - if (alpha != frac_1) { -#ifdef PREMULTIPLY_TOWARDS_WHITE - frac alpha_bias = frac_1 - alpha; -#else - frac alpha_bias = 0; -#endif - - for (i = 0; i < ncomps; i++) - cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias; - } - - /* apply the transfer function(s); convert to color values */ - if (pgs->effective_transfer_non_identity_count != 0) { - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pgs, - cm_comps[i], effective_transfer[i]); - else - for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pgs, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); - } - - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, - &pgs->screen_phase[select]) == 1) - gx_color_load_select(pdc, pgs, dev, select); -} - -static void -cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, - const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) -{ - uchar i, ncomps = dev->color_info.num_components; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value cv_alpha, cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index color; - subclass_color_mappings scm; - - /* map to the color model */ - scm = get_color_mapping_procs_subclass(dev); - map_rgb_subclass(scm, pgs, r, g, b, cm_comps); - - /* pre-multiply to account for the alpha weighting */ - if (alpha != frac_1) { -#ifdef PREMULTIPLY_TOWARDS_WHITE - frac alpha_bias = frac_1 - alpha; -#else - frac alpha_bias = 0; -#endif - - for (i = 0; i < ncomps; i++) - cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias; - } - - /* apply the transfer function(s); convert to color values */ - if (pgs->effective_transfer_non_identity_count == 0) - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); - else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pgs, - cm_comps[i], effective_transfer[i])); - else - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); - - /* encode as a color index */ - if (dev_proc(dev, map_rgb_alpha_color) != gx_default_map_rgb_alpha_color && - (cv_alpha = frac2cv(alpha)) != gx_max_color_value) - color = dev_proc(dev, map_rgb_alpha_color)(dev, cv[0], cv[1], cv[2], cv_alpha); - else - 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); - return; - } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, - &pgs->screen_phase[select]) == 1) - gx_color_load_select(pdc, pgs, dev, select); -} - /* ------ Render Separation All color. ------ */ /* @@ -1249,19 +1177,26 @@ cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, * pcolor_component_map - Map from DeviceN to the Devices colorants. * A negative value indicates component is not to be mapped. * plist - Pointer to list for mapped components + * num_comps - num_comps that we need to zero (may be more than + * is set if we are mapping values for an NCLR ICC profile + * via an alternate tint transform for a sep value) -- + * i.e. cmyk+og values and we may have some spots that + * are supported but may have reached the limit and + * using the alt tint values. Need to make sure to zero all. * * Returns: * Mapped components in plist. */ static inline void map_components_to_colorants(const frac * pcc, - const gs_devicen_color_map * pcolor_component_map, frac * plist) + const gs_devicen_color_map * pcolor_component_map, frac * plist, + int num_colorants) { - int i = pcolor_component_map->num_colorants - 1; + int i; int pos; /* Clear all output colorants first */ - for (; i >= 0; i--) { + for (i = num_colorants - 1; i >= 0; i--) { plist[i] = frac_0; } @@ -1426,7 +1361,8 @@ cmap_separation_halftoned(frac all, gx_device_color * pdc, cm_comps[i] = comp_value; } else { /* map to the color model */ - map_components_to_colorants(&all, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(&all, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); } if (devicen_has_cmyk(dev, des_profile) && @@ -1447,7 +1383,7 @@ cmap_separation_halftoned(frac all, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1493,7 +1429,8 @@ cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs, } else { /* map to the color model */ - map_components_to_colorants(&comp_value, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(&comp_value, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); } /* Check if we have the standard colorants. If yes, then we will apply @@ -1572,7 +1509,7 @@ cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs, return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1598,7 +1535,8 @@ cmap_devicen_halftoned(const frac * pcc, gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &des_profile, &render_cond); /* map to the color model */ - map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); /* See comments in cmap_devicen_direct for details on below operations */ if (devicen_has_cmyk(dev, des_profile) && des_profile->data_cs == gsCMYK && @@ -1618,7 +1556,7 @@ cmap_devicen_halftoned(const frac * pcc, } /* We need to finish halftoning */ - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1647,9 +1585,10 @@ cmap_devicen_direct(const frac * pcc, /* map to the color model */ if (dev_profile->spotnames != NULL && dev_profile->spotnames->equiv_cmyk_set) { map_components_to_colorants(pcc, dev_profile->spotnames->color_map, - cm_comps); + cm_comps, ncomps); } else { - map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps); + map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, + pgs->color_component_map.num_colorants); } /* Check if we have the standard colorants. If yes, then we will apply ICC color management to those colorants. To understand why, consider @@ -1713,7 +1652,7 @@ cmap_devicen_direct(const frac * pcc, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1814,6 +1753,21 @@ gx_default_w_b_map_color_rgb(gx_device * dev, gx_color_index color, return 0; } +gx_color_index +gx_default_w_b_mono_encode_color(gx_device *dev, const gx_color_value cv[]) +{ + return cv[0] > gx_max_color_value / 2 ? (gx_color_index)1 + : (gx_color_index)0; +} + +int +gx_default_w_b_mono_decode_color(gx_device * dev, gx_color_index color, + gx_color_value pgray[1]) +{ /* Map 0 to max_value, 1 to 0. */ + pgray[0] = -(gx_color_value) color; + return 0; +} + /* Black-on-white */ gx_color_index gx_default_b_w_map_rgb_color(gx_device * dev, const gx_color_value cv[]) @@ -1835,6 +1789,21 @@ gx_default_b_w_map_color_rgb(gx_device * dev, gx_color_index color, return 0; } +gx_color_index +gx_default_b_w_mono_encode_color(gx_device *dev, const gx_color_value cv[]) +{ + return cv[0] > gx_max_color_value / 2 ? (gx_color_index)0 + : (gx_color_index)1; +} + +int +gx_default_b_w_mono_decode_color(gx_device * dev, gx_color_index color, + gx_color_value pgray[1]) +{ /* Map 0 to max_value, 1 to 0. */ + pgray[0] = -((gx_color_value) color ^ 1); + return 0; +} + /* RGB mapping for gray-scale devices */ gx_color_index @@ -1865,6 +1834,26 @@ gx_default_gray_map_color_rgb(gx_device * dev, gx_color_index color, } gx_color_index +gx_default_gray_encode_color(gx_device * dev, const gx_color_value cv[]) +{ + gx_color_value gray = (cv[0] * dev->color_info.max_gray + + (gx_max_color_value / 2)) / gx_max_color_value; + + return gray; +} + +int +gx_default_gray_decode_color(gx_device * dev, gx_color_index color, + gx_color_value *cv) +{ + gx_color_value gray = (gx_color_value) + (color * gx_max_color_value / dev->color_info.max_gray); + + cv[0] = gray; + return 0; +} + +gx_color_index gx_default_8bit_map_gray_color(gx_device * dev, const gx_color_value cv[]) { gx_color_index color = gx_color_value_to_byte(cv[0]); @@ -2042,23 +2031,22 @@ cmyk_16bit_map_color_cmyk(gx_device * dev, gx_color_index color, return 0; } -/* Default mapping between RGB+alpha and RGB. */ - -gx_color_index -gx_default_map_rgb_alpha_color(gx_device * dev, - gx_color_value r, gx_color_value g, gx_color_value b, gx_color_value alpha) -{ /* Colors have been premultiplied: we don't need to do it here. */ - gx_color_value cv[3]; - cv[0] = r; cv[1] = g; cv[2] = b; - return (*dev_proc(dev, map_rgb_color))(dev, cv); -} - int -gx_default_map_color_rgb_alpha(gx_device * dev, gx_color_index color, - gx_color_value prgba[4]) -{ - prgba[3] = gx_max_color_value; /* alpha = 1 */ - return (*dev_proc(dev, map_color_rgb)) (dev, color, prgba); +cmyk_16bit_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + gx_color_value c = ((color >> 24) >> 24) & 0xffff; + gx_color_value m = ((color >> 16) >> 16) & 0xffff; + gx_color_value y = ( color >> 16) & 0xffff; + gx_color_value not_k = (~color ) & 0xffff; + int r = not_k - c; + int g = not_k - m; + int b = not_k - y; + + prgb[0] = (r < 0 ? 0 : r); + prgb[1] = (g < 0 ? 0 : g); + prgb[2] = (b < 0 ? 0 : b); + return 0; } frac @@ -2093,7 +2081,7 @@ cmapper_transfer_halftone_add(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2122,7 +2110,7 @@ cmapper_transfer_halftone_op(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2146,7 +2134,7 @@ cmapper_transfer_halftone_sub(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2242,7 +2230,7 @@ cmapper_halftone(gx_cmapper_t *data) cv_frac[i] = cv2frac(pconc[i]); } if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2274,8 +2262,6 @@ gx_get_cmapper(gx_cmapper_t *data, const gs_gstate *pgs, data->select = select; data->devc.type = gx_dc_type_none; data->direct = 0; - if (has_transfer && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); /* Per spec. Images with soft mask, and the mask, do not use transfer function */ if (pgs->effective_transfer_non_identity_count == 0 || (dev_proc(dev, dev_spec_op)(dev, gxdso_in_smask, NULL, 0)) > 0) @@ -2286,7 +2272,7 @@ gx_get_cmapper(gx_cmapper_t *data, const gs_gstate *pgs, data->set_color = cmapper_transfer_halftone_add; else data->set_color = cmapper_transfer_add; - } else if (dev->color_info.opmode == GX_CINFO_OPMODE) { + } else if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { if (has_halftone) data->set_color = cmapper_transfer_halftone_op; else @@ -2327,8 +2313,6 @@ cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, /* apply the transfer function(s) */ if (has_transfer) { if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); for (i = 0; i < ncomps; i++) cv_frac[i] = cv2frac(pconc[i]); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { @@ -2338,10 +2322,7 @@ cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, frac_value, effective_transfer[i]); } } else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { - check_cmyk_color_model_comps(dev); - } - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ uint k = dev->color_info.black_component; for (i = 0; i < ncomps; i++) { frac_value = cv2frac(pconc[i]); @@ -2371,7 +2352,7 @@ cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, /* Halftoning */ if (has_halftone) { if (gx_render_device_DeviceN(&(cv_frac[0]), pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } else { /* We have a frac value from the transfer function. Do the encode. @@ -2396,17 +2377,12 @@ cmap_transfer(gx_color_value *pconc, const gs_gstate * pgs, gx_device * dev) /* apply the transfer function(s) */ if (pgs->effective_transfer_non_identity_count == 0) { - if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) - check_cmyk_color_model_comps(dev); } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) for (i = 0; i < ncomps; i++) pconc[i] = frac2cv(gx_map_color_frac(pgs, cv2frac(pconc[i]), effective_transfer[i])); else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { - check_cmyk_color_model_comps(dev); - } - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ i = dev->color_info.black_component; if (i < ncomps) pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, @@ -2433,10 +2409,7 @@ cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs, cv_frac = gx_map_color_frac(pgs, frac_value, effective_transfer[plane]); pconc[0] = frac2cv(cv_frac); } else { - if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { - check_cmyk_color_model_comps(dev); - } - if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ + if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) { /* CMYK-like color space */ uint k = dev->color_info.black_component; if (plane == k) { frac_value = cv2frac(pconc[0]); @@ -2457,7 +2430,6 @@ cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs, bool gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs) { - subclass_color_mappings scm; const gx_cm_color_map_procs *pprocs; gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile = NULL; @@ -2468,16 +2440,10 @@ gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs) dev_profile, &des_profile, &render_cond); if (des_profile != NULL) { - scm = get_color_mapping_procs_subclass(dev); - pprocs = scm.procs; - /* FIXME: This looks wrong to me. Presumably we should be finding - * the parentmost device, looking at the procs for that, and if - * they are forwarding ones, getting the procs for the forwarded - * device. This is NOT what this code does. */ + const gx_device *cmdev; + + pprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev); /* Check if they are forwarding procs */ - if (fwd_uses_fwd_cmap_procs(dev)) { - pprocs = fwd_get_target_cmap_procs(dev); - } switch(des_profile->num_comps) { case 1: if (pprocs == &DeviceGray_procs) { |