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

ray at ghostscript.com ray at ghostscript.com
Fri Jun 29 13:21:42 PDT 2007


Author: ray
Date: 2007-06-29 13:21:42 -0700 (Fri, 29 Jun 2007)
New Revision: 8088

Modified:
   trunk/gs/src/gdevwts.c
Log:
Fix optimization for 0 and 0xff (non-dithered) colors in the wtsimdi_copy_mono
routine. Also add a (temporary) change to force color==0 to cmyk=0x000000ff
(only 100% black). This would be done differently if the input color were
tagged RGB where presumably text objects would map. This is a reasonable
temporary approach since copy_mono is used for bitmapped text.

Also remove the "SKIP_OUTPUT" compile time #define and add "output_is_nul"
detection of the OutputFile name being nul: or /dev/null to make it easier
to go back and forth between timing runs (to /dev/null) and runs where we
want to look at the output.

DETAILS:

Both the copy_mono optimizations and the mapping of color 0 can be disabled
by removing (or commenting) the #defines above wtsimdi_copy_mono. These are
on by default.



Modified: trunk/gs/src/gdevwts.c
===================================================================
--- trunk/gs/src/gdevwts.c	2007-06-29 15:38:25 UTC (rev 8087)
+++ trunk/gs/src/gdevwts.c	2007-06-29 20:21:42 UTC (rev 8088)
@@ -759,6 +759,17 @@
      * Check if this is a new color.  To minimize color conversion
      * time, we keep a couple of values cached in the wtsimdi device.
      */
+#define COPY_MONO_BLACK_IS_K 
+#define COPY_MONO_OPTIMIZATION
+
+#ifdef COPY_MONO_BLACK_IS_K 
+    if (one == 0) {
+	/* FIXME: This should rely on tag bits, but copy_mono black is (probably) only used for text */
+	idev->current_color.cmyk[0] =idev->current_color.cmyk[1] =  idev->current_color.cmyk[2] = 0;
+	idev->current_color.cmyk[3] = 0xff;	/* 100% K channel, 0% C, M, Y */
+	idev->current_color.color_index = 0;
+    } else
+#endif
     if ((code = wtsimdi_resolve_one(idev, one)) < 0)
 	return code;
 
@@ -768,40 +779,28 @@
         base = scan_line_base(mdev, y);
         for (plane_ix = 0; plane_ix < 4; plane_ix++) {
 	    int nfill = (end_x >> 3) - first_byte;
+	    int i;
+	    byte smask, save_left, save_right;
 
 	    width_padded = wch[plane_ix].width_padded;
 	    dst = base + first_byte + plane_ix * halftoned_bytes;
+	    save_left = dst[0];
+	    save_right = dst[nfill];
 	    comp_value = idev->current_color.cmyk[plane_ix];
-	    if (0 && comp_value == 0) {
-		/* TODO: these cases should be optimized, avoiding a screen */
-		if (nfill == 0) {
-		    dst[0] &= (0xff << (8 - (x & 7))) |
-			((1 << (7 - (end_x & 7))) - 1);
-		} else {
-		    int i;
-
-		    dst[0] &= (0xff << (8 - (x & 7)));
-		    for (i = 1; i < nfill; i++)
-			dst[i] = 0;
-		    dst[i] &= ((1 << (7 - (end_x & 7))) - 1);
+#ifdef  COPY_MONO_OPTIMIZATION
+	    if (comp_value == 0) {
+		for (i = 0; i < nfill + 1; i++) {
+		    if ((smask = (src[i] << 8 | src[i + 1]) >> sshift) != 0)
+			dst[i] = dst[i] & ~smask;
 		}
-	    } else if (0 && comp_value == 0xff) {
-		if (nfill == 0) {
-		    dst[0] |= ~((0xff << (8 - (x & 7))) |
-			((1 << (7 - (end_x & 7))) - 1));
-		} else {
-		    int i;
-
-		    dst[0] |= ~(0xff << (8 - (x & 7)));
-		    for (i = 1; i < nfill; i++)
-			dst[i] = 0xff;
-		    dst[i] |= ~((1 << (7 - (end_x & 7))) - 1);
+	    } else if (comp_value == 0xff) {
+		for (i = 0; i < nfill + 1; i++) {
+		    if ((smask = (src[i] << 8 | src[i + 1]) >> sshift) != 0)
+			dst[i] = smask | (dst[i] & ~smask) ;
 		}
-	    } else {
-		byte save_left = dst[0];
-		byte save_right = dst[nfill];
-		int i;
-
+	    } else
+#endif
+	    {
 		for (i = 0; i < nfill + 1;) {
 		    int n_samples;
 		    int cx, cy;
@@ -813,7 +812,7 @@
 
 		    imax = min((nfill + 1 - i) << 3, n_samples);
 		    for (j = 0; j < imax; j += 8) {
-			byte smask = (src[i] << 8 | src[i + 1]) >> sshift;
+			smask = (src[i] << 8 | src[i + 1]) >> sshift;
 			if (smask) {
 			    byte b;
 			    b = (((unsigned int)(((int)(samples[j + 0])) - comp_value) >> 24)) & 0x80;
@@ -828,12 +827,13 @@
 			}
 			i++;
 		    }
-		    dst[0] = (save_left & (0xff << (8 - (x & 7)))) |
+		}
+	    }
+	    /* Restore edge areas on left and right that may have been overwritten */
+	    dst[0] = (save_left & (0xff << (8 - (x & 7)))) |
 			(dst[0] & ~(0xff << (8 - (x & 7))));
-		    dst[nfill] = (save_right & ((1 << (7 - (end_x & 7))) - 1)) |
+	    dst[nfill] = (save_right & ((1 << (7 - (end_x & 7))) - 1)) |
 			(dst[nfill] & ~((1 << (7 - (end_x & 7))) - 1));
-		}
-	    }
         }
 	src += sraster;
     }
