[gs-cvs] rev 8013 - trunk/gs/src

ray at ghostscript.com ray at ghostscript.com
Sun May 27 22:35:15 PDT 2007


Author: ray
Date: 2007-05-27 22:35:14 -0700 (Sun, 27 May 2007)
New Revision: 8013

Modified:
   trunk/gs/src/gdevbit.c
   trunk/gs/src/gdevwts.c
   trunk/gs/src/gxclread.c
   trunk/gs/src/gxdevcli.h
   trunk/gs/src/gxdevice.h
Log:
Primarily fix for wtsimdi problem with wts dithering phase shift at
band boundaries (add band_offset_x, band_offset_y), adding band_offset_x
and band_offset_y to the device structure and corresponding initializer
changes. Also clean up gdevwts.c MSVC warnings, and add a fast check to
gdevbit.c for /dev/null (mirroring a much older change for Windows
"nul:" device) OutputFile that aids in benchmarking. Fixes bug #689245
for customer #951.

DETAILS:

Running with the wtsimdi device at default banding now matches the
results with a single band (the wtsimdi device sets BandingAlways,
so this can only be verified if the -dBandHeight= and -dBufferSpace=
options are set large enough for a full page.

EXPECTED DIFFERENCES:

None. (wtsimdi device changes only).

NOTE: 'contrib' devices that do not use the std_device macros to
initialize the device_common part of the device structure will get
a compile error (as the bittagsrgb device did). We need to fix our
bittagsrgb device, and the eps-merge may need changes if there are
devices that do not use the macros (none known at this time).


Modified: trunk/gs/src/gdevbit.c
===================================================================
--- trunk/gs/src/gdevbit.c	2007-05-28 05:13:25 UTC (rev 8012)
+++ trunk/gs/src/gdevbit.c	2007-05-28 05:35:14 UTC (rev 8013)
@@ -263,6 +263,8 @@
         0 ,
         0 ,
         0 ,
+	0,
+	0,
         { 
             gx_default_install,
             gx_default_begin_page,
@@ -621,7 +623,7 @@
     int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
     byte *in = gs_alloc_bytes(pdev->memory, line_size, "bit_print_page(in)");
     byte *data;
-    int nul = !strcmp(pdev->fname, "nul");
+    int nul = !strcmp(pdev->fname, "nul") || !strcmp(pdev->fname, "/dev/null");
     int lnum = 0, bottom = pdev->height;
 
     if (in == 0)

Modified: trunk/gs/src/gdevwts.c
===================================================================
--- trunk/gs/src/gdevwts.c	2007-05-28 05:13:25 UTC (rev 8012)
+++ trunk/gs/src/gdevwts.c	2007-05-28 05:35:14 UTC (rev 8013)
@@ -118,8 +118,10 @@
 			3, 24, 255, 255, 256, 256, wtsimdi_print_page)
 };
 
+#if DUMMY_WTS_HALFTONE_LINE
 private void
 wts_halftone_line(void **wts, int y, int width, int n_planes,
+		  long band_offset_x, long band_offset_y,
 		  byte **dst, const byte *src)
 {
     int x;
@@ -141,9 +143,11 @@
 	}
     }
 }
