From: Søren Sandmann Pedersen <s...@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

_______________________________________________
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to