[gs-cvs] rev 8430 - trunk/gs/src
tor at ghostscript.com
tor at ghostscript.com
Mon Dec 10 08:13:27 PST 2007
Author: tor
Date: 2007-12-10 08:13:26 -0800 (Mon, 10 Dec 2007)
New Revision: 8430
Modified:
trunk/gs/src/gdevp14.c
trunk/gs/src/gdevp14.h
Log:
Pick up the transparency mask buffer when a new transparency group is pushed rather than when it is popped. Solves memory leaks and incorrect rendering when transparency groups are nested.
Modified: trunk/gs/src/gdevp14.c
===================================================================
--- trunk/gs/src/gdevp14.c 2007-12-10 09:45:03 UTC (rev 8429)
+++ trunk/gs/src/gdevp14.c 2007-12-10 16:13:26 UTC (rev 8430)
@@ -553,7 +553,8 @@
result->n_planes = n_planes;
result->rowstride = rowstride;
result->transfer_fn = NULL;
-
+ result->maskbuf = NULL;
+
if (height <= 0) {
/* Empty clipping - will skip all drawings. */
result->planestride = 0;
@@ -583,6 +584,10 @@
static void
pdf14_buf_free(pdf14_buf *buf, gs_memory_t *memory)
{
+ if (buf->maskbuf) {
+ errprintf("forgot to free transparency maskbuf\n");
+ pdf14_buf_free(buf->maskbuf, memory);
+ }
gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
gs_free_object(memory, buf->data, "pdf14_buf_free");
gs_free_object(memory, buf, "pdf14_buf_free");
@@ -684,6 +689,14 @@
buf->saved = tos;
ctx->stack = buf;
+ /* If a transparency mask is used for this group, this function call will have
+ been preceded by pdf14_push_transparency_mask ... pdf14_pop_transparency_mask
+ calls to create the mask buffer. This mask is stored in ctx->maskbuf.
+ We pick it up here when pushing the group (instead of when popping)
+ so that nested transparency groups and masks will work. */
+ buf->maskbuf = ctx->maskbuf;
+ ctx->maskbuf = NULL;
+
if (buf->data == NULL)
return 0;
@@ -732,7 +745,7 @@
{
pdf14_buf *tos = ctx->stack;
pdf14_buf *nos = tos->saved;
- pdf14_buf *maskbuf = ctx->maskbuf;
+ pdf14_buf *maskbuf = tos->maskbuf;
int y0 = max(tos->rect.p.y, nos->rect.p.y);
int y1 = min(tos->rect.q.y, nos->rect.q.y);
int x0 = max(tos->rect.p.x, nos->rect.p.x);
@@ -887,14 +900,20 @@
ctx->stack = nos;
if_debug0('v', "[v]pop buf\n");
- pdf14_buf_free(tos, ctx->memory);
if (maskbuf != NULL) {
pdf14_buf_free(maskbuf, ctx->memory);
- ctx->maskbuf = NULL;
+ tos->maskbuf = NULL;
}
+ pdf14_buf_free(tos, ctx->memory);
return 0;
}
+/*
+ * Create a transparency mask that will be used as the mask for
+ * the next transparency group that is created afterwards.
+ * The sequence of calls is:
+ * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
+ */
static int
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, byte bg_alpha,
byte *transfer_fn)
@@ -928,7 +947,14 @@
pdf14_buf *tos = ctx->stack;
ctx->stack = tos->saved;
+
+ /* After creating the mask buffer we're storing it in ctx->maskbuf so
+ that the next pdf14_push_transparency_group call can pick
+ it up. */
+ if (ctx->maskbuf != NULL)
+ errprintf("programmer error. we lost a transparency mask.\n");
ctx->maskbuf = tos;
+
return 0;
}
Modified: trunk/gs/src/gdevp14.h
===================================================================
--- trunk/gs/src/gdevp14.h 2007-12-10 09:45:03 UTC (rev 8429)
+++ trunk/gs/src/gdevp14.h 2007-12-10 16:13:26 UTC (rev 8430)
@@ -56,6 +56,9 @@
byte *transfer_fn;
gs_int_rect bbox;
+
+ /* the associated transparency mask */
+ pdf14_buf *maskbuf;
};
struct pdf14_ctx_s {
More information about the gs-cvs
mailing list