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

leonardo at ghostscript.com leonardo at ghostscript.com
Mon Jan 28 00:50:10 PST 2008


Author: leonardo
Date: 2008-01-28 00:50:10 -0800 (Mon, 28 Jan 2008)
New Revision: 8507

Modified:
   trunk/gs/src/gdevp14.c
Log:
Fix (clist & transparency) : Improve the compositor queue logic (continued).

DETAILS :

The last commit is incomplete due to human error.
Please don't use the last revision.

Bug 689492 "Ghostscript uses a large amount of memory", part 2.

This patch fixes the missed shadow of a text, which is mentioned 
in the Comment #8 of the bug report.

1. Added macros for configuring visual trace for easier debugging.
2. The idle transparency bufer allocation condition was wrong. 
   The patched code allocated ;esser buffers.
3. Found more cases when a mask needs to be released.
4. The old code immediately executes idle masks.
   It caused a wrong order for compositor execution
   with images that have a soft mask.
   With the test case the image's mask was executed before 
   the group that containing the image.
   It caused a premature releasing of a mask,
   which preceeeds the group and must noy be released.

   The new code delays the execution of idle masks
   after all containing groups are executed,
   so that the queue is now longer and stores all masks.
   We beleive that's not harmful, because
   transparency queue elements are pretty small and
   work for hos based applications only.

   The new function mark_as_idle works for the new logic.
   Few aother functions are enhanced with a smarter
   processing of the idle flag.
5. Improved comments for the compositor queue logic.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gdevp14.c
===================================================================
--- trunk/gs/src/gdevp14.c	2008-01-28 08:45:21 UTC (rev 8506)
+++ trunk/gs/src/gdevp14.c	2008-01-28 08:50:10 UTC (rev 8507)
@@ -44,6 +44,12 @@
 #include "gxdcconv.h"
 #include "vdtrace.h"
 
+/* Visual  trace options : set one to 1. */
+#define VD_PAINT_MASK 0
+#define VD_PAINT_COLORS 0
+#define VD_PAINT_ALPHA 1
+
+
 /*
  * We chose the blending color space based upon the process color model of the
  * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
@@ -540,7 +546,7 @@
     result->maskbuf = NULL;
     result->idle = idle;
 
-    if (height <= 0 && !idle) {
+    if (height <= 0 || idle) {
 	/* Empty clipping - will skip all drawings. */
 	result->planestride = 0;
 	result->data = 0;
@@ -733,10 +739,20 @@
     int x1 = min(tos->rect.q.x, nos->rect.q.x);
     pdf14_buf *maskbuf = tos->maskbuf;
 
+    if (ctx->maskbuf) {
+	/* Happens with the test case of bug 689492 with no banding
+	   while rendering the group of an image with a mask.
+	   Not sure why gs/lib processes a mask inside the image droup,
+	   anyway we need to release it safely. */
+	pdf14_buf_free(ctx->maskbuf, ctx->memory);
+	ctx->maskbuf = NULL;
+    }
     ctx->maskbuf = maskbuf;  /* Restore the mask saved by pdf14_push_transparency_group. */
     tos->maskbuf = NULL;     /* Clean the pointer sinse the mask ownership is now passed to ctx. */
     if (tos->idle)
 	goto exit;
+    if (maskbuf != NULL && maskbuf->data == NULL)
+	goto exit;
     if (x0 < x1 && y0 < y1) {
 	int n_chan = ctx->n_chan;
 	int num_comp = n_chan - 1;
@@ -833,7 +849,9 @@
 		    mask = mask_tr_fn[mask];
 		    tmp = pix_alpha * mask + 0x80;
 		    pix_alpha = (tmp + (tmp >> 8)) >> 8;
-		    vd_pixel(int2fixed(x), int2fixed(y), mask);
+#		    if VD_PAINT_MASK
+			vd_pixel(int2fixed(x), int2fixed(y), mask);
+#		    endif
 		}
 
 		if (nos_knockout) {
@@ -874,11 +892,16 @@
 			nos_ptr[x + i * nos_planestride] = 255 - nos_pixel[i];
 		    nos_ptr[x + num_comp * nos_planestride] = nos_pixel[num_comp];
 		}
-		if (maskbuf == NULL) {
+#		if VD_PAINT_COLORS
 		    vd_pixel(int2fixed(x), int2fixed(y), n_chan == 1 ? 
 			(nos_pixel[0] << 16) + (nos_pixel[0] << 8) + nos_pixel[0] :
-			(nos_pixel[0] << 16) + (nos_pixel[1] << 8) + nos_pixel[2]);
-		}
+			(nos_pixel[0] << 16) + (nos_pixel[1] << 8) + nos_pixel[2]);*/
+#		endif
+#		if VD_PAINT_ALPHA
+		    vd_pixel(int2fixed(x), int2fixed(y),
+			(nos_pixel[n_chan - 1] << 16) + (nos_pixel[n_chan - 1] << 8) + 
+			 nos_pixel[n_chan - 1]);
+#		endif
 		if (nos_alpha_g_ptr != NULL)
 		    ++nos_alpha_g_ptr;
 	    }