+#endif
 
 private void
 wts_halftone_line_16(wts_cooked_halftone *wch, int y, int width, int n_planes,
+		     long band_offset_x, long band_offset_y,
 		     byte **dst, const byte *src)
 {
     int x;
@@ -160,7 +164,7 @@
 	    int n_samples;
 	    int cx, cy;
 
-	    wts_get_samples(w, x, y, &cx, &cy, &n_samples);
+	    wts_get_samples(w, band_offset_x + x, band_offset_y + y, &cx, &cy, &n_samples);
 	    samples = w->samples + cy * w->cell_width + cx;
 
 	    imax = min(width - x, n_samples);
@@ -206,6 +210,7 @@
 
 private void
 wts_halftone_line_8(wts_cooked_halftone *wch, int y, int width, int n_planes,
+		    long band_offset_x, long band_offset_y,
 		    byte * dst, const byte * src)
 {
     int x;
@@ -225,7 +230,7 @@
 	    int n_samples;
 	    int cx, cy;
 
-	    wts_get_samples(w, x, y, &cx, &cy, &n_samples);
+	    wts_get_samples(w, band_offset_x + x, band_offset_y + y, &cx, &cy, &n_samples);
 	    samples = wch[plane_ix].cell + cy * width_padded + cx;
 
 	    imax = min(width - x, n_samples);
@@ -326,7 +331,7 @@
     int cmyk_bytes = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
     /* Output bytes have to be padded to 16 bits. */
     int y;
-    char *cmyk_line = 0;
+    byte *cmyk_line = 0;
     byte *data;
     int code = 0;
     int pbm_bytes;
@@ -338,7 +343,7 @@
     /* Initialize the wts halftones. */
     wts_init_halftones(wdev, n_planes);
 
-    cmyk_line = gs_malloc(pdev->memory, cmyk_bytes, 1, "wtscmyk_print_page(in)");
+    cmyk_line = (byte *)gs_malloc(pdev->memory, cmyk_bytes, 1, "wtscmyk_print_page(in)");
     if (cmyk_line == 0) {
 	code = GS_NOTE_ERROR(pdev->memory, gs_error_VMerror);
 	goto out;
@@ -376,7 +381,8 @@
     /* For each raster line */
     for (y = 0; y < pdev->height; y++) {
 	gdev_prn_get_bits(pdev, y, cmyk_line, &data);
-	wts_halftone_line_8(wdev->wcooked, y, pdev->width, n_planes, dst, data);
+	wts_halftone_line_8(wdev->wcooked, y, pdev->width, n_planes, 
+			    wdev->band_offset_x, wdev->band_offset_y, dst, data);
 	for (i = 0; i < n_planes; i++)
 	    if (ostream[i])
 		fwrite(dst + i * pbm_bytes, 1, pbm_bytes, ostream[i]);
@@ -541,7 +547,7 @@
     gx_device_memory * const mdev = (gx_device_memory *)dev;
     gx_device_wtsimdi * idev = (gx_device_wtsimdi *)
 	    ((mdev->target) ? (gx_device_wts *)(mdev->target)
-			    : dev);
+			    : (gx_device_wts *)dev);
     wts_cooked_halftone * wch = idev->wcooked;
     int n_planes = 4;
     int code, comp_value;
@@ -609,7 +615,8 @@
 		    int cx, cy;
 		    int j;
 
-		    wts_get_samples(wch[plane_ix].wts, (x & -8) + (i << 3), y, &cx, &cy, &n_samples);
+		    wts_get_samples(wch[plane_ix].wts, ((dev->band_offset_x + x) & -8) + (i << 3),
+				    (dev->band_offset_y + y), &cx, &cy, &n_samples);
 		    samples = wch[plane_ix].cell + cy * width_padded + cx;
 
 		    imax = min((nfill + 1 - i) << 3, n_samples);
@@ -645,7 +652,7 @@
     gx_device_memory * const mdev = (gx_device_memory *)dev;
     gx_device_wtsimdi * idev = (gx_device_wtsimdi *)
 	    ((mdev->target) ? (gx_device_wts *)(mdev->target)
-			    : dev);
+			    : (gx_device_wts *)dev);
     wts_cooked_halftone * wch = idev->wcooked;
     int n_planes = 4;
     int code, comp_value;
@@ -732,7 +739,8 @@
 		    int cx, cy;
 		    int j;
 
-		    wts_get_samples(wch[plane_ix].wts, (x & -8) + (i << 3), y, &cx, &cy, &n_samples);
+		    wts_get_samples(wch[plane_ix].wts, ((dev->band_offset_x + x) & -8) + (i << 3),
+				    (dev->band_offset_y + y), &cx, &cy, &n_samples);
 		    samples = wch[plane_ix].cell + cy * width_padded + cx;
 
 		    imax = min((nfill + 1 - i) << 3, n_samples);
@@ -835,7 +843,7 @@
 	gx_device_memory * const mdev = (gx_device_memory *)dev;
         gx_device_wtsimdi * idev = (gx_device_wtsimdi *)
 	    ((mdev->target) ? (gx_device_wts *)(mdev->target)
-			    : dev);
+			    : (gx_device_wts *)dev);
 	int width = dev->width;
 	int n_planes = 4;
 	int r_last = -1, g_last = -1, b_last = -1, r, g, b;
@@ -874,8 +882,8 @@
 	    *cmyk_data++ = y;
 	    *cmyk_data++ = k;
 	}
-	wts_halftone_line_8(idev->wcooked, original_y, width,
-					    n_planes, buffer, cmyk_buffer);
+	wts_halftone_line_8(idev->wcooked, original_y, width, n_planes,
+			    idev->band_offset_x, idev->band_offset_y,  buffer, cmyk_buffer);
 	params->data[0] = buffer;
 	gs_free(dev->memory, cmyk_buffer, halftoned_bytes * n_planes, 1,
 		       	"wtsimdi_print_page(halftoned_data)");

Modified: trunk/gs/src/gxclread.c
===================================================================
--- trunk/gs/src/gxclread.c	2007-05-28 05:13:25 UTC (rev 8012)
+++ trunk/gs/src/gxclread.c	2007-05-28 05:35:14 UTC (rev 8013)
@@ -469,6 +469,24 @@
     for (i = 0; i < num_pages && code >= 0; ++i) {
 	const gx_placed_page *ppage = &ppages[i];
 
+	/*
+	 * Set the band_offset_? values in case the buffer device
+	 * needs this. Example, wtsimdi device needs to adjust the 
+	 * phase of the dithering based on the page position, NOT
+	 * the position within the band buffer to avoid band stitch
+	 * lines in the dither pattern.
+	 *
+	 * The band_offset_x is not important for placed pages that
+	 * are nested on a 'master' page (imposition) since each
+	 * page expects to be dithered independently, but setting
+	 * this allows pages to be contiguous without a dithering
+	 * shift.
+	 *
+	 * The following sets the band_offset_? relative to the
+	 * master page.
+	 */
+	bdev->band_offset_x = ppage->offset.x;
+	bdev->band_offset_y = ppage->offset.y + (band_first * band_height);
 	code = clist_playback_file_bands(playback_action_render,
 					 crdev, &ppage->page->info,
 					 bdev, band_first, band_last,

Modified: trunk/gs/src/gxdevcli.h
===================================================================
--- trunk/gs/src/gxdevcli.h	2007-05-28 05:13:25 UTC (rev 8012)
+++ trunk/gs/src/gxdevcli.h	2007-05-28 05:35:14 UTC (rev 8013)
@@ -704,6 +704,8 @@
 	bool IgnoreNumCopies;		/* if true, force num_copies = 1 */\
 	bool UseCIEColor;		/* for PS LL3 */\
 	bool LockSafetyParams;		/* If true, prevent unsafe changes */\
+	long band_offset_x;		/* offsets of clist band base to (mem device) buffer */\
+	long band_offset_y;		/* for rendering that is phase sensitive (wtsimdi) */\
 	gx_page_device_procs page_procs;	/* must be last */\
 		/* end of std_device_body */\
 	gx_device_procs procs	/* object procedures */

Modified: trunk/gs/src/gxdevice.h
===================================================================
--- trunk/gs/src/gxdevice.h	2007-05-28 05:13:25 UTC (rev 8012)
+++ trunk/gs/src/gxdevice.h	2007-05-28 05:35:14 UTC (rev 8013)
@@ -102,6 +102,7 @@
 #define std_device_part3_()\
 	0/*PageCount*/, 0/*ShowpageCount*/, 1/*NumCopies*/, 0/*NumCopies_set*/,\
 	0/*IgnoreNumCopies*/, 0/*UseCIEColor*/, 0/*LockSafetyParams*/,\
+	0/*band_offset_x*/, 0/*band_offset_y*/,\
 	{ gx_default_install, gx_default_begin_page, gx_default_end_page }
 /*
  * We need a number of different variants of the std_device_ macro simply



More information about the gs-cvs mailing list