[Pixman] [PATCH] pixman_image_set_alpha_map(): Disallow alpha map cycles

Søren Sandmann sandmann at daimi.au.dk
Wed Aug 4 17:09:01 PDT 2010


From: Søren Sandmann Pedersen <ssp at redhat.com>

If someone tries to set an alpha map that itself has an alpha map,
simply return. Also, if someone tries to add an alpha map to an image
that is being _used_ as an alpha map, simply return.

This ensures that an alpha map can never have an alpha map.
---
 pixman/pixman-image.c   |   30 +++++++++++++++++++++++++++---
 pixman/pixman-private.h |    1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 269c3c1..0b8bb3c 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -101,6 +101,7 @@ _pixman_image_allocate (void)
 
 	pixman_region32_init (&common->clip_region);
 
+	common->alpha_count = 0;
 	common->have_clip_region = FALSE;
 	common->clip_sources = FALSE;
 	common->transform = NULL;
@@ -195,9 +196,6 @@ pixman_image_unref (pixman_image_t *image)
 	if (common->filter_params)
 	    free (common->filter_params);
 
-	if (common->alpha_map)
-	    pixman_image_unref ((pixman_image_t *)common->alpha_map);
-
 	if (image->type == LINEAR ||
 	    image->type == RADIAL ||
 	    image->type == CONICAL)
@@ -668,15 +666,41 @@ pixman_image_set_alpha_map (pixman_image_t *image,
 
     return_if_fail (!alpha_map || alpha_map->type == BITS);
 
+    if (alpha_map && common->alpha_count > 0)
+    {
+	/* If this image is being used as an alpha map itself,
+	 * then you can't give it an alpha map of its own.
+	 */
+	return;
+    }
+
+    if (alpha_map && alpha_map->common.alpha_map)
+    {
+	/* If the image has an alpha map of its own,
+	 * then it can't be used as an alpha map itself
+	 */
+	return;
+    }
+
     if (common->alpha_map != (bits_image_t *)alpha_map)
     {
 	if (common->alpha_map)
+	{
+	    common->alpha_map->common.alpha_count--;
+
 	    pixman_image_unref ((pixman_image_t *)common->alpha_map);
+	}
 
 	if (alpha_map)
+	{
 	    common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
+
+	    common->alpha_map->common.alpha_count++;
+	}
 	else
+	{
 	    common->alpha_map = NULL;
+	}
     }
 
     common->alpha_origin_x = x;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0629c42..c4e6bb8 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -80,6 +80,7 @@ struct image_common
     image_type_t                type;
     int32_t                     ref_count;
     pixman_region32_t           clip_region;
+    int32_t			alpha_count;	    /* How many times this image is being used as an alpha map */
     pixman_bool_t               have_clip_region;   /* FALSE if there is no clip */
     pixman_bool_t               client_clip;        /* Whether the source clip was
 						       set by a client */
-- 
1.6.0.6



More information about the Pixman mailing list