FW: Revised fix for 687418 WTS does not work with bitcmyk driver
"Dan Coby" <[email protected]>
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
I am sending this again since Russell had a problem with the extension of the original attachment. Dan -----Original Message----- From: Dan Coby [mailto:[email protected]] Sent: Tuesday, May 18, 2004 10:15 AM To: Gs-Code-Review Subject: Revised fix for 687418 WTS does not work with bitcmyk driver (xefitra) Revised fix for 687418 WTS does not work with bitcmyk driver. DETAILS: The changes in this revised fix are pretty extensive. Note: This patch includes several items from Russell Lang. I am including these since they are required for the proper execution of the patch and it does not seem reasonable to require possible testers or reviewers to have to track down and install these patches separately. The list of changes includes: 1. Added logic to check_device_separable to also set the gray_index value. This suggestion came from Russell Lang. 2. Add verification that a colorants bits are consecutive. (from Russell Lang in: http://www.ghostscript.com/pipermail/gs-code-review/2004-May/004501.html 3. Changes to gx_default_encode_color and gx_default_decode_color to use position and bit count info from the device's color_info data. (Also from Russell Lang in the previously mentioned submission.) 4. Included test routines. (Also from Russell Lang in the previously mentioned submission.) 5. Added calls to check_device_separable prior to calls to the various 'fill_in_procs' routines (gx_device_fill_in_procs, gx_forward_fill_in_procs, fill_in_procs). The fill_in_procs routines use the separable information in choosing default routines for the encode_color and decode_color routines. Thus we have a chicken and egg problem since check_device_separable also uses the device's encode_color routine. The test routines from Russell were a great help in debugging Also various changes that were found while testing this patch: 6. The various color deskjet drivers (gdevcdj.c) was incorrectly setting the dither_grays and dither_colors values to 5 instead of 256. (I have no idea why.) The max_gray and max_color values were set to being set correctly to 255. 7. The color deskjet devices (gdevcdj.c) were doing BG and UCR removal inside of the encode_color routines. These devices use the default color_mapping_procs which also do these tasks. The code in the encode_color_routine was removed since it could cause conflicts with the overprint routines. The code in the encode_color routine was also using a fixed BG/UCR logic (from PS level 2). 8. Corrected a problem in the color desk jet decode_color routine which was always returning zero for the black value. 9. Changed the casting for values assigned to the std_colorant_names field. Note: MSVC and gcc complain about different conditions. There does not seem to be a combination that will keep both happy. This set produces no complaints from gcc. 10. Corrected the setting of dither_grays and dither_colors for the devicen device. Previously this was being set to 1 when it should have been set to 256. Found by Russell Lang. 11. Modified check_device_separable to only check for appropriate values of the max_gray/dither_grays and max_color/dither_colors pairs only for gray/color devices. 12. Added check for encode_color routines which encode zero bits for a colorant. Previously this condition would have caused an infinitely in check_device_separable. Change suggested by Russell Lang. 13. Removed a previous call to set_linear_color_bits_mask_shift in gx_default_fill_in_procs. This has been logically replaced by the calls to check_device_separable which have been added. 14. Corrected a problem in the ppm_map_rgb_color in gdevpbm.c. This routine was calling gx_default_encode_color which requires 15. Corrected problem in pcx256 device which incorrectly setting the dither_grays and dither_colors values. 16. Removed the check_process_color_names routine from gdevpsd.c since it not used. 17. Modified the dci_alpha_values macro in gxdevcli.h. This macro was setting some devices as 'separable' but was not setting the related color_info fields (comp_shift, comp_bits, comp_mask). Now this macro sets a devices as 'unknown'. The check_device_separable routine will change this for devices which are separable. Devices which want to change their process color model need to either set themselves as 'unknown' and let check_device_separable handle things or else the device needs to setup its own values for separable fields. Note: There is another related submission from Russell Lang that is not included in this patch. This consists of changes to the display device for making it 'separable'. This change is needed for Igor's linear shading work. http://www.ghostscript.com/pipermail/gs-code-review/2004-May/004500.html Dan _______________________________________________ gs-code-review mailing list [email protected] http://www.ghostscript.com/mailman/listinfo/gs-code-review
687418.txt
(text/plain, 38 KB)
Index: src/gdevcdj.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevcdj.c,v
retrieving revision 1.13
diff -u -r1.13 gdevcdj.c
--- a/src/gdevcdj.c 13 Nov 2002 23:33:05 -0000 1.13
+++ b/src/gdevcdj.c 18 May 2004 03:52:14 -0000
@@ -400,7 +400,7 @@
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
(bpp == 32 ? 4 : (bpp == 1 || bpp == 8) ? 1 : 3), bpp,\
(bpp >= 8 ? 255 : 1), (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0),\
- (bpp >= 8 ? 5 : 2), (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0),\
+ (bpp >= 8 ? 256 : 2), (bpp >= 8 ? 256 : bpp > 1 ? 2 : 0),\
print_page, 0 /* cmyk */, correct)
#define prn_cmyk_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\
@@ -408,7 +408,7 @@
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
((bpp == 1 || bpp == 4) ? 1 : 4), bpp,\
(bpp > 8 ? 255 : 1), (1 << (bpp >> 2)) - 1, /* max_gray, max_color */\
- (bpp > 8 ? 5 : 2), (bpp > 8 ? 5 : bpp > 1 ? 2 : 0),\
+ (bpp > 8 ? 256 : 2), (bpp > 8 ? 256 : bpp > 1 ? 2 : 0),\
print_page, 1 /* cmyk */, correct)
#define bjc_device(dtype, p, d, x, y, b, pp, c) \
@@ -2738,20 +2738,6 @@
default: {
int nbits = pdev->color_info.depth;
- if (cyan == magenta && magenta == yellow) {
-
- /* Convert CMYK to gray -- Red Book 6.2.2 */
-
- float bpart = ((float) cyan) * (lum_red_weight / 100.) +
- ((float) magenta) * (lum_green_weight / 100.) +
- ((float) yellow) * (lum_blue_weight / 100.) +
- (float) black;
-
- cyan = magenta = yellow = (gx_color_index) 0;
- black = (gx_color_index) (bpart > gx_max_color_value ?
- gx_max_color_value : bpart);
- }
-
color = gx_cmyk_value_bits(cyan, magenta, yellow, black,
nbits >> 2);
}
@@ -2956,10 +2942,10 @@
}
break;
case 24:
- { gx_color_value c = (gx_color_value)color ^ 0xffffff;
- prgb[0] = gx_color_value_from_byte(c >> 16);
- prgb[1] = gx_color_value_from_byte((c >> 8) & 0xff);
- prgb[2] = gx_color_value_from_byte(c & 0xff);
+ { gx_color_index c = color ^ 0xffffff;
+ prgb[0] = gx_color_value_from_byte((gx_color_value)(c >> 16));
+ prgb[1] = gx_color_value_from_byte((gx_color_value)((c >> 8) & 0xff));
+ prgb[2] = gx_color_value_from_byte((gx_color_value)(c & 0xff));
}
break;
case 32:
@@ -3272,18 +3258,18 @@
ci->max_gray = (bpp >= 8 ? 255 : 1);
if (ci->num_components == 1) {
- ci->dither_grays = (bpp >= 8 ? 5 : 2);
- ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
+ ci->dither_grays = (bpp >= 8 ? 256 : 2);
+ ci->dither_colors = (bpp >= 8 ? 256 : bpp > 1 ? 2 : 0);
} else {
- ci->dither_grays = (bpp > 8 ? 5 : 2);
- ci->dither_colors = (bpp > 8 ? 5 : bpp > 1 ? 2 : 0);
+ ci->dither_grays = (bpp > 8 ? 256 : 2);
+ ci->dither_colors = (bpp > 8 ? 256 : bpp > 1 ? 2 : 0);
}
} else {
ci->num_components = (bpp == 1 || bpp == 8 ? 1 : 3);
ci->max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
ci->max_gray = (bpp >= 8 ? 255 : 1);
- ci->dither_grays = (bpp >= 8 ? 5 : 2);
- ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
+ ci->dither_grays = (bpp >= 8 ? 256 : 2);
+ ci->dither_colors = (bpp >= 8 ? 256 : bpp > 1 ? 2 : 0);
}
ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp);
Index: src/gdevcmap.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevcmap.c,v
retrieving revision 1.5
diff -u -r1.5 gdevcmap.c
--- a/src/gdevcmap.c 22 Aug 2002 07:12:28 -0000 1.5
+++ b/src/gdevcmap.c 18 May 2004 03:52:15 -0000
@@ -149,6 +149,7 @@
target->memory, true);
gx_device_set_target((gx_device_forward *)dev, target);
gx_device_copy_params((gx_device *)dev, target);
+ check_device_separable((gx_device *)dev);
gx_device_forward_fill_in_procs((gx_device_forward *) dev);
code = gdev_cmap_set_method(dev, method);
if (code < 0)
Index: src/gdevdevn.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevdevn.c,v
retrieving revision 1.16
diff -u -r1.16 gdevdevn.c
--- a/src/gdevdevn.c 28 Apr 2004 16:41:44 -0000 1.16
+++ b/src/gdevdevn.c 18 May 2004 03:52:17 -0000
@@ -144,8 +144,7 @@
/* DeviceN device specific parameters */
{ 1, /* Bits per color - must match ncomp, depth, etc. above */
- /* Names of color model colorants */
- (fixed_colorant_names_list *) &DeviceCMYKComponents,
+ &DeviceCMYKComponents, /* Names of color model colorants */
4, /* Number colorants for CMYK */
{0}, /* SeparationNames */
{0}, /* SeparationOrder names */
@@ -168,15 +167,15 @@
/* Note: We start with at least one component */
GX_CINFO_POLARITY_SUBTRACTIVE, /* Polarity */
8, 0, /* Depth, Gray_index, */
- 255, 255, 1, 1, /* MaxGray, MaxColor, DitherGray, DitherColor */
- GX_CINFO_SEP_LIN, /* Linear & Seperable */
+ 255, 255, 256, 256, /* MaxGray, MaxColor, DitherGray, DitherColor */
+ GX_CINFO_SEP_LIN, /* Linear & Separable */
"DeviceN", /* Process color model name */
/* Note: We start with at least one component */
spotcmyk_print_page), /* Printer page print routine */
/* DeviceN device specific parameters */
{ 8, /* Bits per color - must match ncomp, depth, etc. above */
NULL , /* No names for standard DeviceN color model */
- 0, /* No standarad colorants for DeviceN */
+ 0, /* No standarad colorants for DeviceN */
{0}, /* SeparationNames */
{0}, /* SeparationOrder names */
{0, 1, 2, 3 } /* Initial component order */
@@ -363,7 +362,8 @@
}
/* Return the number of bytes in the destination buffer. */
if (out_byte_loc != out_bit_start) { /* If partially filled last byte */
- *out++ = *out & ((~0) << out_byte_loc); /* Mask unused part of last byte */
+ *out = *out & ((~0) << out_byte_loc); /* Mask unused part of last byte */
+ out++;
}
length = out - dest;
return length;
@@ -862,7 +862,7 @@
int name_size, int component_type)
{
return devicen_get_color_comp_index(dev,
- &(((spotcmyk_device *)dev)->devn_params),
+ &(((const spotcmyk_device *)dev)->devn_params),
pname, name_size, component_type);
}
@@ -879,7 +879,7 @@
* number if the name is found. It returns a negative value if not found.
*/
int
-devicen_get_color_comp_index(const gx_device * dev, gs_devn_params * pparams,
+devicen_get_color_comp_index(const gx_device * dev, const gs_devn_params * pparams,
const char * pname, int name_size, int component_type)
{
int color_component_number = 0;
Index: src/gdevdevn.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevdevn.h,v
retrieving revision 1.4
diff -u -r1.4 gdevdevn.h
--- a/src/gdevdevn.h 28 Apr 2004 16:41:44 -0000 1.4
+++ b/src/gdevdevn.h 18 May 2004 03:52:17 -0000
@@ -79,7 +79,7 @@
* names are those in this list plus those in the separation[i].info.name
* list (below).
*/
- fixed_colorant_names_list * std_colorant_names;
+ const fixed_colorant_names_list * std_colorant_names;
int num_std_colorant_names; /* Number of names in list */
/*
@@ -158,8 +158,9 @@
* This routine returns a positive value (0 to n) which is the device colorant
* number if the name is found. It returns a negative value if not found.
*/
-int devicen_get_color_comp_index(const gx_device * dev, gs_devn_params * pparams,
- const char * pname, int name_size, int component_type);
+int devicen_get_color_comp_index(const gx_device * dev,
+ const gs_devn_params * pparams, const char * pname,
+ int name_size, int component_type);
/*
* This routine will extract a specified set of bits from a buffer and pack
Index: src/gdevdflt.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevdflt.c,v
retrieving revision 1.22
diff -u -r1.22 gdevdflt.c
--- a/src/gdevdflt.c 6 May 2004 19:06:26 -0000 1.22
+++ b/src/gdevdflt.c 18 May 2004 03:52:18 -0000
@@ -238,18 +238,23 @@
gx_color_index color,
gx_color_value cv[4] )
{
- int i, code = dev_proc(dev, map_color_rgb)(dev, color, cv);
- gx_color_value min_val = gx_max_color_value;
+ /* The device may have been determined to be 'separable'. */
+ if (dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
+ return gx_default_decode_color(dev, color, cv);
+ else {
+ int i, code = dev_proc(dev, map_color_rgb)(dev, color, cv);
+ gx_color_value min_val = gx_max_color_value;
+
+ for (i = 0; i < 3; i++) {
+ if ((cv[i] = gx_max_color_value - cv[i]) < min_val)
+ min_val = cv[i];
+ }
+ for (i = 0; i < 3; i++)
+ cv[i] -= min_val;
+ cv[3] = min_val;
- for (i = 0; i < 3; i++) {
- if ((cv[i] = gx_max_color_value - cv[i]) < min_val)
- min_val = cv[i];
+ return code;
}
- for (i = 0; i < 3; i++)
- cv[i] -= min_val;
- cv[3] = min_val;
-
- return code;
}
/*
@@ -406,15 +411,18 @@
if (pinfo->separable_and_linear != GX_CINFO_UNKNOWN_SEP_LIN)
return;
/* If there is not an encode_color_routine then we cannot proceed. */
- if (dev_proc(dev, encode_color == NULL))
+ if (dev_proc(dev, encode_color) == NULL)
return;
/*
* If these values do not check then we should have an error. However
* we do not know what to do so we are simply exitting and hoping that
* the device will clean up its values.
*/
- if (!pinfo->dither_grays || pinfo->dither_grays != (pinfo->max_gray + 1) ||
- !pinfo->dither_colors || pinfo->dither_colors != (pinfo->max_color + 1))
+ if (pinfo->gray_index < num_components &&
+ (!pinfo->dither_grays || pinfo->dither_grays != (pinfo->max_gray + 1)))
+ return;
+ if ((num_components > 1 || pinfo->gray_index != 0) &&
+ (!pinfo->dither_colors || pinfo->dither_colors != (pinfo->max_color + 1)))
return;
/*
* If dither_grays or dither_colors is not a power of two then we assume
@@ -432,9 +440,9 @@
color_index = dev_proc(dev, encode_color)(dev, colorants);
if (color_index != 0)
return; /* Exit if zero colorants produce a non zero index */
- for (i = 0; i < num_components; i ++) {
+ for (i = 0; i < num_components; i++) {
/* Check this colorant = max with all others = 0 */
- for (j = 0; j < num_components; j ++)
+ for (j = 0; j < num_components; j++)
colorants[j] = 0;
colorants[i] = gx_max_color_value;
color_index = dev_proc(dev, encode_color)(dev, colorants);
@@ -443,12 +451,15 @@
current_bits |= color_index;
comp_mask[i] = color_index;
/* Determine the shift count for the colorant */
- for (j = 0; (color_index & 1) == 0; j++)
+ for (j = 0; (color_index & 1) == 0 && color_index != 0; j++)
color_index >>= 1;
comp_shift[i] = j;
/* Determine the bit count for the colorant */
- for (j = 0; color_index != 0; j++)
+ for (j = 0; color_index != 0; j++) {
+ if ((color_index & 1) == 0) /* check for non-consecutive bits */
+ return;
color_index >>= 1;
+ }
comp_bits[i] = j;
/*
* We could verify that the bit count matches the dither_grays or
@@ -456,7 +467,7 @@
* are halftoning. Thus we are allowing for non equal colorant sizes.
*/
/* Check for overlap with other colorant if they are all maxed */
- for (j = 0; j < num_components; j ++)
+ for (j = 0; j < num_components; j++)
colorants[j] = gx_max_color_value;
colorants[i] = 0;
color_index = dev_proc(dev, encode_color)(dev, colorants);
@@ -470,6 +481,20 @@
pinfo->comp_bits[i] = comp_bits[i];
pinfo->comp_mask[i] = comp_mask[i];
}
+ /*
+ * The 'gray_index' value allows one colorant to have a different number
+ * of shades from the remainder. Since the default macros only guess at
+ * an appropriate value, we are setting its value based upon the data that
+ * we just determined. Note: In some cases the macros set max_gray to 0
+ * and dither_grays to 1. This is not valid so ignore this case.
+ */
+ for (i = 0; i < num_components; i ++) {
+ int dither = 1 << comp_bits[i];
+ if (pinfo->dither_grays != 1 && dither == pinfo->dither_grays) {
+ pinfo->gray_index = i;
+ break;
+ }
+ }
}
#undef is_power_of_two
@@ -622,10 +647,6 @@
set_dev_proc(dev, decode_color, get_decode_color(dev));
fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
- /* Initialize the separable status if not known. */
- if ( dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ) {
- set_linear_color_bits_mask_shift(dev);
- }
/*
* If the device is known not to support overprint mode, indicate this now.
* Note that we do not insist that a device be use a strict DeviceCMYK
@@ -650,6 +671,8 @@
int
gx_default_open_device(gx_device * dev)
{
+ /* Initialize the separable status if not known. */
+ check_device_separable(dev);
return 0;
}
Index: src/gdevdsp.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevdsp.c,v
retrieving revision 1.20
diff -u -r1.20 gdevdsp.c
--- a/src/gdevdsp.c 30 Apr 2003 10:34:53 -0000 1.20
+++ b/src/gdevdsp.c 18 May 2004 03:52:19 -0000
@@ -933,6 +933,7 @@
gs_make_mem_device(ddev->mdev, mdproto, gs_memory_stable(ddev->memory),
0, (gx_device *) NULL);
+ check_device_separable((gx_device *)(ddev->mdev));
gx_device_fill_in_procs((gx_device *)(ddev->mdev));
/* Mark the memory device as retained. When the bitmap is closed,
* we will clear this and the memory device will be then be freed.
Index: src/gdevmem.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevmem.c,v
retrieving revision 1.7
diff -u -r1.7 gdevmem.c
--- a/src/gdevmem.c 13 Jan 2004 02:06:12 -0000 1.7
+++ b/src/gdevmem.c 18 May 2004 03:52:19 -0000
@@ -175,6 +175,7 @@
(target == 0 ||
dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE));
}
+ check_device_separable((gx_device *)dev);
gx_device_fill_in_procs((gx_device *)dev);
}
/* Make a monobit memory device. This is never a page device. */
@@ -188,6 +189,7 @@
set_dev_proc(dev, get_page_device, gx_default_get_page_device);
gx_device_set_target((gx_device_forward *)dev, target);
gdev_mem_mono_set_inverted(dev, true);
+ check_device_separable((gx_device *)dev);
gx_device_fill_in_procs((gx_device *)dev);
}
Index: src/gdevp14.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevp14.c,v
retrieving revision 1.20
diff -u -r1.20 gdevp14.c
--- a/src/gdevp14.c 4 Dec 2003 12:35:34 -0000 1.20
+++ b/src/gdevp14.c 18 May 2004 03:52:22 -0000
@@ -1006,6 +1006,7 @@
if (code < 0)
return NULL;
+ check_device_separable((gx_device *)mdev);
gx_device_fill_in_procs((gx_device *)mdev);
mdev->pdf14_dev = pdev;
mdev->opacity = pis->opacity.alpha;
@@ -1589,6 +1590,7 @@
if (code < 0)
return code;
+ check_device_separable((gx_device *)p14dev);
gx_device_fill_in_procs((gx_device *)p14dev);
gs_pdf14_device_copy_params((gx_device *)p14dev, target);
Index: src/gdevp2up.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevp2up.c,v
retrieving revision 1.5
diff -u -r1.5 gdevp2up.c
--- a/src/gdevp2up.c 1 Apr 2004 04:51:42 -0000 1.5
+++ b/src/gdevp2up.c 18 May 2004 03:52:22 -0000
@@ -116,6 +116,7 @@
if (prdev == 0)
return_error(gs_error_VMerror);
memcpy(prdev, prdev_template, prdev_size);
+ check_device_separable((gx_device *)rdev);
gx_device_fill_in_procs(rdev);
set_dev_proc(prdev, open_device,
dev_proc(&gs_pcx256_device, open_device));
Index: src/gdevpbm.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevpbm.c,v
retrieving revision 1.10
diff -u -r1.10 gdevpbm.c
--- a/src/gdevpbm.c 9 Oct 2002 02:34:11 -0000 1.10
+++ b/src/gdevpbm.c 18 May 2004 03:52:23 -0000
@@ -325,13 +325,39 @@
return 0;
}
+/*
+ * Pre gs8.00 version of RGB mapping for 24-bit true (RGB) color devices
+ * It is kept here for backwards comparibility since the gs8.00 version
+ * has changed in functionality. The new one requires that the device be
+ * 'separable'. This routine is logically separable but does not require
+ * the various color_info fields associated with separability (comp_shift,
+ * comp_bits, and comp_mask) be setup.
+ */
+
+private gx_color_index
+gx_old_default_rgb_map_rgb_color(gx_device * dev,
+ gx_color_value r, gx_color_value g, gx_color_value b)
+{
+ if (dev->color_info.depth == 24)
+ return gx_color_value_to_byte(b) +
+ ((uint) gx_color_value_to_byte(g) << 8) +
+ ((ulong) gx_color_value_to_byte(r) << 16);
+ else {
+ int bpc = dev->color_info.depth / 3;
+ int drop = sizeof(gx_color_value) * 8 - bpc;
+
+ return ((((r >> drop) << bpc) + (g >> drop)) << bpc) + (b >> drop);
+ }
+}
+
/* Map an RGB color to a PPM color tuple. */
/* Keep track of whether the image is black-and-white, gray, or colored. */
private gx_color_index
ppm_map_rgb_color(gx_device * pdev, const gx_color_value cv[])
{
gx_device_pbm * const bdev = (gx_device_pbm *)pdev;
- gx_color_index color = gx_default_encode_color(pdev, cv);
+ gx_color_index color =
+ gx_old_default_rgb_map_rgb_color(pdev, cv[0], cv[1], cv[2]);
int bpc = pdev->color_info.depth / 3;
gx_color_index mask =
((gx_color_index)1 << (pdev->color_info.depth - bpc)) - 1;
Index: src/gdevpcx.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevpcx.c,v
retrieving revision 1.6
diff -u -r1.6 gdevpcx.c
--- a/src/gdevpcx.c 1 Apr 2004 04:51:42 -0000 1.6
+++ b/src/gdevpcx.c 18 May 2004 03:52:23 -0000
@@ -58,7 +58,7 @@
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
X_DPI, Y_DPI,
0, 0, 0, 0, /* margins */
- 1, 8, 255, 0, 256, 0, pcx256_print_page)
+ 1, 8, 255, 255, 256, 256, pcx256_print_page)
};
/* 4-bit planar (EGA/VGA-style) color. */
Index: src/gdevplnx.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevplnx.c,v
retrieving revision 1.7
diff -u -r1.7 gdevplnx.c
--- a/src/gdevplnx.c 4 Dec 2003 12:35:34 -0000 1.7
+++ b/src/gdevplnx.c 18 May 2004 03:52:24 -0000
@@ -395,6 +395,7 @@
gx_device_init((gx_device *)edev,
(const gx_device *)&gs_plane_extract_device,
edev->memory, true);
+ check_device_separable((gx_device *)edev);
gx_device_forward_fill_in_procs((gx_device_forward *)edev);
gx_device_set_target((gx_device_forward *)edev, target);
gx_device_copy_params((gx_device *)edev, target);
Index: src/gdevpnga.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevpnga.c,v
retrieving revision 1.8
diff -u -r1.8 gdevpnga.c
--- a/src/gdevpnga.c 20 Jan 2004 19:11:11 -0000 1.8
+++ b/src/gdevpnga.c 18 May 2004 03:52:25 -0000
@@ -764,6 +764,7 @@
if (code < 0)
return NULL;
+ check_device_separable((gx_device *)mdev);
gx_device_fill_in_procs((gx_device *)mdev);
mdev->pnga_dev = pdev;
mdev->opacity = pis->opacity.alpha;
Index: src/gdevprn.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevprn.c,v
retrieving revision 1.14
diff -u -r1.14 gdevprn.c
--- a/src/gdevprn.c 4 Dec 2003 12:35:34 -0000 1.14
+++ b/src/gdevprn.c 18 May 2004 03:52:26 -0000
@@ -983,6 +983,7 @@
if (target == (gx_device *)mdev) {
/* The following is a special hack for setting up printer devices. */
assign_dev_procs(mdev, mdproto);
+ check_device_separable((gx_device *)mdev);
gx_device_fill_in_procs((gx_device *)mdev);
} else
gs_make_mem_device(mdev, mdproto, mem, (for_band ? 1 : 0),
Index: src/gdevpsd.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevpsd.c,v
retrieving revision 1.10
diff -u -r1.10 gdevpsd.c
--- a/src/gdevpsd.c 29 Apr 2004 18:51:28 -0000 1.10
+++ b/src/gdevpsd.c 18 May 2004 03:52:27 -0000
@@ -175,8 +175,7 @@
psd_print_page), /* Printer page print routine */
/* devn_params specific parameters */
{ 8, /* Bits per color - must match ncomp, depth, etc. above */
- /* Names of color model colorants */
- (fixed_colorant_names_list *) &DeviceRGBComponents,
+ &DeviceRGBComponents, /* Names of color model colorants */
3, /* Number colorants for RGB */
{0}, /* SeparationNames */
{0}, /* SeparationOrder names */
@@ -203,8 +202,7 @@
psd_print_page), /* Printer page print routine */
/* devn_params specific parameters */
{ 8, /* Bits per color - must match ncomp, depth, etc. above */
- /* Names of color model colorants */
- (fixed_colorant_names_list *) &DeviceCMYKComponents,
+ &DeviceCMYKComponents, /* Names of color model colorants */
4, /* Number colorants for CMYK */
{0}, /* SeparationNames */
{0}, /* SeparationOrder names */
@@ -558,33 +556,6 @@
}
#undef set_param_array
-#define compare_color_names(name, name_size, str, str_size) \
- (name_size == str_size && \
- (strncmp((const char *)name, (const char *)str, name_size) == 0))
-
-/*
- * This routine will check if a name matches any item in a list of process model
- * color component names.
- */
-private bool
-check_process_color_names(const fixed_colorant_names_list * pcomp_list,
- const gs_param_string * pstring)
-{
- if (pcomp_list) {
- fixed_colorant_name * plist =
- (fixed_colorant_name *) * pcomp_list;
- uint size = pstring->size;
-
- while( *plist) {
- if (compare_color_names(*plist, strlen(*plist), pstring->data, size)) {
- return true;
- }
- plist++;
- }
- }
- return false;
-}
-
#define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
BEGIN\
switch (code = pread(plist, (param_name = pname), &(pa))) {\
@@ -631,26 +602,22 @@
{
xdev->color_model = color_model;
if (color_model == psd_DEVICE_GRAY) {
- xdev->devn_params.std_colorant_names =
- (fixed_colorant_names_list *) &DeviceGrayComponents;
+ xdev->devn_params.std_colorant_names = &DeviceGrayComponents;
xdev->devn_params.num_std_colorant_names = 1;
xdev->color_info.cm_name = "DeviceGray";
xdev->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE;
} else if (color_model == psd_DEVICE_RGB) {
- xdev->devn_params.std_colorant_names =
- (fixed_colorant_names_list *) &DeviceRGBComponents;
+ xdev->devn_params.std_colorant_names = &DeviceRGBComponents;
xdev->devn_params.num_std_colorant_names = 3;
xdev->color_info.cm_name = "DeviceRGB";
xdev->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE;
} else if (color_model == psd_DEVICE_CMYK) {
- xdev->devn_params.std_colorant_names =
- (fixed_colorant_names_list *) &DeviceCMYKComponents;
+ xdev->devn_params.std_colorant_names = &DeviceCMYKComponents;
xdev->devn_params.num_std_colorant_names = 4;
xdev->color_info.cm_name = "DeviceCMYK";
xdev->color_info.polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
} else if (color_model == psd_DEVICE_N) {
- xdev->devn_params.std_colorant_names =
- (fixed_colorant_names_list *) &DeviceCMYKComponents;
+ xdev->devn_params.std_colorant_names = &DeviceCMYKComponents;
xdev->devn_params.num_std_colorant_names = 4;
xdev->color_info.cm_name = "DeviceN";
xdev->color_info.polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
@@ -750,7 +717,7 @@
psd_get_color_comp_index(const gx_device * dev, const char * pname,
int name_size, int component_type)
{
- gs_devn_params * pparams = &(((psd_device *)dev)->devn_params);
+ const gs_devn_params * pparams = &(((const psd_device *)dev)->devn_params);
int num_order = pparams->separation_order.num_names;
int color_component_number = 0;
Index: src/gdevrops.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevrops.c,v
retrieving revision 1.10
diff -u -r1.10 gdevrops.c
--- a/src/gdevrops.c 28 Apr 2004 09:39:50 -0000 1.10
+++ b/src/gdevrops.c 18 May 2004 03:52:27 -0000
@@ -134,6 +134,7 @@
NULL, true);
gx_device_set_target((gx_device_forward *)dev, target);
/* Drawing operations are defaulted, non-drawing are forwarded. */
+ check_device_separable((gx_device *) dev);
gx_device_fill_in_procs((gx_device *) dev);
gx_device_copy_params((gx_device *)dev, target);
dev->log_op = log_op;
Index: src/gdevxalt.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevxalt.c,v
retrieving revision 1.10
diff -u -r1.10 gdevxalt.c
--- a/src/gdevxalt.c 7 Sep 2002 20:02:54 -0000 1.10
+++ b/src/gdevxalt.c 18 May 2004 03:52:36 -0000
@@ -406,6 +406,7 @@
if (code < 0)
return 0;
+ check_device_separable(tdev);
gx_device_fill_in_procs(tdev);
gx_device_set_target((gx_device_forward *)dev, tdev);
x_clear_color_cache(dev);
Index: src/gdevxini.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevxini.c,v
retrieving revision 1.13
diff -u -r1.13 gdevxini.c
--- a/src/gdevxini.c 16 Jun 2002 05:48:55 -0000 1.13
+++ b/src/gdevxini.c 18 May 2004 03:52:37 -0000
@@ -606,11 +606,14 @@
COPY_PROC(text_begin);
#undef COPY_PROC
if (xdev->is_buffered) {
+ check_device_separable((gx_device *)xdev);
gx_device_forward_fill_in_procs((gx_device_forward *)xdev);
xdev->box_procs = gdev_x_box_procs;
xdev->box_proc_data = xdev;
- } else
+ } else {
+ check_device_separable((gx_device *)xdev);
gx_device_fill_in_procs((gx_device *)xdev);
+ }
}
return 0;
}
Index: src/gsdevice.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsdevice.c,v
retrieving revision 1.20
diff -u -r1.20 gsdevice.c
--- a/src/gsdevice.c 13 Dec 2003 18:07:56 -0000 1.20
+++ b/src/gsdevice.c 18 May 2004 03:52:38 -0000
@@ -314,6 +314,7 @@
{
if (dev->is_open)
return 0;
+ check_device_separable(dev);
gx_device_fill_in_procs(dev);
{
int code = (*dev_proc(dev, open_device))(dev);
Index: src/gslib.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gslib.c,v
retrieving revision 1.12
diff -u -r1.12 gslib.c
--- a/src/gslib.c 18 Aug 2003 21:21:57 -0000 1.12
+++ b/src/gslib.c 18 May 2004 03:52:41 -0000
@@ -153,6 +153,7 @@
/****** WRONG ******/
gs_lib_device_list(&list, NULL);
gs_copydevice(&dev, list[0], mem);
+ check_device_separable(dev);
gx_device_fill_in_procs(dev);
bbdev =
gs_alloc_struct_immovable(mem, gx_device_bbox, &st_device_bbox,
Index: src/gxcmap.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxcmap.c,v
retrieving revision 1.18
diff -u -r1.18 gxcmap.c
--- a/src/gxcmap.c 16 Jan 2004 06:36:59 -0000 1.18
+++ b/src/gxcmap.c 18 May 2004 03:52:46 -0000
@@ -50,8 +50,9 @@
gx_default_encode_color(gx_device * dev, const gx_color_value cv[])
{
int ncomps = dev->color_info.num_components;
- int i, i_gray = dev->color_info.gray_index;
+ int i;
const byte * comp_shift = dev->color_info.comp_shift;
+ const byte * comp_bits = dev->color_info.comp_bits;
gx_color_index color = 0;
#ifdef DEBUG
@@ -61,11 +62,9 @@
}
#endif
for (i = 0; i < ncomps; i++) {
- ulong cbits = cv[i] * ((i == i_gray ?
- dev->color_info.max_gray :
- dev->color_info.max_color ) + 1);
+ color |= (gx_color_index)(cv[i] >> (gx_color_value_bits - comp_bits[i]))
+ << comp_shift[i];
- color |= (cbits / (gx_max_color_value + 1)) << comp_shift[i];
}
return color;
}
@@ -76,7 +75,9 @@
int ncomps = dev->color_info.num_components;
int i;
const byte * comp_shift = dev->color_info.comp_shift;
+ const byte * comp_bits = dev->color_info.comp_bits;
const gx_color_index * comp_mask = dev->color_info.comp_mask;
+ int bits, shift;
#ifdef DEBUG
if ( dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN ) {
@@ -86,12 +87,14 @@
#endif
for (i = 0; i < ncomps; i++) {
- gx_color_index div = ( i == dev->color_info.gray_index ?
- dev->color_info.max_gray :
- dev->color_info.max_color ) + 1;
-
- cv[i] = (gx_color_value)(((color & comp_mask[i]) >> comp_shift[i]) *
- (gx_max_color_value + 1) / div);
+ bits = (color & comp_mask[i]) >> comp_shift[i];
+ shift = gx_color_value_bits - comp_bits[i];
+ cv[i] = bits << shift;
+ while ((shift-=comp_bits[i]) >= 0)
+ cv[i] |= bits << shift;
+ if (shift < 0)
+ cv[i] |= bits >> -shift;
+
}
return 0;
}
Index: src/gxdevcli.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxdevcli.h,v
retrieving revision 1.31
diff -u -r1.31 gxdevcli.h
--- a/src/gxdevcli.h 6 May 2004 05:19:15 -0000 1.31
+++ b/src/gxdevcli.h 18 May 2004 03:52:49 -0000
@@ -491,14 +491,13 @@
#define dci_std_gray_index(nc) \
((nc) == 3 ? GX_CINFO_COMP_NO_INDEX : (nc) - 1)
-#define dci_alpha_values(nc, depth, mg, mc, dg, dc, ta, ga) \
- dci_extended_alpha_values(nc, nc, \
- dci_std_polarity(nc), \
- depth, \
- dci_std_gray_index(nc), \
- mg, mc, dg, dc, ta, ga, \
- (depth >= 16 ? GX_CINFO_SEP_LIN \
- : GX_CINFO_UNKNOWN_SEP_LIN), \
+#define dci_alpha_values(nc, depth, mg, mc, dg, dc, ta, ga) \
+ dci_extended_alpha_values(nc, nc, \
+ dci_std_polarity(nc), \
+ depth, \
+ dci_std_gray_index(nc), \
+ mg, mc, dg, dc, ta, ga, \
+ GX_CINFO_UNKNOWN_SEP_LIN, \
dci_std_cm_name(nc) )
Index: src/gximag3x.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gximag3x.c,v
retrieving revision 1.15
diff -u -r1.15 gximag3x.c
--- a/src/gximag3x.c 11 Mar 2004 14:50:50 -0000 1.15
+++ b/src/gximag3x.c 18 May 2004 03:52:51 -0000
@@ -501,6 +501,7 @@
midev->bitmap_memory = mem;
midev->width = width;
midev->height = height;
+ check_device_separable((gx_device *)midev);
gx_device_fill_in_procs((gx_device *)midev);
code = dev_proc(midev, open_device)((gx_device *)midev);
if (code < 0) {
Index: src/gximage3.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gximage3.c,v
retrieving revision 1.12
diff -u -r1.12 gximage3.c
--- a/src/gximage3.c 18 Aug 2003 21:21:57 -0000 1.12
+++ b/src/gximage3.c 18 May 2004 03:52:52 -0000
@@ -110,6 +110,7 @@
midev->bitmap_memory = mem;
midev->width = width;
midev->height = height;
+ check_device_separable((gx_device *)midev);
gx_device_fill_in_procs((gx_device *)midev);
code = dev_proc(midev, open_device)((gx_device *)midev);
if (code < 0) {
Index: src/gxpcmap.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxpcmap.c,v
retrieving revision 1.11
diff -u -r1.11 gxpcmap.c
--- a/src/gxpcmap.c 19 Oct 2003 06:15:30 -0000 1.11
+++ b/src/gxpcmap.c 18 May 2004 03:52:53 -0000
@@ -153,6 +153,7 @@
gx_device_init((gx_device *)adev,
(const gx_device *)&gs_pattern_accum_device,
mem, true);
+ check_device_separable((gx_device *)adev);
gx_device_forward_fill_in_procs((gx_device_forward *)adev);
return adev;
}
Index: src/zcolor.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/zcolor.c,v
retrieving revision 1.17
diff -u -r1.17 zcolor.c
--- a/src/zcolor.c 11 Nov 2003 11:23:17 -0000 1.17
+++ b/src/zcolor.c 18 May 2004 03:53:04 -0000
@@ -475,6 +475,190 @@
return 0;
}
+/*
+ * <param1> ... <paramN> .color_test <param1> ... <paramN>
+ *
+ * encode and decode color to allow mapping to be tested.
+ */
+int zcolor_test(i_ctx_t *i_ctx_p)
+{
+ gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ gx_device *dev = gs_currentdevice(igs);
+ int ncomp = dev->color_info.num_components;
+ gx_color_index color;
+ int i;
+ if (ref_stack_count(&o_stack) < ncomp)
+ return_error(e_stackunderflow);
+ for (i=0; i<ncomp; i++) {
+ if (r_has_type(&osp[-i], t_real))
+ cv[i] = (gx_color_value)
+ (osp[-i].value.realval * gx_max_color_value);
+ else if (r_has_type(&osp[-i], t_integer))
+ cv[i] = (gx_color_value)
+ (osp[-i].value.intval * gx_max_color_value);
+ else
+ return_error(e_typecheck);
+ }
+ color = (*dev_proc(dev, encode_color)) (dev, cv);
+ (*dev_proc(dev, decode_color)) (dev, color, cv);
+ for (i=0; i<ncomp; i++)
+ make_real(&osp[-i], (float)cv[i] / (float)gx_max_color_value);
+ return 0;
+}
+
+/*
+ * <levels> .color_test_all <value0> ... <valueN>
+ *
+ * Test encode/decode color procedures for a range of values.
+ * Return value with the worst error in a single component.
+ */
+int zcolor_test_all(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ gx_color_value cvout[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ gx_color_value cvbad[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ int counter[GX_DEVICE_COLOR_MAX_COMPONENTS];
+ gx_device *dev = gs_currentdevice(igs);
+ int ncomp = dev->color_info.num_components;
+ int steps;
+ int maxerror = 0;
+ int err;
+ int acceptable_error;
+ int linsep = dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN;
+ int linsepfailed = 0;
+ int lsmaxerror = 0;
+ gx_color_index color, lscolor;
+ int i, j, k;
+ int finished = 0;
+
+ if (ncomp == 1)
+ acceptable_error = gx_max_color_value / dev->color_info.max_gray + 1;
+ else
+ acceptable_error = gx_max_color_value / dev->color_info.max_color + 1;
+
+ if (ref_stack_count(&o_stack) < 1)
+ return_error(e_stackunderflow);
+ if (!r_has_type(&osp[0], t_integer))
+ return_error(e_typecheck);
+ steps = osp[0].value.intval;
+ for (i=0; i<ncomp; i++) {
+ counter[i] = 0;
+ cvbad[i] = 0;
+ }
+
+ dprintf1("Number of components = %d\n", ncomp);
+ dprintf1("Depth = %d\n", dev->color_info.depth);
+ dprintf2("max_gray = %d dither_grays = %d\n",
+ dev->color_info.max_gray, dev->color_info.dither_grays);
+ dprintf2("max_color = %d dither_colors = %d\n",
+ dev->color_info.max_color, dev->color_info.dither_colors);
+ dprintf1("polarity = %s\n",
+ dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ? "Additive" :
+ dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE ?"Subtractive":
+ "Unknown");
+ /* Indicate color index value with all colorants = zero */
+ for (i=0; i<ncomp; i++)
+ cv[i] = 0;
+ color = (*dev_proc(dev, encode_color)) (dev, cv);
+ dprintf1("Zero color index: %8x\n", color);
+
+ dprintf1("separable_and_linear = %s\n",
+ linsep == GX_CINFO_SEP_LIN_NONE ? "No" :
+ linsep == GX_CINFO_SEP_LIN ? "Yes" :
+ "Unknown");
+ if (dev->color_info.gray_index == GX_CINFO_COMP_INDEX_UNKNOWN)
+ dprintf("gray_index is unknown\n");
+ else
+ dprintf1("gray_index = %d\n", dev->color_info.gray_index);
+ if (linsep) {
+ dprintf(" Shift Mask Bits\n");
+ for (i=0; i<ncomp; i++) {
+ dprintf3(" %5d %8x %4d\n",
+ (int)(dev->color_info.comp_shift[i]),
+ (int)(dev->color_info.comp_mask[i]),
+ (int)(dev->color_info.comp_bits[i]));
+ }
+ }
+
+ while (!finished) {
+ for (j=0; j<=steps; j++) {
+ for (i=0; i<ncomp; i++)
+ cv[i] = counter[i] * gx_max_color_value / steps;
+ color = (*dev_proc(dev, encode_color)) (dev, cv);
+ if (linsep) {
+ /* Derive it the other way */
+ lscolor = gx_default_encode_color(dev, cv);
+ if ((color != lscolor) && (linsepfailed < 5)) {
+ linsepfailed++;
+ dprintf("Failed separable_and_linear for");
+ for (i=0; i<ncomp; i++)
+ dprintf1(" %d", cv[i]);
+ dprintf("\n");
+ dprintf2("encode_color=%x gx_default_encode_color=%x\n",
+ (int)color, (int)lscolor);
+ }
+ }
+ (*dev_proc(dev, decode_color)) (dev, color, cvout);
+ for (i=0; i<ncomp; i++) {
+ err = (int)cvout[i] - (int)cv[i];
+ if (err < 0)
+ err = -err;
+ if (err > maxerror) {
+ maxerror = err;
+ for (k=0; k<ncomp; k++)
+ cvbad[k] = cv[k];
+ }
+ }
+ if (linsep) {
+ gx_default_decode_color(dev, color, cvout);
+ for (i=0; i<ncomp; i++) {
+ err = (int)cvout[i] - (int)cv[i];
+ if (err < 0)
+ err = -err;
+ if (err > lsmaxerror) {
+ lsmaxerror = err;
+ }
+ }
+ }
+ counter[0] += 1;
+ }
+ counter[0] = 0;
+ i = 1;
+ while (i < ncomp) {
+ counter[i] += 1;
+ if (counter[i] > steps) {
+ counter[i] = 0;
+ i++;
+ }
+ else
+ break;
+ }
+ if (i >= ncomp)
+ finished = 1;
+ }
+
+ dprintf2("Maximum error %g %s\n",
+ (float)maxerror / (float)gx_max_color_value,
+ maxerror <= acceptable_error ? "is Ok" :
+ maxerror <= 3*acceptable_error/2 ? "is POOR" : "FAILED");
+
+ if (linsep)
+ dprintf2("Maximum linear_and_separable error %g %s\n",
+ (float)lsmaxerror / (float)gx_max_color_value,
+ lsmaxerror <= acceptable_error ? "is Ok" :
+ lsmaxerror <= 3*acceptable_error/2 ? "is POOR" : "FAILED");
+
+ /* push worst value */
+ push(ncomp-1);
+ op -= ncomp - 1;
+ for (i=0; i<ncomp; i++)
+ make_real(op+i, (float)cvbad[i] / (float)gx_max_color_value);
+
+ return 0;
+}
+
+
/* ------ Initialization procedure ------ */
const op_def zcolor_op_defs[] =
@@ -496,6 +680,9 @@
{ "1%zcolor_remap_one_signed_finish", zcolor_remap_one_signed_finish },
{ "0%zcolor_reset_transfer", zcolor_reset_transfer },
{ "0%zcolor_remap_color", zcolor_remap_color },
+ { "0.color_test", zcolor_test },
+ { "1.color_test_all", zcolor_test_all },
+
/* high level device support */
{ "0.includecolorspace", zincludecolorspace },