[gs-cvs] gs/src

Dan Coby dan at casper.ghostscript.com
Wed Aug 28 16:11:08 PDT 2002


Update of /cvs/ghostscript/gs/src
In directory casper:/tmp/cvs-serv11732/src

Modified Files:
	gsht.c gsptype1.c gsptype2.c gxwts.c gxcht.c gxht.c gxclpath.c 
	gxclrast.c gxdcolor.c 
Log Message:
We have traced the difficulties with multiple-band processing in the code
we released on Aug. 26 to two problems:

  1. The halftone phase information is not adjusted for bands that
     start at locations other than the top of the page.

  2. The "moveto closepath" style of degenerate path, which our code
     allows to be passed through the band list, is used in the path
     encoding code to indicate that a path lies entirely outside the
     current band (i.e.: all of the path operators between the initial
     moveto and the final closepath have been skipped because they are
     outside of the band). This resulted in the code passing isolated
     "closepath" segments through the command list, which much confused
     the band list renderer.

The attached code release fixes both of these problems, and a couple of
other more minor issues we discovered. With this change, our system has
identical output for the banded and unbanded case for the pkmraw device
at 300 dpi, for all but one FTS file (027-09.ps). In that one case, the
banded and unbanded output are visually identical, so the output difference
may not be significant. We will look into this situation, and test some
of the other devices in the next day or so.

As best we can tell, halftone phase adjustment has never been correctly
implemented for the command list device. The pre-DeviceN code handles
binary halftone colors properly, but does not set the phase for general
colored halftones. General colored halftones are much more common in the
DeviceN code, which probably is the reason Dan first noticed the problem
with FTS file 245-07.ps (and others) with the DeviceN code.

                                                         Jan

Modified Files:

  src/gsht.c
    Modified the code that calculates the lcm_height field of a device
    halftone in gx_imager_dev_ht_install to use the full_height rather
    than the height of a halftone order. This typo was introduced sometime
    during the DeviceN development; the pre-DeviceN code was correct.

  src/gsptype1.c
  src/gsptype2.c
  src/gxwts.c
    Added the "get_phase" method to various gx_device_color_type_t
    instances.

  src/gxcht.c
  src/gxht.c
    Added the "get_phase" method to a pair of gx_device_color_type_t
    instances. Also modified the "write" and "read" methods of these 
    structures to ignore halftone phase information. This information
    must be passed to and be directly handled by the command list
    writer code, so that the command list renderer code may correct it
    for the band starting coordinates.

  src/gxclpath.c
    1. Modified cmd_put_drawing_color to directly handle halftone phase
       information, using the new "get_phase" method of device colors.
       The passing of this information must be perfomed at the command
       list level, so that the command list renderer can correct the
       phase for the starting point of the band.
    2. Also in cmd_put_drawing_color, "unset" the saved color information
       if the halftone id does not match the most recently set halftone,
       rather than setting the saved color pointer to 0.
    3. In cmd_put_path, when processing a segment containing a
       moveto followed by a closepath, check if the moveto was to a point
       outside of the current band, and discard the closepath if this
       is the case. This is necessary to avoid inserting isolated
       closepath segments into the command list.

  src/gxclrast.c
    Added code to initialize the dev_color variable to clist_playback_band
    to "no color".

  src/gxdcolor.c
  src/gxdcolor.h
    Added the "get_phase" method to the gx_device_color_type_t structure,
    and installed this method in various instances of the structure. Also
    provided the two canonical implementations of this method.