@@ -925,14 +948,12 @@
     if_debug2('v', "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n", idle, replacing);
     if (replacing && ctx->maskbuf != NULL) {
 	if (ctx->maskbuf->maskbuf != NULL) {
-	    /* fixme: We pass here when a mask of an image
+	    /* Pass here when a mask of an image
 	       is being replaced with the containing group's mask.
 	       It looks as the image's mask covers some band,
 	       but the image itself does not.
-	       This situation looks strange, but it does happen
-	       with the test case of the bug 689492.
-	       Will need further investigation.
-	       For now just release the containing group's mask.
+	       We believe it must not happen,
+	       but provide a cleanup for safety.
 	    */
 	    pdf14_buf_free(ctx->maskbuf->maskbuf, ctx->memory);
 	}
@@ -2965,6 +2986,7 @@
 	    code += 0; /* A good place for a breakpoint. */
 	    break;
 	case PDF14_END_TRANS_GROUP:
+	    code += 0; /* A good place for a breakpoint. */
 	    break;			/* No data */
 	case PDF14_BEGIN_TRANS_GROUP:
 	    /*
@@ -3018,6 +3040,7 @@
 	    }
 	    break;
 	case PDF14_END_TRANS_MASK:
+	    code += 0; /* A good place for a breakpoint. */
 	    break;			/* No data */
 	case PDF14_SET_BLEND_PARAMS:
 	    params.changed = *data++;
@@ -3098,7 +3121,7 @@
  * Find an opening compositor op.
  */
 static int
-find_opening_op(int opening_op, gs_composite_t **ppcte)
+find_opening_op(int opening_op, gs_composite_t **ppcte, int return_code)
 {
     /* Assuming a right *BEGIN* - *END* operation balance. */
     gs_composite_t *pcte = *ppcte;
@@ -3110,9 +3133,20 @@
 
 	    *ppcte = pcte;
 	    if (op == opening_op)
-		return 1;
-	    if (op != PDF14_INIT_TRANS_MASK && op != PDF14_SET_BLEND_PARAMS)
-		return 0;
+		return return_code;
+	    if (op != PDF14_INIT_TRANS_MASK && op != PDF14_SET_BLEND_PARAMS) {
+		if (opening_op == PDF14_BEGIN_TRANS_MASK)
+		    return 0;
+		if (opening_op == PDF14_BEGIN_TRANS_GROUP) {
+		    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
+			return 0;
+		}
+		if (opening_op == PDF14_PUSH_DEVICE) {
+		    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
+			op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_END_TRANS_GROUP)
+			return 0;
+		}
+	    }
 	} else
 	    return 0;
 	pcte = pcte->prev;
@@ -3164,7 +3198,7 @@
 	    if (*ppcte == NULL)
 		return 0;
 	    else {	
-		int code = find_opening_op(PDF14_PUSH_DEVICE, ppcte);
+		int code = find_opening_op(PDF14_PUSH_DEVICE, ppcte, 1);
 
 		if (code == 1)
 		    return 5;
@@ -3175,7 +3209,7 @@
 	case PDF14_END_TRANS_GROUP:
 	    if (*ppcte == NULL)
 		return 2;
-	    return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte);
+	    return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, 6);
 	case PDF14_INIT_TRANS_MASK: 
 	    if (*ppcte == NULL)
 		return 0;
@@ -3185,9 +3219,12 @@
 	case PDF14_END_TRANS_MASK: 
 	    if (*ppcte == NULL)
 		return 2;
-	    return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte);
+	    return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, 6);
 	case PDF14_SET_BLEND_PARAMS: 
-	    return 0;
+	    if (*ppcte == NULL)
+		return 0;
+	    /* hack : ignore csel - here it is always zero : */
+	    return find_same_op(this, PDF14_SET_BLEND_PARAMS, ppcte);
     }
 }
 
@@ -3200,7 +3237,10 @@
     gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)this;
     int op0 = pct0->params.pdf14_op;
 
-    if (op0 == PDF14_PUSH_DEVICE) {
+    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP) {
+	/* Halftone commands are always passed to the target printer device, 
+	   because transparency buffers are always contone.
+	   So we're safe to execute them before queued transparency compositors. */
 	if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone || 
 				       cmd1 == cmd_opv_ext_put_ht_seg))
 	    return true;



More information about the gs-cvs mailing list