summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2021-06-18 15:38:36 +0100
committerRobin Watts <Robin.Watts@artifex.com>2021-06-18 16:48:16 +0100
commit5b67a1d6e34ef22021c0483081cb713711b93749 (patch)
tree25bc03a311b84dfe66b7bcd65fc351812853d872
parent9d500ac7120b5e7c079ad376c6cb5d2e4e985783 (diff)
downloadghostpdl-alphaslay.tar.gz
Start towards removing map_color_rgb.alphaslay
There is a an HWColorMap parameter, generated by param_HWComp that describes the palette for a given device. This relies on calling map_color_rgb on all the possible color values. Thus this generates the palette from the device rgb values, not color correct ones. We hope to remove the (long deprecated) map_color_rgb device proc, and replace it with calls to decode_color. The wrinkle here is that decode_color decodes to the native device colorspace, which may not be rgb. Accordingly, we introduce a gx_map_rgb_color helper function that performs a decode_color, and then (depending on the number of components) converts it (in a non-color correct manner) to rgb if required. This is imperfect, but should be no worse than what we have now - indeed, potentially better, because frequently map_color_rgb is set to be decode_color, so this would give the wrong results for cmyk or greyscale devices. The bmp devices do a similar operation when generating the palette in their headers; use the same routine for that too.
-rw-r--r--base/gsdparam.c14
-rw-r--r--base/gxcmap.c44
-rw-r--r--base/gxcmap.h5
-rw-r--r--base/gxipixel.c3
-rw-r--r--devices/gdevbmpc.c6
5 files changed, 63 insertions, 9 deletions
diff --git a/base/gsdparam.c b/base/gsdparam.c
index f18272615..22394061b 100644
--- a/base/gsdparam.c
+++ b/base/gsdparam.c
@@ -859,11 +859,21 @@ param_HWColorMap(gx_device * dev, byte * palette /* 3 << 8 */ )
gx_color_value rgb[3];
gx_color_index i;
- fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
+ /* FIXME: We should be able to remove this later. */
+ if (dev_proc(dev, decode_color) == NULL) {
+ fill_dev_proc(dev, encode_color, gx_default_encode_color);
+ set_dev_proc(dev, decode_color, gx_default_decode_color);
+ if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN) {
+ if (dev->color_info.num_components <= 3)
+ dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
+ else
+ check_device_compatible_encoding(dev);
+ }
+ }
for (i = 0; (i >> depth) == 0; i++) {
int j;
- if ((*dev_proc(dev, map_color_rgb)) (dev, i, rgb) < 0)
+ if (gx_map_color_rgb(dev, i, rgb) < 0)
return false;
for (j = 0; j < colors; j++)
*p++ = gx_color_value_to_byte(rgb[j]);
diff --git a/base/gxcmap.c b/base/gxcmap.c
index 7d7ea8bd4..8e87970f8 100644
--- a/base/gxcmap.c
+++ b/base/gxcmap.c
@@ -1994,6 +1994,50 @@ gx_unit_frac(float fvalue)
return f;
}
+static inline gx_color_value
+clamp_color_value(int i)
+{
+ if (i < 0)
+ return (gx_color_value)0;
+ if (i > gx_max_color_value)
+ return (gx_color_value)gx_max_color_value;
+ return (gx_color_value)i;
+}
+
+/* Map from a color index to an rgb value. This is not color correct, but
+ * just an approximation. */
+int
+gx_map_color_rgb(gx_device *dev, gx_color_index col, gx_color_value *rgb)
+{
+ gx_color_value comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ int ret;
+ int k;
+
+ switch (dev->color_info.num_components)
+ {
+ case 1:
+ ret = dev_proc(dev, decode_color)(dev, col, rgb);
+ rgb[2] = rgb[1] = rgb[0];
+ return ret;
+ case 4:
+ ret = dev_proc(dev, decode_color)(dev, col, comps);
+ k = gx_max_color_value - comps[3];
+ rgb[0] = clamp_color_value(k - comps[0]);
+ rgb[1] = clamp_color_value(k - comps[1]);
+ rgb[2] = clamp_color_value(k - comps[2]);
+ return ret;
+ case 3:
+ return dev_proc(dev, decode_color)(dev, col, rgb);
+ default:
+ /* We are in trouble. Make something up. */
+ ret = dev_proc(dev, decode_color)(dev, col, comps);
+ rgb[0] = comps[0];
+ rgb[1] = comps[1];
+ rgb[2] = dev->color_info.num_components < 3 ? comps[2] : 0;
+ return ret;
+ }
+}
+
static void
cmapper_transfer_halftone_add(gx_cmapper_t *data)
{
diff --git a/base/gxcmap.h b/base/gxcmap.h
index 4197a48d3..a27de3a56 100644
--- a/base/gxcmap.h
+++ b/base/gxcmap.h
@@ -264,6 +264,11 @@ void cmap_transfer(gx_color_value *pconc, const gs_gstate * pgs,
void cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs,
gx_device *dev, int plane);
+/* Convert from gx_color_index to an rgb representation derived from the
+ * device space colour components. For non-rgb devices this will NOT be
+ * colour correct. */
+int gx_map_color_rgb(gx_device *dev, gx_color_index col, gx_color_value *rgb);
+
typedef struct gx_cmapper_s gx_cmapper_t;
typedef void (gx_cmapper_fn)(gx_cmapper_t *cmapper);
diff --git a/base/gxipixel.c b/base/gxipixel.c
index 2f367e14d..bb8a7ad65 100644
--- a/base/gxipixel.c
+++ b/base/gxipixel.c
@@ -1056,8 +1056,7 @@ color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor)
if (color_is_pure(pdcolor)) {
gx_color_value rgb[3];
- (*dev_proc(dev, map_color_rgb)) (dev, gx_dc_pure_color(pdcolor),
- rgb);
+ gx_map_color_rgb(dev, gx_dc_pure_color(pdcolor), rgb);
if (!(rgb[0] | rgb[1] | rgb[2]))
return 0;
if ((rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value)
diff --git a/devices/gdevbmpc.c b/devices/gdevbmpc.c
index efc2333b4..0398ff737 100644
--- a/devices/gdevbmpc.c
+++ b/devices/gdevbmpc.c
@@ -172,11 +172,7 @@ write_bmp_header(gx_device_printer *pdev, gp_file *file)
q.reserved = 0;
for (i = 0; i != 1 << depth; i++) {
- /* Note that the use of map_color_rgb is deprecated in
- favor of decode_color. This should work, though, because
- backwards compatibility is preserved. */
- (*dev_proc(pdev, map_color_rgb))((gx_device *)pdev,
- (gx_color_index)i, rgb);
+ gx_map_color_rgb((gx_device *)pdev, (gx_color_index)i, rgb);
q.red = gx_color_value_to_byte(rgb[0]);
q.green = gx_color_value_to_byte(rgb[1]);
q.blue = gx_color_value_to_byte(rgb[2]);