Index: gsht.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsht.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gsht.c	26 Aug 2002 23:00:07 -0000	1.8
+++ gsht.c	28 Aug 2002 23:11:06 -0000	1.9
@@ -1046,7 +1046,7 @@
             else
                 porder->wts = wts;
         } else {
-            uint   w = porder->width, h = porder->height;
+            uint   w = porder->width, h = porder->full_height;
             int    dw = igcd(lcm_width, w), dh = igcd(lcm_height, h);
 
             lcm_width /= dw;

Index: gsptype1.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsptype1.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gsptype1.c	22 Aug 2002 07:12:29 -0000	1.8
+++ gsptype1.c	28 Aug 2002 23:11:06 -0000	1.9
@@ -636,6 +636,7 @@
 const gx_device_color_type_t gx_dc_pattern = {
     &st_dc_pattern,
     gx_dc_pattern_save_dc, gx_dc_pattern_get_dev_halftone,
+    gx_dc_ht_get_phase,
     gx_dc_pattern_load, gx_dc_pattern_fill_rectangle,
     gx_dc_default_fill_masked, gx_dc_pattern_equal,
     gx_dc_pattern_write, gx_dc_pattern_read, 
@@ -648,6 +649,7 @@
 const gx_device_color_type_t gx_dc_pure_masked = {
     &st_dc_pure_masked,
     gx_dc_pattern_save_dc, gx_dc_pure_masked_get_dev_halftone,
+    gx_dc_no_get_phase,
     gx_dc_pure_masked_load, gx_dc_pure_masked_fill_rect,
     gx_dc_default_fill_masked, gx_dc_pure_masked_equal,
     gx_dc_pattern_write, gx_dc_pattern_read, 
@@ -660,6 +662,7 @@
 const gx_device_color_type_t gx_dc_binary_masked = {
     &st_dc_binary_masked,
     gx_dc_pattern_save_dc, gx_dc_binary_masked_get_dev_halftone,
+    gx_dc_ht_get_phase,
     gx_dc_binary_masked_load, gx_dc_binary_masked_fill_rect,
     gx_dc_default_fill_masked, gx_dc_binary_masked_equal,
     gx_dc_pattern_write, gx_dc_pattern_read, 
@@ -672,6 +675,7 @@
 const gx_device_color_type_t gx_dc_colored_masked = {
     &st_dc_colored_masked,
     gx_dc_pattern_save_dc, gx_dc_colored_masked_get_dev_halftone,
+    gx_dc_ht_get_phase,
     gx_dc_colored_masked_load, gx_dc_colored_masked_fill_rect,
     gx_dc_default_fill_masked, gx_dc_colored_masked_equal,
     gx_dc_pattern_write, gx_dc_pattern_read, 

Index: gsptype2.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsptype2.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gsptype2.c	22 Aug 2002 07:12:29 -0000	1.8
+++ gsptype2.c	28 Aug 2002 23:11:06 -0000	1.9
@@ -124,6 +124,7 @@
 const gx_device_color_type_t gx_dc_pattern2 = {
     &st_dc_pattern2,
     gx_dc_pattern_save_dc, gx_dc_pattern2_get_dev_halftone,
+    gx_dc_ht_get_phase,
     gx_dc_pattern2_load, gx_dc_pattern2_fill_rectangle,
     gx_dc_default_fill_masked, gx_dc_pattern2_equal,
     gx_dc_pattern_write, gx_dc_pattern_read,

Index: gxwts.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxwts.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- gxwts.c	22 Aug 2002 07:12:29 -0000	1.1
+++ gxwts.c	28 Aug 2002 23:11:06 -0000	1.2
@@ -46,6 +46,7 @@
 const gx_device_color_type_t gx_dc_type_data_wts = {
     &st_dc_wts,
     gx_dc_wts_save_dc, gx_dc_wts_get_dev_halftone,
+    gx_dc_ht_get_phase,
     gx_dc_wts_load, gx_dc_wts_fill_rectangle,
     gx_dc_default_fill_masked, gx_dc_wts_equal,
     gx_dc_wts_write, gx_dc_wts_read,

Index: gxcht.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxcht.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- gxcht.c	26 Aug 2002 23:00:07 -0000	1.9
+++ gxcht.c	28 Aug 2002 23:11:06 -0000	1.10
@@ -63,6 +63,7 @@
 const gx_device_color_type_t gx_dc_type_data_ht_colored = {
     &st_dc_ht_colored,
     gx_dc_ht_colored_save_dc, gx_dc_ht_colored_get_dev_halftone,
+    gx_dc_ht_get_phase,
     gx_dc_ht_colored_load, gx_dc_ht_colored_fill_rectangle,
     gx_dc_default_fill_masked, gx_dc_ht_colored_equal,
     gx_dc_ht_colored_write, gx_dc_ht_colored_read,
@@ -136,7 +137,6 @@
 private const int   dc_ht_colored_has_level = 0x02;
 private const int   dc_ht_colored_has_alpha = 0x04;
 private const int   dc_ht_colored_alpha_is_max = 0x08;
-private const int   dc_ht_colored_has_phase = 0x10;
 
 /*
  * Serialize a device color that uses a traditional colored halftone.
@@ -254,20 +254,6 @@
         }
     }
 
-    /*
-     * Moderate hack: the phase can be retrieved from either a binary or a
-     * colored halftone.
-     */
-    if ( psdc0 == 0                               ||
-         (psdc0->type != gx_dc_type_ht_binary &&
-          psdc0->type != gx_dc_type_ht_colored  ) ||
-         pdevc->phase.x != psdc0->phase.x         ||
-         pdevc->phase.y != psdc0->phase.y           ) {
-        flag_bits |= dc_ht_colored_has_phase;
-        /* the phases are known to be positive */
-        req_size += enc_u_sizexy(pdevc->phase);
-    }
-
     /* see if there is anything to do */
     if (flag_bits == 0) {
         *psize = 0;
@@ -327,9 +313,6 @@
     if ((flag_bits & dc_ht_colored_has_alpha) != 0)
         enc_u_putw(alpha, pdata);
 
-    if ((flag_bits & dc_ht_colored_has_phase) != 0)
-        enc_u_putxy(pdevc->phase, pdata);
-
     *psize = pdata - pdata0;
     return 0;
 }
@@ -381,12 +364,9 @@
     int                     flag_bits;
 
     /* if prior information is available, use it */
-    if (prior_devc != 0) {
-        if (prior_devc->type == gx_dc_type_ht_colored)
-            devc = *prior_devc;
-        else if (prior_devc->type == gx_dc_type_ht_binary)
-            devc.phase = prior_devc->phase;
-    } else
+    if (prior_devc != 0 && prior_devc->type == gx_dc_type_ht_colored)
+        devc = *prior_devc;
+    else
         memset(&devc, 0, sizeof(devc));   /* clear pointers */
     devc.type = gx_dc_type_ht_colored;
 
@@ -468,11 +448,12 @@
         size -= pdata - pdata_start;
     }
 
-    if ((flag_bits & dc_ht_colored_has_phase) != 0) {
-        if (size < 2)
-            return_error(gs_error_rangecheck);
-        enc_u_getxy(devc.phase, pdata);
-    }
+    /* set the phase as required (select value is arbitrary) */
+    color_set_phase_mod( &devc,
+                         pis->screen_phase[0].x,
+                         pis->screen_phase[0].y,
+                         pis->dev_ht->lcm_width,
+                         pis->dev_ht->lcm_height );
 
     /* everything looks OK */
     *pdevc = devc;

Index: gxht.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxht.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- gxht.c	26 Aug 2002 23:00:07 -0000	1.9
+++ gxht.c	28 Aug 2002 23:11:06 -0000	1.10
@@ -52,6 +52,7 @@
       gx_dc_type_data_ht_binary =
 {&st_dc_ht_binary,
  gx_dc_ht_binary_save_dc, gx_dc_ht_binary_get_dev_halftone,
+ gx_dc_ht_get_phase,
  gx_dc_ht_binary_load, gx_dc_ht_binary_fill_rectangle,
  gx_dc_default_fill_masked, gx_dc_ht_binary_equal,
  gx_dc_ht_binary_write, gx_dc_ht_binary_read,
@@ -245,32 +246,14 @@
  * (non-strip) tile. If so, return the byte offset of the appropriate row
  * from the beginning of the tile, and set *ppx to the x phase offset
  * within the tile; if not, return -1.
+ *
+ * This routine cannot be supported in the DeviceN code.
  */
 int
 gx_check_tile_size(const gs_imager_state * pis, int w, int y, int h,
 		   gs_color_select_t select, int *ppx)
 {
-#ifdef TO_DO_DEVICEN
-    int tsy;
-    const gx_strip_bitmap *ptile0;
-
-    if (pis->ht_cache == 0)
-	return -1;		/* no halftone cache */
-    ptile0 = &pis->ht_cache->ht_tiles[0].tiles;		/* a typical tile */
-    if (h > ptile0->rep_height || w > ptile0->rep_width ||
-	ptile0->shift != 0
-	)
-	return -1;
-    tsy = (y + imod(-pis->screen_phase[select].y, ptile0->rep_height)) %
-	ptile0->rep_height;
-    if (tsy + h > ptile0->size.y)
-	return -1;
-    /* Tile fits in Y, might fit in X. */
-    *ppx = imod(-pis->screen_phase[select].x, ptile0->rep_width);
-    return tsy * ptile0->raster;
-#else
     return -1;
-#endif
 }
 
 /* Render a given level into a halftone cache. */
@@ -441,7 +424,6 @@
 private const int   dc_ht_binary_has_color1 = 0x02;
 private const int   dc_ht_binary_has_level = 0x04;
 private const int   dc_ht_binary_has_index = 0x08;
-private const int   dc_ht_binary_has_phase = 0x10;
 
 
 /*
@@ -527,20 +509,6 @@
         req_size += 1;
     }
 
-    /*
-     * Moderate hack: the phase can be retrieved from either a binary or a
-     * colored halftone.
-     */
-    if ( psdc0 == 0                               ||
-         (psdc0->type != gx_dc_type_ht_binary &&
-          psdc0->type != gx_dc_type_ht_colored  ) ||
-         pdevc->phase.x != psdc0->phase.x          ||
-         pdevc->phase.y != psdc0->phase.y            ) {
-        flag_bits |= dc_ht_binary_has_phase;
-        /* the phases are known to be positive */
-        req_size += enc_u_sizexy(pdevc->phase);
-    }
-
     /* check if there is anything to be done */
     if (flag_bits == 0) {
         *psize = 0;
@@ -581,8 +549,6 @@
         enc_u_putw(pdevc->colors.binary.b_level, pdata);
     if ((flag_bits & dc_ht_binary_has_index) != 0)
         *pdata++ = pdevc->colors.binary.b_index;
-    if ((flag_bits & dc_ht_binary_has_phase) != 0)
-        enc_u_putxy(pdevc->phase, pdata);
 
     *psize = pdata - pdata0;
     return 0;
@@ -633,12 +599,9 @@
     int                     code, flag_bits;
 
     /* if prior information is available, use it */
-    if (prior_devc != 0) {
-        if (prior_devc->type == gx_dc_type_ht_binary)
-            devc = *prior_devc;
-        else if (prior_devc->type == gx_dc_type_ht_colored)
-            devc.phase = prior_devc->phase;
-    } else
+    if (prior_devc != 0 && prior_devc->type == gx_dc_type_ht_binary)
+        devc = *prior_devc;
+    else
         memset(&devc, 0, sizeof(devc));   /* clear pointers */
     devc.type = gx_dc_type_ht_binary;
 
@@ -687,12 +650,14 @@
             return_error(gs_error_rangecheck);
         devc.colors.binary.b_index = *pdata++;
     }
-    if ((flag_bits & dc_ht_binary_has_phase) != 0) {
-        /* we know the phase contains at least two bytes */
-        if (size < 2)
-            return_error(gs_error_rangecheck);
-        enc_u_getxy(devc.phase, pdata);
-    }
+
+    /* set the phase as required (select value is arbitrary) */
+    /* set the phase as required (select value is arbitrary) */
+    color_set_phase_mod( &devc,
+                         pis->screen_phase[0].x,
+                         pis->screen_phase[0].y,
+                         pis->dev_ht->lcm_width,
+                         pis->dev_ht->lcm_height );
 
     /* everything looks good */
     *pdevc = devc;

Index: gxclpath.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxclpath.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- gxclpath.c	26 Aug 2002 23:00:07 -0000	1.14
+++ gxclpath.c	28 Aug 2002 23:11:06 -0000	1.15
@@ -106,15 +106,26 @@
     gx_device_color_saved *    psdc = &pcls->sdc;
     byte *                     dp;
     byte *                     dp0;
+    gs_int_point               color_phase;
 
     /* see if the halftone must be inserted in the command list */
     if ( pdht != NULL                          &&
          pdht->id != cldev->device_halftone_id   ) {
         if ((code = cmd_put_halftone(cldev, pdht)) < 0)
             return code;
-        psdc = 0;
+        color_unset(psdc);
     }
 
+    /* see if phase informaiton must be inserted in the command list */
+    if ( pdcolor->type->get_phase(pdcolor, &color_phase) &&
+         (color_phase.x != pcls->tile_phase.x ||
+          color_phase.y != pcls->tile_phase.y   )        &&
+	 (code = cmd_set_tile_phase( cldev,
+                                     pcls,
+                                     color_phase.x,
+                                     color_phase.y )) < 0  )
+        return code;
+
     /*
      * Get the device color type index and the required size.
      *
@@ -1217,6 +1228,10 @@
 		     * ends.
 		     */
 		    set_first_point();
+		    if (side != 0) {
+			open = 0;
+			continue;
+		    }
 		}
 		open = 0;
 		px = first.x, py = first.y;

Index: gxclrast.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxclrast.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- gxclrast.c	26 Aug 2002 23:00:07 -0000	1.18
+++ gxclrast.c	28 Aug 2002 23:11:06 -0000	1.19
@@ -352,6 +352,7 @@
     fill_params.fill_zero_width = false;
     gs_cspace_init_DeviceGray(&cs);
     pcs = &cs;
+    color_unset(&dev_color);
     color_space.params.indexed.use_proc = 0;
     color_space.params.indexed.lookup.table.size = 0;
     data_bits = gs_alloc_bytes(mem, data_bits_size,

Index: gxdcolor.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxdcolor.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gxdcolor.c	26 Aug 2002 23:00:07 -0000	1.8
+++ gxdcolor.c	28 Aug 2002 23:11:06 -0000	1.9
@@ -37,7 +37,7 @@
 private dev_color_proc_get_nonzero_comps(gx_dc_no_get_nonzero_comps);
 const gx_device_color_type_t gx_dc_type_data_none = {
     &st_bytes,
-    gx_dc_no_save_dc, gx_dc_no_get_dev_halftone,
+    gx_dc_no_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
     gx_dc_no_load, gx_dc_no_fill_rectangle, gx_dc_no_fill_masked,
     gx_dc_no_equal, gx_dc_no_write, gx_dc_no_read, gx_dc_no_get_nonzero_comps
 };
@@ -53,7 +53,7 @@
 private dev_color_proc_read(gx_dc_null_read);
 const gx_device_color_type_t gx_dc_type_data_null = {
     &st_bytes,
-    gx_dc_no_save_dc, gx_dc_no_get_dev_halftone,
+    gx_dc_no_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
     gx_dc_null_load, gx_dc_null_fill_rectangle, gx_dc_null_fill_masked,
     gx_dc_null_equal, gx_dc_no_write, gx_dc_null_read, gx_dc_no_get_nonzero_comps
 };
@@ -70,7 +70,7 @@
 private dev_color_proc_read(gx_dc_pure_read);
 const gx_device_color_type_t gx_dc_type_data_pure = {
     &st_bytes,
-    gx_dc_pure_save_dc, gx_dc_no_get_dev_halftone,
+    gx_dc_pure_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
     gx_dc_pure_load, gx_dc_pure_fill_rectangle, gx_dc_pure_fill_masked,
     gx_dc_pure_equal, gx_dc_pure_write, gx_dc_pure_read,
     gx_dc_pure_get_nonzero_comps
@@ -208,6 +208,20 @@
         return dc_color_type_table[i];
     else
         return 0;
+}
+
+/* ------ Canonical get_phase methods ------ */
+bool
+gx_dc_no_get_phase(const gx_device_color * pdevc, gs_int_point * pphase)
+{
+    return false;
+}
+
+bool
+gx_dc_ht_get_phase(const gx_device_color * pdevc, gs_int_point * pphase)
+{
+    *pphase = pdevc->phase;
+    return true;
 }
 
 /* ------ Undefined color ------ */




More information about the gs-cvs mailing list