FW: Fix for 687418 WTS does not work with bitcmyk driver.

"Dan Coby" <[email protected]>
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <[email protected]>
Fix for 687418 WTS does not work with bitcmyk driver.  This fix
is applicable to most devices.

DETAILS:

WTS screening, overprinting, halftoning for more than five colorants
and the fast halftoning logic need to be able to create gx_color_index
values without using the encode_color routine.  This only works if a
device is 'separable'.  However, by default, most devices indicate
'unknown'.  This change implements a heuristic for checking if a
device is separable.  If so then it also determines the various
related parameter values (comp_shift, comp_bits, comp_mask).


Index: src/gdevdflt.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevdflt.c,v
retrieving revision 1.17
diff -u -r1.17 gdevdflt.c
--- a/src/gdevdflt.c    17 Apr 2004 18:30:00 -0000      1.17
+++ b/src/gdevdflt.c    29 Apr 2004 00:37:05 -0000
@@ -331,7 +331,9 @@

 /*
  * If a device has a linear and separable encode color function then
- * set up the comp_bits, comp_mask, and comp_shift fields.
+ * set up the comp_bits, comp_mask, and comp_shift fields.  Note:  This
+ * routine assumes that the colorant shift factor decreases with the
+ * component number.  See check_device_separable() for a general routine.
  */
 void
 set_linear_color_bits_mask_shift(gx_device * dev)
@@ -362,6 +364,113 @@
 #undef comp_shift
 }

+/* Determine if a number is a power of two.  Works only for integers. */
+#define is_power_of_two(x) ((((x) - 1) & (x)) == 0)
+
+/*
+ * This routine attempts to determine if a device's encode_color procedure
+ * produces gx_color_index values which are 'separable'.  A 'separable'
value
+ * means two things.  Each colorant has a group of bits in the
gx_color_index
+ * value which is associated with the colorant.  These bits are separate.
+ * I.e. no bit is associated with more than one colorant.  If a colorant
has
+ * a value of zero then the bits associated with that colorant are zero.
+ * These criteria allows the graphics library to build gx_color_index
values
+ * from the colorant values and not using the encode_color routine. This is
+ * useful and necessary for overprinting, the WTS screeening, halftoning
more
+ * than four colorants, and the fast shading logic.  However this
information
+ * is not setup by the default device macros.  Thus we attempt to derive
this
+ * information.
+ *
+ * This routine can be fooled.  However it usually errors on the side of
+ * assuing that a device is not separable.  In this case it does not create
+ * any new problems.  In theory it can be fooled into believing that a
device
+ * is separable when it is not.  However we do not know of any real cases
that
+ * will fool it.
+ */
+void
+check_device_separable(gx_device * dev)
+{
+    int i, j;
+    gx_device_color_info * pinfo = &(dev->color_info);
+    int num_components = pinfo->num_components;
+    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
+    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
+    gx_color_index comp_mask[GX_DEVICE_COLOR_MAX_COMPONENTS];
+    gx_color_index color_index;
+    gx_color_index current_bits = 0;
+    gx_color_value colorants[GX_DEVICE_COLOR_MAX_COMPONENTS] = { 0 };
+
+    /* If this is already known then we do not need to do anything. */
+    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))
+       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))
+       return;
+    /*
+     * If num_gray or num_color is not a power of two then we assume that
+     * the device is not separable.  In theory this not a requirement but
+     * it has been true for all of the devices that we have seen so far.
+     * This assumption also makes the logic in the next section easier.
+     */
+    if (!is_power_of_two(pinfo->max_gray)
+                   || !is_power_of_two(pinfo->max_color))
+       return;
+    /*
+     * Use the encode_color routine to try to verify that the device is
+     * separable and to determine the shift count, etc. for each colorant.
+     */
+    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 ++) {
+       /* Check this colorant = max with all others = 0 */
+        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 & 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++)
+           color_index >>= 1;
+       comp_shift[i] = j;
+       /* Determine the bit count for the colorant */
+       for (j = 0; color_index != 0; j++)
+           color_index >>= 1;
+       comp_bits[i] = j;
+       /*
+        * We could verify that the bit count matches the dither_grays or
+        * dither_colors values, but this is not really required unless we
+        * 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 ++)
+           colorants[j] = gx_max_color_value;
+       colorants[i] = 0;
+       color_index = dev_proc(dev, encode_color)(dev, colorants);
+       if (color_index & comp_mask[i]) /* Check for overlapping bits */
+           return;
+    }
+    /* 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 ++) {
+       pinfo->comp_shift[i] = comp_shift[i];
+       pinfo->comp_bits[i] = comp_bits[i];
+       pinfo->comp_mask[i] = comp_mask[i];
+    }
+}
+#undef is_power_of_two
+
 /* Fill in NULL procedures in a device procedure record. */
 void
 gx_device_fill_in_procs(register gx_device * dev)
@@ -515,6 +624,9 @@
     if ( dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ) {
        set_linear_color_bits_mask_shift(dev);
     }
+    else if ( dev->color_info.separable_and_linear ==
GX_CINFO_UNKNOWN_SEP_LIN ) {
+       check_device_separable(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
[C:/_/artifex/687418]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.