summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2022-08-23 11:44:11 -0700
committerMichael Vrhel <michael.vrhel@artifex.com>2022-09-14 13:39:41 -0700
commitb7bdb0f124f8b1f4b3b743000a8bfd7e0eec76eb (patch)
tree561f26aa59445256f52772b146a0be4b8b50792f /base
parent481b32c82db2a3265523eb93ba4b0c614ff10502 (diff)
downloadghostpdl-b7bdb0f124f8b1f4b3b743000a8bfd7e0eec76eb.tar.gz
Color replacement example
Add example of how to perform color replacement for devn devices for source colors that are gray, rgb, cmyk, or cielab. Thanks to Robin Watts for the suggestion on using the special ops for this. This commit adds a new special op called gxdso_replacecolor. The PDF14 device (transparency device) will not allow color replacement if we are in a soft mask or if the PDF14 color space is different than the target device color space. The psd devices are set up as a demo to show the use of color replacement. See gdevpsd.c and set ENABLE_COLOR_REPLACE to 1 to activate the example code. This code shows the setting of specific device color values based upon specific source values. Note that access to the pgs and hence the named color profile is provided so that a database of colors mappings can be provided at runtime. How the memory devices deal with the special_op procedure was reworked. Thanks to Robin Watts for his help on this. Now any memory special ops should be handled in mem_spec_op. If it does not handle it and a target device exists, then the target device will have an opportunity to handle the special op.
Diffstat (limited to 'base')
-rw-r--r--base/gdevp14.c23
-rw-r--r--base/gsicc.c13
-rw-r--r--base/gxdevsop.h18
-rw-r--r--base/gxpcmap.c1
4 files changed, 54 insertions, 1 deletions
diff --git a/base/gdevp14.c b/base/gdevp14.c
index 0b47ae6d6..b99a3ffd1 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -8573,6 +8573,29 @@ pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
return p14dev->in_smask_construction > 0;
if (dev_spec_op == gxdso_in_smask)
return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
+ if (dev_spec_op == gxdso_replacecolor) {
+ gx_device *tdev = p14dev->target;
+ cmm_dev_profile_t *tdev_profile;
+ int code;
+
+ /* If in a softmask or softmask construction do not allow
+ replacement. */
+ if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
+ return 0;
+
+ /* If the target CS is different than the pdf14 profile do not
+ allow replacement. */
+ code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
+ if (code != 0)
+ return 0;
+
+ if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
+ p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode)
+ return 0;
+
+ /* Pass on to target device */
+ return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
+ }
if (dev_spec_op == gxdso_device_insert_child) {
gx_device *tdev = p14dev->target;
p14dev->target = (gx_device *)data;
diff --git a/base/gsicc.c b/base/gsicc.c
index 62f68880f..72c455ee2 100644
--- a/base/gsicc.c
+++ b/base/gsicc.c
@@ -454,6 +454,18 @@ gx_remap_ICC(const gs_client_color * pcc, const gs_color_space * pcs,
cmm_dev_profile_t *dev_profile;
int code;
+ color_replace_s param;
+ param.pcc = pcc;
+ param.pcs = pcs;
+ param.pdc = pdc;
+ param.pgs = pgs;
+
+ /* Try color replacement. If successful (>0) then no
+ ICC color management for this color. */
+ if (dev_proc(pgs->device, dev_spec_op)(pgs->device,
+ gxdso_replacecolor, &param, sizeof(color_replace_s)) > 0)
+ return 0;
+
code = dev_proc(dev, get_profile)(dev, &dev_profile);
if (code < 0)
return code;
@@ -475,7 +487,6 @@ gx_remap_ICC(const gs_client_color * pcc, const gs_color_space * pcs,
return_error(gs_error_unknownerror);
}
-
code = gx_remap_ICC_with_link(pcc, pcs, pdc, pgs, dev, select, icc_link);
/* Release the link */
gsicc_release_link(icc_link);
diff --git a/base/gxdevsop.h b/base/gxdevsop.h
index 89eed4b3b..b217321bb 100644
--- a/base/gxdevsop.h
+++ b/base/gxdevsop.h
@@ -134,6 +134,14 @@ typedef struct pattern_accum_param_t {
int pinst_id;
}pattern_accum_param_s;
+/* Structure used for device specific color setting */
+typedef struct color_replace_t {
+ gx_device_color *pdc;
+ const gs_color_space *pcs;
+ const gs_client_color *pcc;
+ const gs_gstate *pgs; /* Perhaps needed for named color profile information */
+} color_replace_s;
+
enum {
/* All gxdso_ keys must be defined in this structure.
* Do NOT rely on your particular gxdso_ having a particular value.
@@ -458,6 +466,16 @@ enum {
*/
gxdso_overprint_op,
+ /* Color replacement method. Intercepts remap color method(s) to
+ * enable the device map source colors to device colors directly
+ * in a method defined in the device.
+ * data = color_replace_s
+ * size = sizeof(color_replace_s)
+ *
+ * Returns 0 is no replacment is made.
+ * Returns >0 if replacement occurred. */
+ gxdso_replacecolor,
+
/* Add new gxdso_ keys above this. */
gxdso_pattern__LAST
};
diff --git a/base/gxpcmap.c b/base/gxpcmap.c
index e8b28b641..74ed63e19 100644
--- a/base/gxpcmap.c
+++ b/base/gxpcmap.c
@@ -423,6 +423,7 @@ pattern_accum_open(gx_device * dev)
#undef PDSET
bits->color_info = padev->color_info;
bits->bitmap_memory = mem;
+
if (target->is_planar > 0)
{
gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS];