Revised fix for 687418 WTS does not work withbitcmyk driver
"Dan Coby" <[email protected]> Mon, 24 May 2004 16:13:52 -0700
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
One more revision on this fix. This revision adds more corrections
into individual devices (see items 18 and 19 in the list below). These
were found while testing on linux. The major change included in this
revision is a rewrite of the gx_default_decode_color routine (see item
21). The previous version contained a while loop that was the subject
of complaints about being confusing and slow. Here is the entire
revised routine.
/*
* This routine is only used if the device is 'separable'. See
* separable_and_linear in gxdevcli.h for more information.
*/
int
gx_default_decode_color(gx_device * dev, gx_color_index color, gx_color_value cv[])
{
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;
uint shift, ivalue, nbits, scale;
#ifdef DEBUG
if ( dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN ) {
dprintf( "gx_default_decode_color() requires separable and linear\n" );
return gs_error_rangecheck;
}
#endif
for (i = 0; i < ncomps; i++) {
/*
* Convert from the gx_color_index bits to a gx_color_value.
* Split the conversion into an integer and a fraction calculation
* so we can do integer arthmetic. The calculation is equivalent
* to floor(0xffff.fffff * ivalue / ((1 << nbits) - 1))
*/
nbits = comp_bits[i];
scale = gx_max_color_value / ((1 << nbits) - 1);
ivalue = (color & comp_mask[i]) >> comp_shift[i];
cv[i] = ivalue * scale;
/*
* Since our scaling factor is an integer, we lost the fraction.
* Determine what part of the ivalue that the faction would have
* added into the result.
*/
shift = nbits - (gx_color_value_bits % nbits);
cv[i] += ivalue >> shift;
}
return 0;
}
Dan
Log message:
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.)
(See the comments in item 21 below about the gx_default_decode_color
routine.)
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
color_info fields.
18. Added a call to check_device_separable into gdev_x_open in
gdevxini.c. With this addition, the x11 device is detected as being
sperable. This is need since the x11 device sets up a color map in
gdev_x_open. Prior to this, the encode_color routine for he x11 device
returns 0 regardless of its input.
19. Modified the uniprint device (gdevupd.c) and color laser jet
devices (gdevcljc.) to use 256 instead of 5 for its dither_gray and
dither_color values with devices that have 8 bits per colorant. This
is appropriate since the the max_gray and max_color values are 255.
(I do not know why these values were being set to 5. This same error
was found in gdevcdj.c. My only guess is that it was a typo in gdevcdj.c.
Since this device is recommended as an example of how to code a color
raster device (in Devices.htm), the error was propogated into the
other devices.
20. Added more comments to gxdevcli.h explaining the use of the
gray_index, max_gray, dither_grays, max_color, and dither_colors
fields in the device color_info structure.
21. Changed the gx_default_decode_color routine (again). Russell
Lang created two revisions to this routine as part of his efforts on
this task. However one version was slow but produced the desired
results. The second version was faster but its output was slightly
different. This revision produces the same output as the first
version but does so without the while loops that slowed its operation.
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
_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review
687418.txt
(text/plain, 47.3 KB)
? src/gxdevice.c
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 24 May 2004 23:08:56 -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/gdevcljc.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevcljc.c,v
retrieving revision 1.6
diff -u -r1.6 gdevcljc.c
--- a/src/gdevcljc.c 21 Feb 2002 22:24:51 -0000 1.6
+++ b/src/gdevcljc.c 24 May 2004 23:08:56 -0000
@@ -96,6 +96,6 @@
85, 110, X_DPI, Y_DPI,
0.167, 0.167,
0.167, 0.167,
- 3, 24, 255, 255, 5, 5,
+ 3, 24, 255, 255, 256, 256,
cljc_print_page)
};
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 24 May 2004 23:08:56 -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 24 May 2004 23:08:57 -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 24 May 2004 23:08:58 -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 24 May 2004 23:08:58 -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,23 +440,28 @@
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);
+ if (color_index == 0) /* If no bits then we have a problem */
+ return;
if (color_index & current_bits) /* Check for overlapping bits */
return;
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 +469,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);
@@ -465,11 +478,26 @@
}
/* If we get to here then the device is very likely to be separable. */
pinfo->separable_and_linear = GX_CINFO_SEP_LIN;
- for (i = 0; i < num_components; i ++) {
+ for (i = 0; i < num_components; i++) {
pinfo->comp_shift[i] = comp_shift[i];
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 +650,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 +674,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 24 May 2004 23:08:59 -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 24 May 2004 23:09:00 -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.22
diff -u -r1.22 gdevp14.c
--- a/src/gdevp14.c 18 May 2004 11:07:29 -0000 1.22
+++ b/src/gdevp14.c 24 May 2004 23:09:01 -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;
@@ -1597,6 +1598,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 24 May 2004 23:09:01 -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 24 May 2004 23:09:02 -0000
@@ -325,14 +325,40 @@
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);
- int bpc = pdev->color_info.depth / 3;
+ gx_color_index color =
+ gx_old_default_rgb_map_rgb_color(pdev, cv[0], cv[1], cv[2]);
+ uint bpc = pdev->color_info.depth / 3;
gx_color_index mask =
((gx_color_index)1 << (pdev->color_info.depth - bpc)) - 1;
if (!(((color >> bpc) ^ color) & mask)) { /* gray shade */
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 24 May 2004 23:09:02 -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.8
diff -u -r1.8 gdevplnx.c
--- a/src/gdevplnx.c 18 May 2004 11:07:29 -0000 1.8
+++ b/src/gdevplnx.c 24 May 2004 23:09:04 -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 24 May 2004 23:09:04 -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 24 May 2004 23:09:05 -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 24 May 2004 23:09:06 -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 24 May 2004 23:09:06 -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/gdevupd.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevupd.c,v
retrieving revision 1.14
diff -u -r1.14 gdevupd.c
--- a/src/gdevupd.c 4 May 2004 21:31:43 -0000 1.14
+++ b/src/gdevupd.c 24 May 2004 23:09:13 -0000
@@ -267,8 +267,8 @@
1, /** color_info.depth 1/2/4/8/16/24/32 */
1, /** color_info.max_gray # of distinct gray levels -1 (255/1) */
0, /** color_info.max_color # of distinct color levels -1 (255/1/0)*/
- 1, /** color_info.dither_grays size of gray ramp for dithering (5/2) */
- 0, /** color_info.dither_colors size of color cube ditto (5/2/0) */
+ 2, /** color_info.dither_grays size of gray ramp for dithering (256/2) */
+ 0, /** color_info.dither_colors size of color cube ditto (256/2/0) */
upd_print_page), /** Print-procedure */
{ NULL, 0, true }, /** Driver-Version */
NULL /** upd-field: Initially none */
@@ -2032,7 +2032,7 @@
nbits = 0;
for(i = 0; i < ncomp; ++i) if(nbits < int_a[IA_COMPBITS].data[i])
nbits = int_a[IA_COMPBITS].data[i];
- if(2 < nbits) ip[4] = 5;
+ if(2 < nbits) ip[4] = 256;
else ip[4] = 2;
} /* Gray-Ramp */
@@ -2040,7 +2040,7 @@
nbits = 0;
for(i = 0; i < ncomp; ++i) if(nbits < int_a[IA_COMPBITS].data[i])
nbits = int_a[IA_COMPBITS].data[i];
- if(2 < nbits) ip[5] = 5;
+ if(2 < nbits) ip[5] = 256;
else ip[5] = 2;
} /* Color-Ramp */
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 24 May 2004 23:09:14 -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/gdevxcf.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevxcf.c,v
retrieving revision 1.6
diff -u -r1.6 gdevxcf.c
--- a/src/gdevxcf.c 11 Mar 2004 14:50:50 -0000 1.6
+++ b/src/gdevxcf.c 24 May 2004 23:09:15 -0000
@@ -217,8 +217,8 @@
GX_DEVICE_COLOR_MAX_COMPONENTS, 3, /* MaxComponents, NumComp */
GX_CINFO_POLARITY_ADDITIVE, /* Polarity */
24, 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_UNKNOWN SEP_LIN, /* Let check_device_separable set up values */
"DeviceN", /* Process color model name */
xcf_print_page), /* Printer page print routine */
/* DeviceN device specific parameters */
@@ -241,8 +241,8 @@
GX_DEVICE_COLOR_MAX_COMPONENTS, 4, /* MaxComponents, NumComp */
GX_CINFO_POLARITY_SUBTRACTIVE, /* Polarity */
32, 0, /* Depth, Gray_index, */
- 255, 255, 1, 1, /* MaxGray, MaxColor, DitherGray, DitherColor */
- GX_CINFO_SEP_LIN, /* Linear & Separable */
+ 255, 255, 256, 256, /* MaxGray, MaxColor, DitherGray, DitherColor */
+ GX_CINFO_UNKNOWN SEP_LIN, /* Let check_device_separable set up values */
"DeviceN", /* Process color model name */
xcf_print_page), /* Printer page print routine */
/* DeviceN device specific parameters */
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 24 May 2004 23:09:15 -0000
@@ -304,6 +304,9 @@
XCloseDisplay(xdev->dpy);
return code;
}
+ /* Now that the color map is setup check if the device is separable. */
+ check_device_separable((gx_device *)xdev);
+
gdev_x_setup_fontmap(xdev);
if (!xdev->ghostview) {
@@ -606,11 +609,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 24 May 2004 23:09:16 -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 24 May 2004 23:09:17 -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.19
diff -u -r1.19 gxcmap.c
--- a/src/gxcmap.c 18 May 2004 11:07:29 -0000 1.19
+++ b/src/gxcmap.c 24 May 2004 23:09:18 -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,22 +62,26 @@
}
#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;
}
+/*
+ * This routine is only used if the device is 'separable'. See
+ * separable_and_linear in gxdevcli.h for more information.
+ */
int
gx_default_decode_color(gx_device * dev, gx_color_index color, gx_color_value cv[])
{
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;
+ uint shift, ivalue, nbits, scale;
#ifdef DEBUG
if ( dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN ) {
@@ -86,12 +91,23 @@
#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);
+ /*
+ * Convert from the gx_color_index bits to a gx_color_value.
+ * Split the conversion into an integer and a fraction calculation
+ * so we can do integer arthmetic. The calculation is equivalent
+ * to floor(0xffff.fffff * ivalue / ((1 << nbits) - 1))
+ */
+ nbits = comp_bits[i];
+ scale = gx_max_color_value / ((1 << nbits) - 1);
+ ivalue = (color & comp_mask[i]) >> comp_shift[i];
+ cv[i] = ivalue * scale;
+ /*
+ * Since our scaling factor is an integer, we lost the fraction.
+ * Determine what part of the ivalue that the faction would have
+ * added into the result.
+ */
+ shift = nbits - (gx_color_value_bits % nbits);
+ cv[i] += ivalue >> 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 24 May 2004 23:09:20 -0000
@@ -328,31 +328,49 @@
* Index of the gray color component, if any. The max_gray and
* dither_gray values apply to this component only; all other
* components use the max_color and dither_color values.
+ *
+ * Note: This field refers to a 'gray' colorant because of the
+ * past use of the max_gray/color and dither_grays/colors fields.
+ * Prior to 8.00, the 'gray' values were used for monochrome
+ * devices and the 'color' values for RGB and CMYK devices.
+ * Ideally we would like to have the flexibiiity of allowing
+ * different numbers of intensity levels for each colorant.
+ * However this is not compatible with the pre 8.00 devices.
+ * With post 8.00 devices, we can have two different numbers of
+ * intensity levels. For one colorant (which is specified by
+ * the gray_index) we will use the max_gray/dither_grays values.
+ * The remaining colorants will use the max_color/dither_colors
+ * values. The colorant which is specified by the gray_index
+ * value does not have to be gray or black. For example if we
+ * have an RGB device and we want 32 intensity levels for red and
+ * blue and 64 levels for green, then we can set gray_index to
+ * 1 (the green colorant), set max_gray to 63 and dither_grays to
+ * 64, and set max_color to 31 and dither_colors to 32.
*
- * This will be GX_CINFO_COMP_NO_INDEX if there is no gray
+ * This will be GX_CINFO_COMP_NO_INDEX if there is no 'gray'
* component.
*/
byte gray_index;
/*
* max_gray and max_color are the number of distinct native
- * intensity levels, less 1, for the gray and all other color
+ * intensity levels, less 1, for the 'gray' and all other color
* components, respectively. For nearly all current devices
- * that support both gray and non-gray components, the two
- * parameters have the same value.
+ * that support both 'gray' and non-'gray' components, the two
+ * parameters have the same value. (See comment for gray_index.)
*
* dither_grays and dither_colors are the number of intensity
- * levels between which halftoning can occur, for the gray and
+ * levels between which halftoning can occur, for the 'gra'y and
* all other color components, respectively. This is
* essentially redundant information: in all reasonable cases,
* dither_grays = max_gray + 1 and dither_colors = max_color + 1.
* These parameters are, however, extensively used in the
* current code, and thus have been retained.
*
- * Note that the non-gray values may now be relevant even if
+ * Note that the non-'gray' values may now be relevant even if
* num_components == 1. This simplifies the handling of devices
* with configurable color models which may be set for a single
- * non-gray color model.
+ * non-'gray' color model.
*/
gx_color_value max_gray; /* # of distinct color levels -1 */
gx_color_value max_color;
@@ -491,14 +509,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 24 May 2004 23:09:21 -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 24 May 2004 23:09:22 -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 24 May 2004 23:09:22 -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 24 May 2004 23:09:23 -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 },
Index: doc/Language.htm
===================================================================
RCS file: /cvs/ghostscript/gs/doc/Language.htm,v
retrieving revision 1.84
diff -u -r1.84 Language.htm
--- a/doc/Language.htm 22 Apr 2004 06:38:19 -0000 1.84
+++ b/doc/Language.htm 24 May 2004 23:09:25 -0000
@@ -1332,6 +1332,21 @@
collection as a performance improvement. Additional settings may be added in the future.
</dl>
+<dl>
+<dt><b><tt>.color_test</tt></b> and <b><tt>.color_test_all</tt></b></dt>
+<dd>These operators are used for the verification of device encode_color and
+decode_color routines. They are for internal use only. Their function
+can, and probably will, change as Artifex's requirements change.
+<p>
+<dd>Currently these operators loop through a set of possible values for the inputs
+to the encode_color routine and then veify that the decode_color routines produce
+values that match the input set to within a tolerance which is based upon the number
+of bits used to encode a pixel. The operators also verify that if the device
+is 'separable' then that the values produced by gx_default_encode_color and
+gx_default_decode_color (the default encode/decode color handlers for a separable
+device) are consistent to within the same tolerance.
+</dl>
+
<h4><a name="Device"></a>Device operators</h4>
<dl>