@@ -999,55 +999,57 @@
  * The input data is 1 bit per component CMYK.  The data is separated
  * into planes.
  */
+private void
 write_pkmraw_row(int width, byte * data, FILE * pstream)
 {
-#define noSKIP_OUTPUT
-#ifndef SKIP_OUTPUT
-    int x, bit;
-    int halftoned_bytes = (width + 7) >> 3;
-    byte * cdata = data;
-    byte * mdata = data + halftoned_bytes;
-    byte * ydata = mdata + halftoned_bytes;
-    byte * kdata = ydata + halftoned_bytes;
-    byte c = *cdata++;
-    byte m = *mdata++;
-    byte y = *ydata++;
-    byte k = *kdata++;
+    if (pstream == NULL)
+	return;
+    {
+	int x, bit;
+	int halftoned_bytes = (width + 7) >> 3;
+	byte * cdata = data;
+	byte * mdata = data + halftoned_bytes;
+	byte * ydata = mdata + halftoned_bytes;
+	byte * kdata = ydata + halftoned_bytes;
+	byte c = *cdata++;
+	byte m = *mdata++;
+	byte y = *ydata++;
+	byte k = *kdata++;
 
-    /*
-     * Contrary to what the documentation implies, gcc compiles putc
-     * as a procedure call.  This is ridiculous, but since we can't
-     * change it, we buffer groups of pixels ourselves and use fwrite.
-     */
-    for (bit = 7, x = 0; x < width;) {
-	byte raw[80 * 3];	/* 80 is arbitrary, must be a multiple of 8 */
-	int end = min(x + sizeof(raw) / 3, width);
-	byte *outp = raw;
+	/*
+	 * Contrary to what the documentation implies, gcc compiles putc
+	 * as a procedure call.  This is ridiculous, but since we can't
+	 * change it, we buffer groups of pixels ourselves and use fwrite.
+	 */
+	for (bit = 7, x = 0; x < width;) {
+	    byte raw[80 * 3];	/* 80 is arbitrary, must be a multiple of 8 */
+	    int end = min(x + sizeof(raw) / 3, width);
+	    byte *outp = raw;
 
-	for (; x < end; x++) {
+	    for (; x < end; x++) {
 
-	    if ((k >> bit) & 1) {
-		*outp++ = 0;	/* Set output color = black */
-		*outp++ = 0;
-		*outp++ = 0;
-	    } else {
-		*outp++ = 255 & (255 + ((c >> bit) & 1));
-		*outp++ = 255 & (255 + ((m >> bit) & 1));
-		*outp++ = 255 & (255 + ((y >> bit) & 1));
+		if ((k >> bit) & 1) {
+		    *outp++ = 0;	/* Set output color = black */
+		    *outp++ = 0;
+		    *outp++ = 0;
+		} else {
+		    *outp++ = 255 & (255 + ((c >> bit) & 1));
+		    *outp++ = 255 & (255 + ((m >> bit) & 1));
+		    *outp++ = 255 & (255 + ((y >> bit) & 1));
+		}
+		if (bit == 0) {
+		    c = *cdata++;
+		    m = *mdata++;
+		    y = *ydata++;
+		    k = *kdata++;
+		    bit = 7;
+		} else
+		    bit--;
 	    }
-	    if (bit == 0) {
-	        c = *cdata++;
-	        m = *mdata++;
-	        y = *ydata++;
-	        k = *kdata++;
-	        bit = 7;
-	    } else
-	        bit--;
+	    fwrite(raw, 1, outp - raw, pstream);
 	}
-	fwrite(raw, 1, outp - raw, pstream);
+	return;
     }
-#endif
-    return 0;
 }
 
 /*
@@ -1067,6 +1069,8 @@
     int width = pdev->width;
     int height = pdev->height;
     dev_proc_get_bits((*save_get_bits)) = dev_proc(pdev, get_bits);
+    int output_is_nul = !strncmp(pdev->fname, "nul:", min(strlen(pdev->fname), 4)) ||
+	!strncmp(pdev->fname, "/dev/null", min(strlen(pdev->fname), 9));
 
     /*
      * The printer device setup changed the get_bits routine to
@@ -1101,11 +1105,13 @@
 	idev->color_cache[i].color_index = gx_no_color_index;
 
     /* Initialize output file header. */
-    fprintf(prn_stream, "P6\n%d %d\n", width, height);
-    fprintf(prn_stream, "# Image generated by %s %d.%02d (device=wtsimdi)\n",
+    if (!output_is_nul) {
+	fprintf(prn_stream, "P6\n%d %d\n", width, height);
+	fprintf(prn_stream, "# Image generated by %s %d.%02d (device=wtsimdi)\n",
 	   	gs_program_name(), gs_revision_number() / 100,
 	   			gs_revision_number() % 100);
-    fprintf(prn_stream, "%d\n", 255);
+	fprintf(prn_stream, "%d\n", 255);
+    }
 
     /*
      * Get raster data and then write data to output file.
@@ -1116,9 +1122,8 @@
 	 * the output data.  Print this data to the output file.
 	 */
 	gdev_prn_get_bits(pdev, y, halftoned_buffer, &halftoned_data);
-#if 1
-	write_pkmraw_row(width, halftoned_data, prn_stream);
-#endif
+	if (!output_is_nul)
+	    write_pkmraw_row(width, halftoned_data, prn_stream);
     }
 cleanup:
 #ifdef DEBUG



More information about the gs-cvs mailing list