diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2021-06-18 15:38:36 +0100 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2021-06-18 16:48:16 +0100 |
commit | 5b67a1d6e34ef22021c0483081cb713711b93749 (patch) | |
tree | 25bc03a311b84dfe66b7bcd65fc351812853d872 | |
parent | 9d500ac7120b5e7c079ad376c6cb5d2e4e985783 (diff) | |
download | ghostpdl-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.c | 14 | ||||
-rw-r--r-- | base/gxcmap.c | 44 | ||||
-rw-r--r-- | base/gxcmap.h | 5 | ||||
-rw-r--r-- | base/gxipixel.c | 3 | ||||
-rw-r--r-- | devices/gdevbmpc.c | 6 |
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]); |