pixman: Branch 'master' - 16 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Sat Aug 8 13:56:41 PDT 2009


 pixman/pixman-access.c           | 1743 ++++++++++++---------------------------
 pixman/pixman-bits-image.c       |  600 ++++---------
 pixman/pixman-conical-gradient.c |    2 
 pixman/pixman-fast-path.c        |   62 +
 pixman/pixman-image.c            |   13 
 pixman/pixman-linear-gradient.c  |    2 
 pixman/pixman-private.h          |   24 
 pixman/pixman-radial-gradient.c  |    2 
 pixman/pixman-region.c           |    2 
 pixman/pixman-solid-fill.c       |    2 
 pixman/pixman-sse2.c             |  140 +++
 pixman/pixman-trap.c             |    4 
 pixman/pixman.c                  |    7 
 13 files changed, 1027 insertions(+), 1576 deletions(-)

New commits:
commit 7b1df41b6110424b8dca9fa655dbc8dd95a76882
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri Jul 31 17:27:38 2009 -0400

    Add a dirty bit to the image struct, and validate before using the image.
    
    This cuts down the number of property_changed calls significantly.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 0be2af3..9e1ee13 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -765,8 +765,6 @@ pixman_image_create_bits (pixman_format_code_t format,
 
     image->common.property_changed = bits_image_property_changed;
 
-    bits_image_property_changed (image);
-
     _pixman_image_reset_clip_region (image);
 
     return image;
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 6a4e31e..d720db3 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -175,8 +175,6 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t *        center,
 
     image->common.property_changed = conical_gradient_property_changed;
 
-    conical_gradient_property_changed (image);
-
     return image;
 }
 
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 163d247..5831953 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -120,6 +120,7 @@ _pixman_image_allocate (void)
 	common->destroy_func = NULL;
 	common->destroy_data = NULL;
 	common->need_workaround = FALSE;
+	common->dirty = TRUE;
     }
 
     return image;
@@ -168,7 +169,7 @@ _pixman_image_get_scanline_64 (pixman_image_t *image,
 static void
 image_property_changed (pixman_image_t *image)
 {
-    image->common.property_changed (image);
+    image->common.dirty = TRUE;
 }
 
 /* Ref Counting */
@@ -238,6 +239,16 @@ _pixman_image_reset_clip_region (pixman_image_t *image)
     image->common.have_clip_region = FALSE;
 }
 
+void
+_pixman_image_validate (pixman_image_t *image)
+{
+    if (image->common.dirty)
+    {
+	image->common.property_changed (image);
+	image->common.dirty = FALSE;
+    }
+}
+
 PIXMAN_EXPORT pixman_bool_t
 pixman_image_set_clip_region32 (pixman_image_t *   image,
                                 pixman_region32_t *region)
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index aafdd3b..d9409fe 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -289,8 +289,6 @@ pixman_image_create_linear_gradient (pixman_point_fixed_t *        p1,
     image->common.classify = linear_gradient_classify;
     image->common.property_changed = linear_gradient_property_changed;
 
-    linear_gradient_property_changed (image);
-
     return image;
 }
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index a4e6cbd..ff7a65f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -82,6 +82,7 @@ struct image_common
     pixman_bool_t               clip_sources;       /* Whether the clip applies when
 						     * the image is used as a source
 						     */
+    pixman_bool_t		dirty;
     pixman_bool_t               need_workaround;
     pixman_transform_t *        transform;
     pixman_repeat_t             repeat;
@@ -277,6 +278,9 @@ _pixman_init_gradient (gradient_t *                  gradient,
 void
 _pixman_image_reset_clip_region (pixman_image_t *image);
 
+void
+_pixman_image_validate (pixman_image_t *image);
+
 pixman_bool_t
 _pixman_image_is_opaque (pixman_image_t *image);
 
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 67a618d..022157b 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -363,8 +363,6 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t *        inner,
 
     image->common.property_changed = radial_gradient_property_changed;
 
-    radial_gradient_property_changed (image);
-
     return image;
 }
 
diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index db23be3..f88955f 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -66,7 +66,7 @@
 #define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2)
 #define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2)
 
-#define PIXMAN_REGION_LOG_FAILURES
+#define noPIXMAN_REGION_LOG_FAILURES
 
 #if defined PIXMAN_REGION_LOG_FAILURES || defined PIXMAN_REGION_DEBUG
 
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 67aec92..38675dc 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -86,8 +86,6 @@ pixman_image_create_solid_fill (pixman_color_t *color)
     img->common.classify = solid_fill_classify;
     img->common.property_changed = solid_fill_property_changed;
 
-    solid_fill_property_changed (img);
-
     return img;
 }
 
diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index 4d7a90a..962cbb3 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -243,6 +243,8 @@ pixman_add_traps (pixman_image_t * image,
     pixman_edge_t l, r;
     pixman_fixed_t t, b;
 
+    _pixman_image_validate (image);
+    
     width = image->bits.width;
     height = image->bits.height;
     bpp = PIXMAN_FORMAT_BPP (image->bits.format);
@@ -357,6 +359,8 @@ pixman_rasterize_trapezoid (pixman_image_t *          image,
 
     return_if_fail (image->type == BITS);
 
+    _pixman_image_validate (image);
+    
     if (!pixman_trapezoid_valid (trap))
 	return;
 
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 12b4c5a..0edd967 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -173,6 +173,11 @@ pixman_image_composite (pixman_op_t      op,
     uint32_t *dest_bits;
     int dest_dx, dest_dy;
 
+    _pixman_image_validate (src);
+    if (mask)
+	_pixman_image_validate (mask);
+    _pixman_image_validate (dest);
+    
     /*
      * Check if we can replace our operator by a simpler one
      * if the src or dest are opaque. The output operator should be
@@ -322,6 +327,8 @@ pixman_image_fill_rectangles (pixman_op_t                 op,
     pixman_color_t c;
     int i;
 
+    _pixman_image_validate (dest);
+    
     if (color->alpha == 0xffff)
     {
 	if (op == PIXMAN_OP_OVER)
commit 942c4ac28209381668208a39ccc9aec4f11bf63f
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri Jul 31 10:39:41 2009 -0400

    Add sse2 version of add_n_8888_8888()

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 2fa956e..e2a39a8 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -3098,6 +3098,145 @@ sse2_composite_over_n_0565 (pixman_implementation_t *imp,
     _mm_empty ();
 }
 
+/* ------------------------------
+ * composite_add_n_8888_8888_ca
+ */
+static void
+sse2_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
+				   pixman_op_t              op,
+				   pixman_image_t *         src_image,
+				   pixman_image_t *         mask_image,
+				   pixman_image_t *         dst_image,
+				   int32_t                  src_x,
+				   int32_t                  src_y,
+				   int32_t                  mask_x,
+				   int32_t                  mask_y,
+				   int32_t                  dest_x,
+				   int32_t                  dest_y,
+				   int32_t                  width,
+				   int32_t                  height)
+{
+    uint32_t src, srca;
+    uint32_t    *dst_line, d;
+    uint32_t    *mask_line, m;
+    uint32_t pack_cmp;
+    int dst_stride, mask_stride;
+
+    __m128i xmm_src, xmm_alpha;
+    __m128i xmm_dst;
+    __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi;
+
+    __m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest;
+
+    src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+    srca = src >> 24;
+    
+    if (src == 0)
+	return;
+
+    PIXMAN_IMAGE_GET_LINE (
+	dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+    PIXMAN_IMAGE_GET_LINE (
+	mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
+
+    xmm_src = _mm_unpacklo_epi8 (
+	create_mask_2x32_128 (src, src), _mm_setzero_si128 ());
+    xmm_alpha = expand_alpha_1x128 (xmm_src);
+    mmx_src   = _mm_movepi64_pi64 (xmm_src);
+    mmx_alpha = _mm_movepi64_pi64 (xmm_alpha);
+
+    while (height--)
+    {
+	int w = width;
+	const uint32_t *pm = (uint32_t *)mask_line;
+	uint32_t *pd = (uint32_t *)dst_line;
+
+	dst_line += dst_stride;
+	mask_line += mask_stride;
+
+	/* call prefetch hint to optimize cache load*/
+	cache_prefetch ((__m128i*)pd);
+	cache_prefetch ((__m128i*)pm);
+
+	while (w && (unsigned long)pd & 15)
+	{
+	    m = *pm++;
+
+	    if (m)
+	    {
+		d = *pd;
+		
+		mmx_mask = unpack_32_1x64 (m);
+		mmx_dest = unpack_32_1x64 (d);
+
+		*pd = pack_1x64_32 (
+		    _mm_adds_pu8 (pix_multiply_1x64 (mmx_mask, mmx_src), mmx_dest));
+	    }
+
+	    pd++;
+	    w--;
+	}
+
+	/* call prefetch hint to optimize cache load*/
+	cache_prefetch ((__m128i*)pd);
+	cache_prefetch ((__m128i*)pm);
+
+	while (w >= 4)
+	{
+	    /* fill cache line with next memory */
+	    cache_prefetch_next ((__m128i*)pd);
+	    cache_prefetch_next ((__m128i*)pm);
+
+	    xmm_mask = load_128_unaligned ((__m128i*)pm);
+
+	    pack_cmp =
+		_mm_movemask_epi8 (
+		    _mm_cmpeq_epi32 (xmm_mask, _mm_setzero_si128 ()));
+
+	    /* if all bits in mask are zero, pack_cmp are equal to 0xffff */
+	    if (pack_cmp != 0xffff)
+	    {
+		xmm_dst = load_128_aligned ((__m128i*)pd);
+
+		unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi);
+
+		pix_multiply_2x128 (&xmm_src, &xmm_src,
+				    &xmm_mask_lo, &xmm_mask_hi,
+				    &xmm_mask_lo, &xmm_mask_hi);
+		xmm_mask_hi = pack_2x128_128 (xmm_mask_lo, xmm_mask_hi);
+		
+		save_128_aligned (
+		    (__m128i*)pd, _mm_adds_epu8 (xmm_mask_hi, xmm_dst));
+	    }
+
+	    pd += 4;
+	    pm += 4;
+	    w -= 4;
+	}
+
+	while (w)
+	{
+	    m = *pm++;
+
+	    if (m)
+	    {
+		d = *pd;
+		
+		mmx_mask = unpack_32_1x64 (m);
+		mmx_dest = unpack_32_1x64 (d);
+
+		*pd = pack_1x64_32 (
+		    _mm_adds_pu8 (pix_multiply_1x64 (mmx_mask, mmx_src), mmx_dest));
+	    }
+
+	    pd++;
+	    w--;
+	}
+    }
+
+    _mm_empty ();
+}
+
 /* ---------------------------------------------------------------------------
  * composite_over_n_8888_8888_ca
  */
@@ -5502,6 +5641,7 @@ static const pixman_fast_path_t sse2_fast_paths[] =
     { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, sse2_composite_copy_area,           0 },
     { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, sse2_composite_copy_area,           0 },
 
+    { PIXMAN_OP_ADD,  PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, sse2_composite_add_n_8888_8888_ca,  NEED_COMPONENT_ALPHA },
     { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_null,     PIXMAN_a8,       sse2_composite_add_8000_8000,       0 },
     { PIXMAN_OP_ADD,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, sse2_composite_add_8888_8888,       0 },
     { PIXMAN_OP_ADD,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, sse2_composite_add_8888_8888,       0 },
commit 23d38201165876c031d314f73e09a75afcac4f00
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri Jul 31 10:26:10 2009 -0400

    Add a fast path for the add_n_8888_8888() operation.
    
    It shows up on gnome-terminal traces.

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index d2ce26f..40b7f9c 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -348,6 +348,67 @@ fast_composite_over_n_8_8888 (pixman_implementation_t *imp,
 }
 
 static void
+fast_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
+				   pixman_op_t              op,
+				   pixman_image_t *         src_image,
+				   pixman_image_t *         mask_image,
+				   pixman_image_t *         dst_image,
+				   int32_t                  src_x,
+				   int32_t                  src_y,
+				   int32_t                  mask_x,
+				   int32_t                  mask_y,
+				   int32_t                  dest_x,
+				   int32_t                  dest_y,
+				   int32_t                  width,
+				   int32_t                  height)
+{
+    uint32_t src, srca, s;
+    uint32_t    *dst_line, *dst, d;
+    uint32_t    *mask_line, *mask, ma;
+    int dst_stride, mask_stride;
+    uint16_t w;
+
+    src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+
+    srca = src >> 24;
+    if (src == 0)
+	return;
+
+    PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
+    PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1);
+
+    while (height--)
+    {
+	dst = dst_line;
+	dst_line += dst_stride;
+	mask = mask_line;
+	mask_line += mask_stride;
+	w = width;
+
+	while (w--)
+	{
+	    ma = *mask++;
+
+	    if (ma == 0xffffffff && srca == 0xff)
+	    {
+		*dst = src;
+	    }
+	    else if (ma)
+	    {
+		d = *dst;
+		s = src;
+		
+		UN8x4_MUL_UN8x4_ADD_UN8x4 (s, ma, d);
+
+		*dst = s;
+	    }
+
+	    dst++;
+	}
+    }
+}
+
+static void
 fast_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
                                     pixman_op_t              op,
                                     pixman_image_t *         src_image,
@@ -1064,6 +1125,7 @@ static const pixman_fast_path_t c_fast_paths[] =
     { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_a8r8g8b8, fast_composite_add_8888_8888,   0 },
     { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8,  PIXMAN_null,     PIXMAN_a8b8g8r8, fast_composite_add_8888_8888,   0 },
     { PIXMAN_OP_ADD, PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fast_composite_add_8000_8000,   0 },
+    { PIXMAN_OP_ADD, PIXMAN_solid,     PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fast_composite_add_n_8888_8888_ca, NEED_COMPONENT_ALPHA },
     { PIXMAN_OP_ADD, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8,       fast_composite_add_8888_8_8,    0 },
     { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_a8r8g8b8, fast_composite_solid_fill, 0 },
     { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_x8r8g8b8, fast_composite_solid_fill, 0 },
commit c606a05213d1fe5d73b39454407414a2a245da39
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Fri Jul 31 07:29:31 2009 -0400

    Move bounds checks for REPEAT_NONE to get_pixel()
    
    On a P4, this is a large speedup for the swfdec-fill-rate-2xaa trace:
    
    After:
    
    [ # ]  backend                         test   min(s) median(s) stddev. count
    [  0]    image        swfdec-fill-rate-2xaa   33.061   33.061   0.00%    1/1
    
    Before:
    
    [ # ]  backend                         test   min(s) median(s) stddev. count
    [  0]    image        swfdec-fill-rate-2xaa   40.342   40.342   0.00%    1/1
    
    Pixman 0.14.0 produces this:
    
    [ # ]  backend                         test   min(s) median(s) stddev. count
    [  0]    image        swfdec-fill-rate-2xaa   36.896   36.896   0.00%    1/1

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 48e9779..0be2af3 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -124,12 +124,18 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
 }
 
 static force_inline uint32_t
-get_pixel (bits_image_t *image, int x, int y)
+get_pixel (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
 {
+    if (check_bounds &&
+	(x < 0 || x >= image->width || y < 0 || y >= image->height))
+    {
+	return 0;
+    }
+	
     return image->fetch_pixel_32 (image, x, y);
 }
 
-static force_inline pixman_bool_t
+static force_inline void
 repeat (pixman_repeat_t repeat, int size, int *coord)
 {
     switch (repeat)
@@ -150,12 +156,8 @@ repeat (pixman_repeat_t repeat, int size, int *coord)
 	break;
 
     case PIXMAN_REPEAT_NONE:
-	if (*coord < 0 || *coord >= size)
-	    return FALSE;
 	break;
     }
-
-    return TRUE;
 }
 
 static force_inline uint32_t
@@ -166,14 +168,16 @@ bits_image_fetch_pixel_nearest (bits_image_t   *image,
     int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
     int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
 
-    if (repeat (image->common.repeat, image->width, &x0) &&
-	repeat (image->common.repeat, image->height, &y0))
+    if (image->common.repeat != PIXMAN_REPEAT_NONE)
     {
-	return get_pixel (image, x0, y0);
+	repeat (image->common.repeat, image->width, &x0);
+	repeat (image->common.repeat, image->height, &y0);
+
+	return get_pixel (image, x0, y0, FALSE);
     }
     else
     {
-	return 0;
+	return get_pixel (image, x0, y0, TRUE);
     }
 }
 
@@ -185,7 +189,6 @@ bits_image_fetch_pixel_bilinear (bits_image_t   *image,
     pixman_repeat_t repeat_mode = image->common.repeat;
     int width = image->width;
     int height = image->height;
-    pixman_bool_t x1r, y1r, x2r, y2r;
     int x1, y1, x2, y2;
     uint32_t tl, tr, bl, br, r;
     int32_t distx, disty, idistx, idisty;
@@ -202,24 +205,25 @@ bits_image_fetch_pixel_bilinear (bits_image_t   *image,
     x2 = x1 + 1;
     y2 = y1 + 1;
 
-    x1r = repeat (repeat_mode, width, &x1);
-    y1r = repeat (repeat_mode, height, &y1);
-    x2r = repeat (repeat_mode, width, &x2);
-    y2r = repeat (repeat_mode, height, &y2);
-
-    tl = tr = bl = br = 0;
-
-    if (x1r && y1r)
-	tl = get_pixel (image, x1, y1);
-
-    if (x1r && y2r)
-	bl = get_pixel (image, x1, y2);
-
-    if (x2r && y1r)
-	tr = get_pixel (image, x2, y1);
-
-    if (x2r && y2r)
-	br = get_pixel (image, x2, y2);
+    if (repeat_mode != PIXMAN_REPEAT_NONE)
+    {
+	repeat (repeat_mode, width, &x1);
+	repeat (repeat_mode, height, &y1);
+	repeat (repeat_mode, width, &x2);
+	repeat (repeat_mode, height, &y2);
+	
+	tl = get_pixel (image, x1, y1, FALSE);
+	bl = get_pixel (image, x1, y2, FALSE);
+	tr = get_pixel (image, x2, y1, FALSE);
+	br = get_pixel (image, x2, y2, FALSE);
+    }
+    else
+    {
+	tl = get_pixel (image, x1, y1, TRUE);
+	tr = get_pixel (image, x2, y1, TRUE);
+	bl = get_pixel (image, x1, y2, TRUE);
+	br = get_pixel (image, x2, y2, TRUE);
+    }
 
     idistx = 256 - distx;
     idisty = 256 - disty;
@@ -273,21 +277,28 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
 	    int rx = i;
 	    int ry = j;
 
-	    if (repeat (repeat_mode, width, &rx)	&&
-		repeat (repeat_mode, height, &ry))
+	    pixman_fixed_t f = *params;
+	    
+	    if (f)
 	    {
-		pixman_fixed_t f = *params;
-
-		if (f)
+		uint32_t pixel;
+		
+		if (repeat_mode != PIXMAN_REPEAT_NONE)
 		{
-		    uint32_t pixel =
-			get_pixel (image, rx, ry);
-
-		    srtot += RED_8 (pixel) * f;
-		    sgtot += GREEN_8 (pixel) * f;
-		    sbtot += BLUE_8 (pixel) * f;
-		    satot += ALPHA_8 (pixel) * f;
+		    repeat (repeat_mode, width, &rx);
+		    repeat (repeat_mode, height, &ry);
+		    
+		    pixel = get_pixel (image, rx, ry, FALSE);
 		}
+		else
+		{
+		    pixel = get_pixel (image, rx, ry, TRUE);
+		}
+
+		srtot += RED_8 (pixel) * f;
+		sgtot += GREEN_8 (pixel) * f;
+		sbtot += BLUE_8 (pixel) * f;
+		satot += ALPHA_8 (pixel) * f;
 	    }
 
 	    params++;
commit 1bec3e8395a307812b25fb195823ac7cf2915340
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu Jul 30 10:51:38 2009 -0400

    Remove leftover 0xffffffff in repeat()

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 00d9e57..48e9779 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -151,10 +151,7 @@ repeat (pixman_repeat_t repeat, int size, int *coord)
 
     case PIXMAN_REPEAT_NONE:
 	if (*coord < 0 || *coord >= size)
-	{
-	    *coord = 0xffffffff;
 	    return FALSE;
-	}
 	break;
     }
 
commit 1b98166b016af5fa374ad534d53b772c7fd2c4a5
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu Jul 30 10:45:18 2009 -0400

    Remove unused function

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 18c8c41..00d9e57 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -124,12 +124,6 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
 }
 
 static force_inline uint32_t
-bits_image_fetch_pixel (bits_image_t *image, int x, int y)
-{
-    return image->fetch_pixel_32 (image, x, y);
-}
-
-static force_inline uint32_t
 get_pixel (bits_image_t *image, int x, int y)
 {
     return image->fetch_pixel_32 (image, x, y);
commit 06836d35d26941e826e99fe35e06da50756da641
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu Jul 30 10:03:44 2009 -0400

    Misc formatting

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index d3b392f..18c8c41 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -98,14 +98,14 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
 {
     uint32_t pixel;
     uint32_t pixel_a;
-    
+
     pixel = image->fetch_pixel_raw_32 (image, x, y);
-    
+
     assert (image->common.alpha_map);
-	
+
     x -= image->common.alpha_origin_x;
     y -= image->common.alpha_origin_y;
-    
+
     if (x < 0 || x >= image->common.alpha_map->width ||
 	y < 0 || y >= image->common.alpha_map->height)
     {
@@ -117,7 +117,7 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
 	    image->common.alpha_map, x, y);
 	pixel_a = ALPHA_8 (pixel_a);
     }
-    
+
     UN8x4_MUL_UN8 (pixel, pixel_a);
 
     return pixel;
@@ -229,7 +229,7 @@ bits_image_fetch_pixel_bilinear (bits_image_t   *image,
 
     if (x2r && y2r)
 	br = get_pixel (image, x2, y2);
-    
+
     idistx = 256 - distx;
     idisty = 256 - disty;
 
@@ -246,7 +246,7 @@ bits_image_fetch_pixel_bilinear (bits_image_t   *image,
     ft = GET8 (tl, 24) * idistx + GET8 (tr, 24) * distx;
     fb = GET8 (bl, 24) * idistx + GET8 (br, 24) * distx;
     r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-    
+
     return r;
 }
 
@@ -274,14 +274,14 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
     y2 = y1 + cheight;
 
     srtot = sgtot = sbtot = satot = 0;
-    
+
     for (i = y1; i < y2; ++i)
     {
 	for (j = x1; j < x2; ++j)
 	{
 	    int rx = i;
 	    int ry = j;
-	    
+
 	    if (repeat (repeat_mode, width, &rx)	&&
 		repeat (repeat_mode, height, &ry))
 	    {
@@ -291,7 +291,7 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
 		{
 		    uint32_t pixel =
 			get_pixel (image, rx, ry);
-		    
+
 		    srtot += RED_8 (pixel) * f;
 		    sgtot += GREEN_8 (pixel) * f;
 		    sbtot += BLUE_8 (pixel) * f;
@@ -307,7 +307,7 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
     srtot >>= 16;
     sgtot >>= 16;
     sbtot >>= 16;
-    
+
     satot = CLIP (satot, 0, 0xff);
     srtot = CLIP (srtot, 0, 0xff);
     sgtot = CLIP (sgtot, 0, 0xff);
@@ -383,7 +383,7 @@ bits_image_fetch_transformed (pixman_image_t * image,
     y = v.vector[1];
     w = v.vector[2];
 
-    if (w == pixman_fixed_1 && uw == 0)
+    if (w == pixman_fixed_1 && uw == 0) /* Affine */
     {
 	for (i = 0; i < width; ++i)
 	{
@@ -402,16 +402,16 @@ bits_image_fetch_transformed (pixman_image_t * image,
 	for (i = 0; i < width; ++i)
 	{
 	    pixman_fixed_t x0, y0;
-	
+
 	    if (!mask || (mask[i] & mask_bits))
 	    {
 		x0 = ((pixman_fixed_48_16_t)x << 16) / w;
 		y0 = ((pixman_fixed_48_16_t)y << 16) / w;
-		
+
 		buffer[i] =
 		    bits_image_fetch_pixel_filtered (&image->bits, x0, y0);
 	    }
-	    
+
 	    x += ux;
 	    y += uy;
 	    w += uw;
@@ -452,7 +452,7 @@ bits_image_fetch_solid_64 (pixman_image_t * image,
     uint64_t *end;
 
     color = image->bits.fetch_pixel_raw_64 (&image->bits, 0, 0);
-    
+
     end = buffer + width;
     while (buffer < end)
 	*(buffer++) = color;
@@ -531,7 +531,7 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
 	    image->fetch_scanline_raw_64 ((pixman_image_t *)image, x, y, w, buffer, NULL, 0);
 	else
 	    image->fetch_scanline_raw_32 ((pixman_image_t *)image, x, y, w, buffer, NULL, 0);
-	
+
 	buffer += w * (wide? 2 : 1);
 	x += w;
 	width -= w;
commit 7c8959ea3b2ff3d3abf995b3feccc677e15b4e27
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu Jul 30 09:58:12 2009 -0400

    Change all the fetch_pixels() functions to only fetch one pixel.

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 22f41cb..532aa2e 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -63,10 +63,10 @@
     uint32_t *bits = __bits_image->bits;                                \
     int stride = __bits_image->rowstride;                               \
     int offset0 = stride < 0 ?                                          \
-	((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \
-	stride * __bits_image->height;                                  \
+    ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride :	\
+    stride * __bits_image->height;					\
     int offset1 = stride < 0 ?                                          \
-	offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) :    \
+    offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) :	\
 	offset0 + (offset0 >> 2)
 
 /* Note no trailing semicolon on the above macro; if it's there, then
@@ -364,7 +364,7 @@ fetch_scanline_r8g8b8 (pixman_image_t *image,
     while (pixel < end)
     {
 	uint32_t b = 0xff000000;
-
+	
 #ifdef WORDS_BIGENDIAN
 	b |= (READ (image, pixel++) << 16);
 	b |= (READ (image, pixel++) << 8);
@@ -374,7 +374,7 @@ fetch_scanline_r8g8b8 (pixman_image_t *image,
 	b |= (READ (image, pixel++) << 8);
 	b |= (READ (image, pixel++) << 16);
 #endif
-
+	
 	*buffer++ = b;
     }
 }
@@ -430,7 +430,7 @@ fetch_scanline_r5g6b5 (pixman_image_t *image,
 	
 	r |= (r >> 5) & 0x70007;
 	r |= (r >> 6) & 0x300;
-
+	
 	*buffer++ = 0xff000000 | r;
     }
 }
@@ -456,7 +456,7 @@ fetch_scanline_b5g6r5 (pixman_image_t *image,
 	b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
 	g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
 	r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-
+	
 	*buffer++ = 0xff000000 | r | g | b;
     }
 }
@@ -483,7 +483,7 @@ fetch_scanline_a1r5g5b5 (pixman_image_t *image,
 	r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
 	g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
 	b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
-
+	
 	*buffer++ = a | r | g | b;
     }
 }
@@ -509,7 +509,7 @@ fetch_scanline_x1r5g5b5 (pixman_image_t *image,
 	r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
 	g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
 	b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
-
+	
 	*buffer++ = 0xff000000 | r | g | b;
     }
 }
@@ -536,7 +536,7 @@ fetch_scanline_a1b5g5r5 (pixman_image_t *image,
 	b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
 	g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
 	r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-
+	
 	*buffer++ = a | r | g | b;
     }
 }
@@ -562,7 +562,7 @@ fetch_scanline_x1b5g5r5 (pixman_image_t *image,
 	b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
 	g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
 	r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-
+	
 	*buffer++ = 0xff000000 | r | g | b;
     }
 }
@@ -589,7 +589,7 @@ fetch_scanline_a4r4g4b4 (pixman_image_t *image,
 	r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
 	g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
 	b = ((p & 0x000f) | ((p & 0x000f) << 4));
-
+	
 	*buffer++ = a | r | g | b;
     }
 }
@@ -615,7 +615,7 @@ fetch_scanline_x4r4g4b4 (pixman_image_t *image,
 	r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
 	g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
 	b = ((p & 0x000f) | ((p & 0x000f) << 4));
-
+	
 	*buffer++ = 0xff000000 | r | g | b;
     }
 }
@@ -642,7 +642,7 @@ fetch_scanline_a4b4g4r4 (pixman_image_t *image,
 	b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
 	g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
 	r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
-
+	
 	*buffer++ = a | r | g | b;
     }
 }
@@ -668,7 +668,7 @@ fetch_scanline_x4b4g4r4 (pixman_image_t *image,
 	b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
 	g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
 	r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
-
+	
 	*buffer++ = 0xff000000 | r | g | b;
     }
 }
@@ -714,7 +714,7 @@ fetch_scanline_r3g3b2 (pixman_image_t *image,
 	     ((p & 0x03) << 2) |
 	     ((p & 0x03) << 4) |
 	     ((p & 0x03) << 6));
-
+	
 	*buffer++ = 0xff000000 | r | g | b;
     }
 }
@@ -741,13 +741,13 @@ fetch_scanline_b2g3r3 (pixman_image_t *image,
 	     ((p & 0xc0) >> 2) |
 	     ((p & 0xc0) >> 4) |
 	     ((p & 0xc0) >> 6));
-
+	
 	g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
-
+	
 	r = (((p & 0x07)     ) |
 	     ((p & 0x07) << 3) |
 	     ((p & 0x06) << 6)) << 16;
-
+	
 	*buffer++ = 0xff000000 | r | g | b;
     }
 }
@@ -774,7 +774,7 @@ fetch_scanline_a2r2g2b2 (pixman_image_t *image,
 	r = ((p & 0x30) * 0x55) << 12;
 	g = ((p & 0x0c) * 0x55) << 6;
 	b = ((p & 0x03) * 0x55);
-
+	
 	*buffer++ = a | r | g | b;
     }
 }
@@ -801,7 +801,7 @@ fetch_scanline_a2b2g2r2 (pixman_image_t *image,
 	b = ((p & 0x30) * 0x55) >> 6;
 	g = ((p & 0x0c) * 0x55) << 6;
 	r = ((p & 0x03) * 0x55) << 16;
-
+	
 	*buffer++ = a | r | g | b;
     }
 }
@@ -823,7 +823,7 @@ fetch_scanline_c8 (pixman_image_t *image,
     while (pixel < end)
     {
 	uint32_t p = READ (image, pixel++);
-
+	
 	*buffer++ = indexed->rgba[p];
     }
 }
@@ -844,7 +844,7 @@ fetch_scanline_x4a4 (pixman_image_t *image,
     while (pixel < end)
     {
 	uint8_t p = READ (image, pixel++) & 0xf;
-
+	
 	*buffer++ = (p | (p << 4)) << 24;
     }
 }
@@ -873,7 +873,7 @@ fetch_scanline_a4 (pixman_image_t *image,
 	uint32_t p = FETCH_4 (image, bits, i + x);
 	
 	p |= p << 4;
-
+	
 	*buffer++ = p << 24;
     }
 }
@@ -1137,1264 +1137,676 @@ fetch_scanline_yv12 (pixman_image_t *image,
 /**************************** Pixel wise fetching *****************************/
 
 /* Despite the type, expects a uint64_t buffer */
-static void
-fetch_pixels_a2r10g10b10_64 (bits_image_t *image,
-                             uint32_t *    b,
-                             int           n_pixels)
+static uint64_t
+fetch_pixel_a2r10g10b10 (bits_image_t *image,
+			 int		  offset,
+			 int           line)
 {
-    int i;
-    uint64_t *buffer = (uint64_t *)b;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t p = READ (image, bits + offset);
+    uint64_t a = p >> 30;
+    uint64_t r = (p >> 20) & 0x3ff;
+    uint64_t g = (p >> 10) & 0x3ff;
+    uint64_t b = p & 0x3ff;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = ((uint32_t *)buffer)[2 * i];
-	int line = ((uint32_t *)buffer)[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t p = READ (image, bits + offset);
-	    uint64_t a = p >> 30;
-	    uint64_t r = (p >> 20) & 0x3ff;
-	    uint64_t g = (p >> 10) & 0x3ff;
-	    uint64_t b = p & 0x3ff;
-	    
-	    r = r << 6 | r >> 4;
-	    g = g << 6 | g >> 4;
-	    b = b << 6 | b >> 4;
-	    
-	    a <<= 62;
-	    a |= a >> 2;
-	    a |= a >> 4;
-	    a |= a >> 8;
-	    
-	    buffer[i] = a << 48 | r << 32 | g << 16 | b;
-	}
-    }
+    r = r << 6 | r >> 4;
+    g = g << 6 | g >> 4;
+    b = b << 6 | b >> 4;
+    
+    a <<= 62;
+    a |= a >> 2;
+    a |= a >> 4;
+    a |= a >> 8;
+    
+    return a << 48 | r << 32 | g << 16 | b;
 }
 
 /* Despite the type, this function expects a uint64_t buffer */
-static void
-fetch_pixels_x2r10g10b10_64 (bits_image_t *image,
-                             uint32_t *    b,
-                             int           n_pixels)
+static uint64_t
+fetch_pixel_x2r10g10b10 (bits_image_t *image,
+			 int	   offset,
+			 int           line)
 {
-    uint64_t *buffer = (uint64_t *)b;
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t p = READ (image, bits + offset);
+    uint64_t r = (p >> 20) & 0x3ff;
+    uint64_t g = (p >> 10) & 0x3ff;
+    uint64_t b = p & 0x3ff;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = ((uint32_t *)buffer)[2 * i];
-	int line = ((uint32_t *)buffer)[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t p = READ (image, bits + offset);
-	    uint64_t r = (p >> 20) & 0x3ff;
-	    uint64_t g = (p >> 10) & 0x3ff;
-	    uint64_t b = p & 0x3ff;
-	    
-	    r = r << 6 | r >> 4;
-	    g = g << 6 | g >> 4;
-	    b = b << 6 | b >> 4;
-	    
-	    buffer[i] = 0xffffULL << 48 | r << 32 | g << 16 | b;
-	}
-    }
+    r = r << 6 | r >> 4;
+    g = g << 6 | g >> 4;
+    b = b << 6 | b >> 4;
+    
+    return 0xffffULL << 48 | r << 32 | g << 16 | b;
 }
 
 /* Despite the type, expects a uint64_t buffer */
-static void
-fetch_pixels_a2b10g10r10_64 (bits_image_t *image,
-                             uint32_t *    b,
-                             int           n_pixels)
+static uint64_t
+fetch_pixel_a2b10g10r10 (bits_image_t *image,
+			 int           offset,
+			 int           line)
 {
-    uint64_t *buffer = (uint64_t *)b;
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t p = READ (image, bits + offset);
+    uint64_t a = p >> 30;
+    uint64_t b = (p >> 20) & 0x3ff;
+    uint64_t g = (p >> 10) & 0x3ff;
+    uint64_t r = p & 0x3ff;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = ((uint32_t *)buffer)[2 * i];
-	int line = ((uint32_t *)buffer)[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t p = READ (image, bits + offset);
-	    uint64_t a = p >> 30;
-	    uint64_t b = (p >> 20) & 0x3ff;
-	    uint64_t g = (p >> 10) & 0x3ff;
-	    uint64_t r = p & 0x3ff;
-	    
-	    r = r << 6 | r >> 4;
-	    g = g << 6 | g >> 4;
-	    b = b << 6 | b >> 4;
-	    
-	    a <<= 62;
-	    a |= a >> 2;
-	    a |= a >> 4;
-	    a |= a >> 8;
-	    
-	    buffer[i] = a << 48 | r << 32 | g << 16 | b;
-	}
-    }
+    r = r << 6 | r >> 4;
+    g = g << 6 | g >> 4;
+    b = b << 6 | b >> 4;
+    
+    a <<= 62;
+    a |= a >> 2;
+    a |= a >> 4;
+    a |= a >> 8;
+    
+    return a << 48 | r << 32 | g << 16 | b;
 }
 
 /* Despite the type, this function expects a uint64_t buffer */
-static void
-fetch_pixels_x2b10g10r10_64 (bits_image_t *image,
-                             uint32_t *    b,
-                             int           n_pixels)
+static uint64_t
+fetch_pixel_x2b10g10r10 (bits_image_t *image,
+			 int           offset,
+			 int           line)
 {
-    uint64_t *buffer = (uint64_t *)b;
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t p = READ (image, bits + offset);
+    uint64_t b = (p >> 20) & 0x3ff;
+    uint64_t g = (p >> 10) & 0x3ff;
+    uint64_t r = p & 0x3ff;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = ((uint32_t *)buffer)[2 * i];
-	int line = ((uint32_t *)buffer)[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t p = READ (image, bits + offset);
-	    uint64_t b = (p >> 20) & 0x3ff;
-	    uint64_t g = (p >> 10) & 0x3ff;
-	    uint64_t r = p & 0x3ff;
-	    
-	    r = r << 6 | r >> 4;
-	    g = g << 6 | g >> 4;
-	    b = b << 6 | b >> 4;
-	    
-	    buffer[i] = 0xffffULL << 48 | r << 32 | g << 16 | b;
-	}
-    }
+    r = r << 6 | r >> 4;
+    g = g << 6 | g >> 4;
+    b = b << 6 | b >> 4;
+    
+    return 0xffffULL << 48 | r << 32 | g << 16 | b;
 }
 
-static void
-fetch_pixels_a8r8g8b8 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a8r8g8b8 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
-    
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    buffer[i] = READ (image, (uint32_t *)bits + offset);
-	}
-    }
+    uint32_t *bits = image->bits + line * image->rowstride;
+    return READ (image, (uint32_t *)bits + offset);
 }
 
-static void
-fetch_pixels_x8r8g8b8 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_x8r8g8b8 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
-    
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    buffer[i] = READ (image, (uint32_t *)bits + offset) | 0xff000000;
-	}
-    }
+    uint32_t *bits = image->bits + line * image->rowstride;
+
+    return READ (image, (uint32_t *)bits + offset) | 0xff000000;
 }
 
-static void
-fetch_pixels_a8b8g8r8 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a8b8g8r8 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-	    
-	    buffer[i] = ((pixel & 0xff000000) |
-	                 ((pixel >> 16) & 0xff) |
-	                 (pixel & 0x0000ff00) |
-	                 ((pixel & 0xff) << 16));
-	}
-    }
+    return ((pixel & 0xff000000) |
+	    ((pixel >> 16) & 0xff) |
+	    (pixel & 0x0000ff00) |
+	    ((pixel & 0xff) << 16));
 }
 
-static void
-fetch_pixels_x8b8g8r8 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_x8b8g8r8 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-	    
-	    buffer[i] = (0xff000000) |
-		((pixel >> 16) & 0xff) |
-		(pixel & 0x0000ff00) |
-		((pixel & 0xff) << 16);
-	}
-    }
+    return ((0xff000000) |
+	    ((pixel >> 16) & 0xff) |
+	    (pixel & 0x0000ff00) |
+	    ((pixel & 0xff) << 16));
 }
 
-static void
-fetch_pixels_b8g8r8a8 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_b8g8r8a8 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-	    
-	    buffer[i] = ((pixel & 0xff000000) >> 24 |
-	                 (pixel & 0x00ff0000) >> 8 |
-	                 (pixel & 0x0000ff00) << 8 |
-	                 (pixel & 0x000000ff) << 24);
-	}
-    }
+    return ((pixel & 0xff000000) >> 24 |
+	    (pixel & 0x00ff0000) >> 8 |
+	    (pixel & 0x0000ff00) << 8 |
+	    (pixel & 0x000000ff) << 24);
 }
 
-static void
-fetch_pixels_b8g8r8x8 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_b8g8r8x8 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-	    
-	    buffer[i] = ((0xff000000) |
-	                 (pixel & 0xff000000) >> 24 |
-	                 (pixel & 0x00ff0000) >> 8 |
-	                 (pixel & 0x0000ff00) << 8);
-	}
-    }
+    return ((0xff000000) |
+	    (pixel & 0xff000000) >> 24 |
+	    (pixel & 0x00ff0000) >> 8 |
+	    (pixel & 0x0000ff00) << 8);
 }
 
-static void
-fetch_pixels_r8g8b8 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_r8g8b8 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint8_t   *pixel = ((uint8_t *) bits) + (offset * 3);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint8_t   *pixel = ((uint8_t *) bits) + (offset * 3);
-	    
 #ifdef WORDS_BIGENDIAN
-	    buffer[i] = (0xff000000 |
-	                 (READ (image, pixel + 0) << 16) |
-	                 (READ (image, pixel + 1) << 8) |
-	                 (READ (image, pixel + 2)));
+    return (0xff000000 |
+	    (READ (image, pixel + 0) << 16) |
+	    (READ (image, pixel + 1) << 8) |
+	    (READ (image, pixel + 2)));
 #else
-	    buffer[i] = (0xff000000 |
-	                 (READ (image, pixel + 2) << 16) |
-	                 (READ (image, pixel + 1) << 8) |
-	                 (READ (image, pixel + 0)));
+    return (0xff000000 |
+	    (READ (image, pixel + 2) << 16) |
+	    (READ (image, pixel + 1) << 8) |
+	    (READ (image, pixel + 0)));
 #endif
-	}
-    }
 }
 
-static void
-fetch_pixels_b8g8r8 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_b8g8r8 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
-    
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint8_t   *pixel = ((uint8_t *) bits) + (offset * 3);
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint8_t   *pixel = ((uint8_t *) bits) + (offset * 3);
 #ifdef WORDS_BIGENDIAN
-	    buffer[i] = (0xff000000 |
-	                 (READ (image, pixel + 2) << 16) |
-	                 (READ (image, pixel + 1) << 8) |
-	                 (READ (image, pixel + 0)));
+    return (0xff000000 |
+	    (READ (image, pixel + 2) << 16) |
+	    (READ (image, pixel + 1) << 8) |
+	    (READ (image, pixel + 0)));
 #else
-	    buffer[i] = (0xff000000 |
-	                 (READ (image, pixel + 0) << 16) |
-	                 (READ (image, pixel + 1) << 8) |
-	                 (READ (image, pixel + 2)));
+    return (0xff000000 |
+	    (READ (image, pixel + 0) << 16) |
+	    (READ (image, pixel + 1) << 8) |
+	    (READ (image, pixel + 2)));
 #endif
-	}
-    }
 }
 
-static void
-fetch_pixels_r5g6b5 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_r5g6b5 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t r, g, b;
-	    
-	    r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
-	    g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
-	    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
+    g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
+    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_b5g6r5 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_b5g6r5 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
+    uint32_t r, g, b;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t r, g, b;
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    
-	    b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
-	    g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
-	    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-	    
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
+    g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
+    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_a1r5g5b5 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a1r5g5b5 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
-	    r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
-	    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-	    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-	    
-	    buffer[i] = (a | r | g | b);
-	}
-    }
+    a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
+    r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
+    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+    
+    return (a | r | g | b);
 }
 
-static void
-fetch_pixels_x1r5g5b5 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_x1r5g5b5 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t r, g, b;
-	    
-	    r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
-	    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-	    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-	    
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
+    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+    b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_a1b5g5r5 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a1b5g5r5 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
-	    b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
-	    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-	    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-	    
-	    buffer[i] = (a | r | g | b);
-	}
-    }
+    a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
+    b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
+    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+    
+    return (a | r | g | b);
 }
 
-static void
-fetch_pixels_x1b5g5r5 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_x1b5g5r5 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t r, g, b;
-	    
-	    b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
-	    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
-	    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-	    
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
+    g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+    r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_a4r4g4b4 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a4r4g4b4 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
-	    r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
-	    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-	    b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
-	    
-	    buffer[i] = (a | r | g | b);
-	}
-    }
+    a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
+    r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+    b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+    
+    return (a | r | g | b);
 }
 
-static void
-fetch_pixels_x4r4g4b4 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_x4r4g4b4 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t r, g, b;
-	    
-	    r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
-	    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-	    b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
-	    
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+    b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_a4b4g4r4 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a4b4g4r4 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
-	    b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
-	    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-	    r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
-	    
-	    buffer[i] = (a | r | g | b);
-	}
-    }
+    a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
+    b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
+    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+    r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
+    
+    return (a | r | g | b);
 }
 
-static void
-fetch_pixels_x4b4g4r4 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_x4b4g4r4 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-	    uint32_t r, g, b;
-	    
-	    b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
-	    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
-	    r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
-	    
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
+    g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+    r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_a8 (bits_image_t *image,
-                 uint32_t *    buffer,
-                 int           n_pixels)
+static uint32_t
+fetch_pixel_a8 (bits_image_t *image,
+		int           offset,
+		int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-	    
-	    buffer[i] = pixel << 24;
-	}
-    }
+    return pixel << 24;
 }
 
-static void
-fetch_pixels_r3g3b2 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_r3g3b2 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-	    uint32_t r, g, b;
-	    
-	    r = ((pixel & 0xe0) |
-	         ((pixel & 0xe0) >> 3) |
-	         ((pixel & 0xc0) >> 6)) << 16;
-	    
-	    g = ((pixel & 0x1c) |
-	         ((pixel & 0x18) >> 3) |
-	         ((pixel & 0x1c) << 3)) << 8;
-	    
-	    b = (((pixel & 0x03)     ) |
-	         ((pixel & 0x03) << 2) |
-	         ((pixel & 0x03) << 4) |
-	         ((pixel & 0x03) << 6));
-	    
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    r = ((pixel & 0xe0) |
+	 ((pixel & 0xe0) >> 3) |
+	 ((pixel & 0xc0) >> 6)) << 16;
+    
+    g = ((pixel & 0x1c) |
+	 ((pixel & 0x18) >> 3) |
+	 ((pixel & 0x1c) << 3)) << 8;
+    
+    b = (((pixel & 0x03)     ) |
+	 ((pixel & 0x03) << 2) |
+	 ((pixel & 0x03) << 4) |
+	 ((pixel & 0x03) << 6));
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_b2g3r3 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_b2g3r3 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-	    uint32_t r, g, b;
-	    
-	    b = ((pixel & 0xc0)         |
-	         ((pixel & 0xc0) >> 2)  |
-	         ((pixel & 0xc0) >> 4)  |
-	         ((pixel & 0xc0) >> 6));
-	    
-	    g = ((pixel & 0x38)         |
-	         ((pixel & 0x38) >> 3)  |
-	         ((pixel & 0x30) << 2)) << 8;
-	    
-	    r = ((pixel & 0x07)         |
-	         ((pixel & 0x07) << 3)  |
-	         ((pixel & 0x06) << 6)) << 16;
-	    
-	    buffer[i] = (0xff000000 | r | g | b);
-	}
-    }
+    b = ((pixel & 0xc0)         |
+	 ((pixel & 0xc0) >> 2)  |
+	 ((pixel & 0xc0) >> 4)  |
+	 ((pixel & 0xc0) >> 6));
+    
+    g = ((pixel & 0x38)         |
+	 ((pixel & 0x38) >> 3)  |
+	 ((pixel & 0x30) << 2)) << 8;
+    
+    r = ((pixel & 0x07)         |
+	 ((pixel & 0x07) << 3)  |
+	 ((pixel & 0x06) << 6)) << 16;
+    
+    return (0xff000000 | r | g | b);
 }
 
-static void
-fetch_pixels_a2r2g2b2 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a2r2g2b2 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = ((pixel & 0xc0) * 0x55) << 18;
-	    r = ((pixel & 0x30) * 0x55) << 12;
-	    g = ((pixel & 0x0c) * 0x55) << 6;
-	    b = ((pixel & 0x03) * 0x55);
-	    
-	    buffer[i] = a | r | g | b;
-	}
-    }
+    a = ((pixel & 0xc0) * 0x55) << 18;
+    r = ((pixel & 0x30) * 0x55) << 12;
+    g = ((pixel & 0x0c) * 0x55) << 6;
+    b = ((pixel & 0x03) * 0x55);
+    
+    return a | r | g | b;
 }
 
-static void
-fetch_pixels_a2b2g2r2 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a2b2g2r2 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = ((pixel & 0xc0) * 0x55) << 18;
-	    b = ((pixel & 0x30) * 0x55) >> 6;
-	    g = ((pixel & 0x0c) * 0x55) << 6;
-	    r = ((pixel & 0x03) * 0x55) << 16;
-	    
-	    buffer[i] = a | r | g | b;
-	}
-    }
+    a = ((pixel & 0xc0) * 0x55) << 18;
+    b = ((pixel & 0x30) * 0x55) >> 6;
+    g = ((pixel & 0x0c) * 0x55) << 6;
+    r = ((pixel & 0x03) * 0x55) << 16;
+    
+    return a | r | g | b;
 }
 
-static void
-fetch_pixels_c8 (bits_image_t *image,
-                 uint32_t *    buffer,
-                 int           n_pixels)
+static uint32_t
+fetch_pixel_c8 (bits_image_t *image,
+		int           offset,
+		int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+    const pixman_indexed_t * indexed = image->indexed;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-	    const pixman_indexed_t * indexed = image->indexed;
-	    
-	    buffer[i] = indexed->rgba[pixel];
-	}
-    }
+    return indexed->rgba[pixel];
 }
 
-static void
-fetch_pixels_x4a4 (bits_image_t *image,
-                   uint32_t *    buffer,
-                   int           n_pixels)
+static uint32_t
+fetch_pixel_x4a4 (bits_image_t *image,
+		  int           offset,
+		  int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-	    
-	    buffer[i] = ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
-	}
-    }
+    return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
 }
 
-static void
-fetch_pixels_a4 (bits_image_t *image,
-                 uint32_t *    buffer,
-                 int           n_pixels)
+static uint32_t
+fetch_pixel_a4 (bits_image_t *image,
+		int           offset,
+		int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = FETCH_4 (image, bits, offset);
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = FETCH_4 (image, bits, offset);
-	    
-	    pixel |= pixel << 4;
-	    buffer[i] = pixel << 24;
-	}
-    }
+    pixel |= pixel << 4;
+    return pixel << 24;
 }
 
-static void
-fetch_pixels_r1g2b1 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_r1g2b1 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = FETCH_4 (image, bits, offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = FETCH_4 (image, bits, offset);
-	    uint32_t r, g, b;
-	    
-	    r = ((pixel & 0x8) * 0xff) << 13;
-	    g = ((pixel & 0x6) * 0x55) << 7;
-	    b = ((pixel & 0x1) * 0xff);
-	    
-	    buffer[i] = 0xff000000 | r | g | b;
-	}
-    }
+    r = ((pixel & 0x8) * 0xff) << 13;
+    g = ((pixel & 0x6) * 0x55) << 7;
+    b = ((pixel & 0x1) * 0xff);
+    
+    return 0xff000000 | r | g | b;
 }
 
-static void
-fetch_pixels_b1g2r1 (bits_image_t *image,
-                     uint32_t *    buffer,
-                     int           n_pixels)
+static uint32_t
+fetch_pixel_b1g2r1 (bits_image_t *image,
+		    int           offset,
+		    int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = FETCH_4 (image, bits, offset);
+    uint32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = FETCH_4 (image, bits, offset);
-	    uint32_t r, g, b;
-	    
-	    b = ((pixel & 0x8) * 0xff) >> 3;
-	    g = ((pixel & 0x6) * 0x55) << 7;
-	    r = ((pixel & 0x1) * 0xff) << 16;
-	    
-	    buffer[i] = 0xff000000 | r | g | b;
-	}
-    }
+    b = ((pixel & 0x8) * 0xff) >> 3;
+    g = ((pixel & 0x6) * 0x55) << 7;
+    r = ((pixel & 0x1) * 0xff) << 16;
+    
+    return 0xff000000 | r | g | b;
 }
 
-static void
-fetch_pixels_a1r1g1b1 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a1r1g1b1 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = FETCH_4 (image, bits, offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = FETCH_4 (image, bits, offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = ((pixel & 0x8) * 0xff) << 21;
-	    r = ((pixel & 0x4) * 0xff) << 14;
-	    g = ((pixel & 0x2) * 0xff) << 7;
-	    b = ((pixel & 0x1) * 0xff);
-	    
-	    buffer[i] = a | r | g | b;
-	}
-    }
+    a = ((pixel & 0x8) * 0xff) << 21;
+    r = ((pixel & 0x4) * 0xff) << 14;
+    g = ((pixel & 0x2) * 0xff) << 7;
+    b = ((pixel & 0x1) * 0xff);
+    
+    return a | r | g | b;
 }
 
-static void
-fetch_pixels_a1b1g1r1 (bits_image_t *image,
-                       uint32_t *    buffer,
-                       int           n_pixels)
+static uint32_t
+fetch_pixel_a1b1g1r1 (bits_image_t *image,
+		      int           offset,
+		      int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = FETCH_4 (image, bits, offset);
+    uint32_t a, r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = FETCH_4 (image, bits, offset);
-	    uint32_t a, r, g, b;
-	    
-	    a = ((pixel & 0x8) * 0xff) << 21;
-	    r = ((pixel & 0x4) * 0xff) >> 3;
-	    g = ((pixel & 0x2) * 0xff) << 7;
-	    b = ((pixel & 0x1) * 0xff) << 16;
-	    
-	    buffer[i] = a | r | g | b;
-	}
-    }
+    a = ((pixel & 0x8) * 0xff) << 21;
+    r = ((pixel & 0x4) * 0xff) >> 3;
+    g = ((pixel & 0x2) * 0xff) << 7;
+    b = ((pixel & 0x1) * 0xff) << 16;
+    
+    return a | r | g | b;
 }
 
-static void
-fetch_pixels_c4 (bits_image_t *image,
-                 uint32_t *    buffer,
-                 int           n_pixels)
+static uint32_t
+fetch_pixel_c4 (bits_image_t *image,
+		int           offset,
+		int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = FETCH_4 (image, bits, offset);
+    const pixman_indexed_t * indexed = image->indexed;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = FETCH_4 (image, bits, offset);
-	    const pixman_indexed_t * indexed = image->indexed;
-	    
-	    buffer[i] = indexed->rgba[pixel];
-	}
-    }
+    return indexed->rgba[pixel];
 }
 
-static void
-fetch_pixels_a1 (bits_image_t *image,
-                 uint32_t *    buffer,
-                 int           n_pixels)
+static uint32_t
+fetch_pixel_a1 (bits_image_t *image,
+		int           offset,
+		int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, bits + (offset >> 5));
+    uint32_t a;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, bits + (offset >> 5));
-	    uint32_t a;
-	    
 #ifdef WORDS_BIGENDIAN
-	    a = pixel >> (0x1f - (offset & 0x1f));
+    a = pixel >> (0x1f - (offset & 0x1f));
 #else
-	    a = pixel >> (offset & 0x1f);
+    a = pixel >> (offset & 0x1f);
 #endif
-	    a = a & 1;
-	    a |= a << 1;
-	    a |= a << 2;
-	    a |= a << 4;
-	    
-	    buffer[i] = a << 24;
-	}
-    }
+    a = a & 1;
+    a |= a << 1;
+    a |= a << 2;
+    a |= a << 4;
+    
+    return a << 24;
 }
 
-static void
-fetch_pixels_g1 (bits_image_t *image,
-                 uint32_t *    buffer,
-                 int           n_pixels)
+static uint32_t
+fetch_pixel_g1 (bits_image_t *image,
+		int           offset,
+		int           line)
 {
-    int i;
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t pixel = READ (image, bits + (offset >> 5));
+    const pixman_indexed_t * indexed = image->indexed;
+    uint32_t a;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    uint32_t *bits = image->bits + line * image->rowstride;
-	    uint32_t pixel = READ (image, bits + (offset >> 5));
-	    const pixman_indexed_t * indexed = image->indexed;
-	    uint32_t a;
-	    
 #ifdef WORDS_BIGENDIAN
-	    a = pixel >> (0x1f - (offset & 0x1f));
+    a = pixel >> (0x1f - (offset & 0x1f));
 #else
-	    a = pixel >> (offset & 0x1f);
+    a = pixel >> (offset & 0x1f);
 #endif
-	    a = a & 1;
-	    
-	    buffer[i] = indexed->rgba[a];
-	}
-    }
+    a = a & 1;
+    
+    return indexed->rgba[a];
 }
 
-static void
-fetch_pixels_yuy2 (bits_image_t *image,
-                   uint32_t *    buffer,
-                   int           n_pixels)
+static uint32_t
+fetch_pixel_yuy2 (bits_image_t *image,
+		  int           offset,
+		  int           line)
 {
-    int i;
+    const uint32_t *bits = image->bits + image->rowstride * line;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    const uint32_t *bits = image->bits + image->rowstride * line;
-	    
-	    int16_t y, u, v;
-	    int32_t r, g, b;
-	    
-	    y = ((uint8_t *) bits)[offset << 1] - 16;
-	    u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
-	    v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
-	    
-	    /* R = 1.164(Y - 16) + 1.596(V - 128) */
-	    r = 0x012b27 * y + 0x019a2e * v;
-	    
-	    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
-	    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
-	    
-	    /* B = 1.164(Y - 16) + 2.018(U - 128) */
-	    b = 0x012b27 * y + 0x0206a2 * u;
-	    
-	    buffer[i] = 0xff000000 |
-		(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
-		(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
-		(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
-	}
-    }
+    int16_t y, u, v;
+    int32_t r, g, b;
+    
+    y = ((uint8_t *) bits)[offset << 1] - 16;
+    u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
+    v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
+    
+    /* R = 1.164(Y - 16) + 1.596(V - 128) */
+    r = 0x012b27 * y + 0x019a2e * v;
+    
+    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+    
+    /* B = 1.164(Y - 16) + 2.018(U - 128) */
+    b = 0x012b27 * y + 0x0206a2 * u;
+    
+    return 0xff000000 |
+	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
+	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
+	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
 }
 
-static void
-fetch_pixels_yv12 (bits_image_t *image,
-                   uint32_t *    buffer,
-                   int           n_pixels)
+static uint32_t
+fetch_pixel_yv12 (bits_image_t *image,
+		  int           offset,
+		  int           line)
 {
-    int i;
+    YV12_SETUP (image);
+    int16_t y = YV12_Y (line)[offset] - 16;
+    int16_t u = YV12_U (line)[offset >> 1] - 128;
+    int16_t v = YV12_V (line)[offset >> 1] - 128;
+    int32_t r, g, b;
     
-    for (i = 0; i < n_pixels; ++i)
-    {
-	int offset = buffer[2 * i];
-	int line = buffer[2 * i + 1];
-	
-	if (offset == 0xffffffff || line == 0xffffffff)
-	{
-	    buffer[i] = 0;
-	}
-	else
-	{
-	    YV12_SETUP (image);
-	    int16_t y = YV12_Y (line)[offset] - 16;
-	    int16_t u = YV12_U (line)[offset >> 1] - 128;
-	    int16_t v = YV12_V (line)[offset >> 1] - 128;
-	    int32_t r, g, b;
-	    
-	    /* R = 1.164(Y - 16) + 1.596(V - 128) */
-	    r = 0x012b27 * y + 0x019a2e * v;
-	    
-	    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
-	    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
-	    
-	    /* B = 1.164(Y - 16) + 2.018(U - 128) */
-	    b = 0x012b27 * y + 0x0206a2 * u;
-	    
-	    buffer[i] = 0xff000000 |
-		(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
-		(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
-		(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
-	}
-    }
+    /* R = 1.164(Y - 16) + 1.596(V - 128) */
+    r = 0x012b27 * y + 0x019a2e * v;
+    
+    /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+    g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+    
+    /* B = 1.164(Y - 16) + 2.018(U - 128) */
+    b = 0x012b27 * y + 0x0206a2 * u;
+    
+    return 0xff000000 |
+	(r >= 0 ? r < 0x1000000 ? r         & 0xff0000 : 0xff0000 : 0) |
+	(g >= 0 ? g < 0x1000000 ? (g >> 8)  & 0x00ff00 : 0x00ff00 : 0) |
+	(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
 }
 
 /*********************************** Store ************************************/
@@ -2762,7 +2174,7 @@ store_scanline_a1b5g5r5 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT_A (values[i]);
-
+	
 	WRITE (image, pixel++,
 	       ((a << 8) & 0x8000) |
 	       ((b << 7) & 0x7c00) |
@@ -2785,7 +2197,7 @@ store_scanline_x1b5g5r5 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT (values[i]);
-
+	
 	WRITE (image, pixel++, ((b << 7) & 0x7c00) |
 	       ((g << 2) & 0x03e0) |
 	       ((r >> 3)         ));
@@ -2806,7 +2218,7 @@ store_scanline_a4r4g4b4 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT_A (values[i]);
-
+	
 	WRITE (image, pixel++,
 	       ((a << 8) & 0xf000) |
 	       ((r << 4) & 0x0f00) |
@@ -2829,7 +2241,7 @@ store_scanline_x4r4g4b4 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT (values[i]);
-
+	
 	WRITE (image, pixel++,
 	       ((r << 4) & 0x0f00) |
 	       ((g     ) & 0x00f0) |
@@ -2872,7 +2284,7 @@ store_scanline_x4b4g4r4 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT (values[i]);
-
+	
 	WRITE (image, pixel++,
 	       ((b << 4) & 0x0f00) |
 	       ((g     ) & 0x00f0) |
@@ -2933,7 +2345,7 @@ store_scanline_b2g3r3 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT (values[i]);
-
+	
 	WRITE (image, pixel++,
 	       ((b     ) & 0xc0) |
 	       ((g >> 2) & 0x38) |
@@ -2955,7 +2367,7 @@ store_scanline_a2r2g2b2 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT_A (values[i]);
-
+	
 	WRITE (image, pixel++,
 	       ((a     ) & 0xc0) |
 	       ((r >> 2) & 0x30) |
@@ -2978,7 +2390,7 @@ store_scanline_a2b2g2r2 (bits_image_t *  image,
     for (i = 0; i < width; ++i)
     {
 	SPLIT_A (values[i]);
-
+	
 	*(pixel++) =
 	    ((a     ) & 0xc0) |
 	    ((b >> 2) & 0x30) |
@@ -3020,12 +2432,12 @@ store_scanline_x4a4 (bits_image_t *  image,
 
 #define STORE_8(img,l,o,v)  (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
 #ifdef WORDS_BIGENDIAN
-#define STORE_4(img,l,o,v)					   \
+#define STORE_4(img,l,o,v)					    \
     STORE_8 (img,l,o,((o) & 4 ?					    \
                       (FETCH_8 (img,l,o) & 0xf0) | (v) :            \
                       (FETCH_8 (img,l,o) & 0x0f) | ((v) << 4)))
 #else
-#define STORE_4(img,l,o,v)				       \
+#define STORE_4(img,l,o,v)					\
     STORE_8 (img,l,o,((o) & 4 ?					\
                       (FETCH_8 (img,l,o) & 0x0f) | ((v) << 4) : \
                       (FETCH_8 (img,l,o) & 0xf0) | (v)))
@@ -3169,7 +2581,7 @@ store_scanline_a1 (bits_image_t *  image,
     {
 	uint32_t  *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
 	uint32_t mask, v;
-
+	
 #ifdef WORDS_BIGENDIAN
 	mask = 1 << (0x1f - ((i + x) & 0x1f));
 #else
@@ -3196,14 +2608,14 @@ store_scanline_g1 (bits_image_t *  image,
     {
 	uint32_t  *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
 	uint32_t mask, v;
-
+	
 #ifdef WORDS_BIGENDIAN
 	mask = 1 << (0x1f - ((i + x) & 0x1f));
 #else
 	mask = 1 << ((i + x) & 0x1f);
 #endif
 	v = RGB24_TO_ENTRY_Y (indexed, values[i]) ? mask : 0;
-
+	
 	WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
     }
 }
@@ -3258,14 +2670,17 @@ fetch_scanline_generic_64 (pixman_image_t *image,
 }
 
 /* Despite the type, this function expects a uint64_t *buffer */
-static void
-fetch_pixels_generic_64 (bits_image_t *image,
-                         uint32_t *    buffer,
-                         int           n_pixels)
+static uint64_t
+fetch_pixel_generic_64 (bits_image_t *image,
+			int	      offset,
+			int           line)
 {
-    image->fetch_pixels_raw_32 (image, buffer, n_pixels);
+    uint32_t pixel32 = image->fetch_pixel_raw_32 (image, offset, line);
+    uint64_t result;
     
-    pixman_expand ((uint64_t *)buffer, buffer, image->format, n_pixels);
+    pixman_expand ((uint64_t *)&result, &pixel32, image->format, 1);
+
+    return result;
 }
 
 /*
@@ -3274,17 +2689,17 @@ fetch_pixels_generic_64 (bits_image_t *image,
  *
  * WARNING: This function loses precision!
  */
-static void
-fetch_pixels_generic_lossy_32 (bits_image_t *image,
-                               uint32_t *    buffer,
-                               int           n_pixels)
+static uint32_t
+fetch_pixel_generic_lossy_32 (bits_image_t *image,
+			      int           offset,
+			      int           line)
 {
-    /* Since buffer contains n_pixels coordinate pairs, it also has enough
-     * room for n_pixels 64 bit pixels.
-     */
-    image->fetch_pixels_raw_64 (image, buffer, n_pixels);
+    uint64_t pixel64 = image->fetch_pixel_raw_64 (image, offset, line);
+    uint32_t result;
     
-    pixman_contract (buffer, (uint64_t *)buffer, n_pixels);
+    pixman_contract (&result, &pixel64, 1);
+
+    return result;
 }
 
 typedef struct
@@ -3292,8 +2707,8 @@ typedef struct
     pixman_format_code_t	format;
     fetch_scanline_t		fetch_scanline_raw_32;
     fetch_scanline_t		fetch_scanline_raw_64;
-    fetch_pixels_t		fetch_pixels_raw_32;
-    fetch_pixels_t		fetch_pixels_raw_64;
+    fetch_pixel_32_t		fetch_pixel_raw_32;
+    fetch_pixel_64_t		fetch_pixel_raw_64;
     store_scanline_t		store_scanline_raw_32;
     store_scanline_t		store_scanline_raw_64;
 } format_info_t;
@@ -3303,9 +2718,9 @@ typedef struct
 	PIXMAN_ ## format,						\
 	    fetch_scanline_ ## format,					\
 	    fetch_scanline_generic_64,					\
-	    fetch_pixels_ ## format, fetch_pixels_generic_64,		\
+	    fetch_pixel_ ## format, fetch_pixel_generic_64,		\
 	    store_scanline_ ## format, store_scanline_generic_64	\
-	    }
+    }
 
 static const format_info_t accessors[] =
 {
@@ -3344,17 +2759,17 @@ static const format_info_t accessors[] =
     FORMAT_INFO (c8),
     
 #define fetch_scanline_g8 fetch_scanline_c8
-#define fetch_pixels_g8 fetch_pixels_c8
+#define fetch_pixel_g8 fetch_pixel_c8
 #define store_scanline_g8 store_scanline_c8
     FORMAT_INFO (g8),
-
+    
 #define fetch_scanline_x4c4 fetch_scanline_c8
-#define fetch_pixels_x4c4 fetch_pixels_c8
+#define fetch_pixel_x4c4 fetch_pixel_c8
 #define store_scanline_x4c4 store_scanline_c8
     FORMAT_INFO (x4c4),
-
+    
 #define fetch_scanline_x4g4 fetch_scanline_c8
-#define fetch_pixels_x4g4 fetch_pixels_c8
+#define fetch_pixel_x4g4 fetch_pixel_c8
 #define store_scanline_x4g4 store_scanline_c8
     FORMAT_INFO (x4g4),
     
@@ -3368,9 +2783,9 @@ static const format_info_t accessors[] =
     FORMAT_INFO (a1b1g1r1),
     
     FORMAT_INFO (c4),
-
+    
 #define fetch_scanline_g4 fetch_scanline_c4
-#define fetch_pixels_g4 fetch_pixels_c4
+#define fetch_pixel_g4 fetch_pixel_c4
 #define store_scanline_g4 store_scanline_c4
     FORMAT_INFO (g4),
     
@@ -3382,33 +2797,33 @@ static const format_info_t accessors[] =
     
     { PIXMAN_a2r10g10b10,
       NULL, fetch_scanline_a2r10g10b10,
-      fetch_pixels_generic_lossy_32, fetch_pixels_a2r10g10b10_64,
+      fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
       NULL, store_scanline_a2r10g10b10 },
     
     { PIXMAN_x2r10g10b10,
       NULL, fetch_scanline_x2r10g10b10,
-      fetch_pixels_generic_lossy_32, fetch_pixels_x2r10g10b10_64,
+      fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
       NULL, store_scanline_x2r10g10b10 },
     
     { PIXMAN_a2b10g10r10,
       NULL, fetch_scanline_a2b10g10r10,
-      fetch_pixels_generic_lossy_32, fetch_pixels_a2b10g10r10_64,
+      fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
       NULL, store_scanline_a2b10g10r10 },
     
     { PIXMAN_x2b10g10r10,
       NULL, fetch_scanline_x2b10g10r10,
-      fetch_pixels_generic_lossy_32, fetch_pixels_x2b10g10r10_64,
+      fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
       NULL, store_scanline_x2b10g10r10 },
     
 /* YUV formats */
     { PIXMAN_yuy2,
       fetch_scanline_yuy2, fetch_scanline_generic_64,
-      fetch_pixels_yuy2, fetch_pixels_generic_64,
+      fetch_pixel_yuy2, fetch_pixel_generic_64,
       NULL, NULL },
-
+    
     { PIXMAN_yv12,
       fetch_scanline_yv12, fetch_scanline_generic_64,
-      fetch_pixels_yv12, fetch_pixels_generic_64,
+      fetch_pixel_yv12, fetch_pixel_generic_64,
       NULL, NULL },
     
     { PIXMAN_null },
@@ -3425,8 +2840,8 @@ setup_accessors (bits_image_t *image)
 	{
 	    image->fetch_scanline_raw_32 = info->fetch_scanline_raw_32;
 	    image->fetch_scanline_raw_64 = info->fetch_scanline_raw_64;
-	    image->fetch_pixels_raw_32 = info->fetch_pixels_raw_32;
-	    image->fetch_pixels_raw_64 = info->fetch_pixels_raw_64;
+	    image->fetch_pixel_raw_32 = info->fetch_pixel_raw_32;
+	    image->fetch_pixel_raw_64 = info->fetch_pixel_raw_64;
 	    image->store_scanline_raw_32 = info->store_scanline_raw_32;
 	    image->store_scanline_raw_64 = info->store_scanline_raw_64;
 	    
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index de88ae9..d3b392f 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -94,51 +94,42 @@ _pixman_image_store_scanline_64 (bits_image_t *  image,
 /* Fetch functions */
 
 static uint32_t
-bits_image_fetch_pixel_raw (bits_image_t *image, int x, int y)
-{
-    uint32_t pixel[2];
-
-    pixel[0] = x;
-    pixel[1] = y;
-
-    image->fetch_pixels_raw_32 (image, pixel, 1);
-
-    return pixel[0];
-}
-
-static uint32_t
 bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
 {
     uint32_t pixel;
+    uint32_t pixel_a;
     
-    pixel = bits_image_fetch_pixel_raw (image, x, y);
+    pixel = image->fetch_pixel_raw_32 (image, x, y);
     
-    if (image->common.alpha_map)
-    {
-	uint32_t pixel_a;
+    assert (image->common.alpha_map);
 	
-	x -= image->common.alpha_origin_x;
-	y -= image->common.alpha_origin_y;
-
-	if (x < 0 || x >= image->common.alpha_map->width ||
-	    y < 0 || y >= image->common.alpha_map->height)
-	{
-	    pixel_a = 0;
-	}
-	else
-	{
-	    pixel_a = bits_image_fetch_pixel_raw (
-		image->common.alpha_map, x, y);
-	    pixel_a = ALPHA_8 (pixel_a);
-	}
-
-	UN8x4_MUL_UN8 (pixel, pixel_a);
+    x -= image->common.alpha_origin_x;
+    y -= image->common.alpha_origin_y;
+    
+    if (x < 0 || x >= image->common.alpha_map->width ||
+	y < 0 || y >= image->common.alpha_map->height)
+    {
+	pixel_a = 0;
     }
+    else
+    {
+	pixel_a = image->fetch_pixel_raw_32 (
+	    image->common.alpha_map, x, y);
+	pixel_a = ALPHA_8 (pixel_a);
+    }
+    
+    UN8x4_MUL_UN8 (pixel, pixel_a);
 
     return pixel;
 }
 
 static force_inline uint32_t
+bits_image_fetch_pixel (bits_image_t *image, int x, int y)
+{
+    return image->fetch_pixel_32 (image, x, y);
+}
+
+static force_inline uint32_t
 get_pixel (bits_image_t *image, int x, int y)
 {
     return image->fetch_pixel_32 (image, x, y);
@@ -437,17 +428,14 @@ bits_image_fetch_solid_32 (pixman_image_t * image,
                            const uint32_t * mask,
                            uint32_t         mask_bits)
 {
-    uint32_t color[2];
+    uint32_t color;
     uint32_t *end;
 
-    color[0] = 0;
-    color[1] = 0;
-
-    image->bits.fetch_pixels_raw_32 (&image->bits, color, 1);
+    color = image->bits.fetch_pixel_raw_32 (&image->bits, 0, 0);
 
     end = buffer + width;
     while (buffer < end)
-	*(buffer++) = color[0];
+	*(buffer++) = color;
 }
 
 static void
@@ -460,14 +448,10 @@ bits_image_fetch_solid_64 (pixman_image_t * image,
                            uint32_t         unused2)
 {
     uint64_t color;
-    uint32_t *coords = (uint32_t *)&color;
     uint64_t *buffer = (uint64_t *)b;
     uint64_t *end;
 
-    coords[0] = 0;
-    coords[1] = 0;
-    
-    image->bits.fetch_pixels_raw_64 (&image->bits, (uint32_t *)&color, 1);
+    color = image->bits.fetch_pixel_raw_64 (&image->bits, 0, 0);
     
     end = buffer + width;
     while (buffer < end)
@@ -652,8 +636,7 @@ bits_image_property_changed (pixman_image_t *image)
 
     _pixman_bits_image_setup_raw_accessors (bits);
 
-    image->bits.fetch_pixel_raw_32 = bits_image_fetch_pixel_raw;
-    image->bits.fetch_pixel_32 = bits_image_fetch_pixel_raw;
+    image->bits.fetch_pixel_32 = image->bits.fetch_pixel_raw_32;
 
     if (bits->common.alpha_map)
     {
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index dc8e0db..a4e6cbd 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -34,14 +34,14 @@ typedef void (*fetch_scanline_t) (pixman_image_t *image,
 				  const uint32_t *mask,
 				  uint32_t        mask_bits);
 
-typedef void (*fetch_pixels_t)   (bits_image_t *  image,
-				  uint32_t *      buffer,
-				  int             n_pixels);
-
 typedef uint32_t (*fetch_pixel_32_t) (bits_image_t *image,
 				      int           x,
 				      int           y);
 
+typedef uint64_t (*fetch_pixel_64_t) (bits_image_t *image,
+				      int           x,
+				      int           y);
+
 typedef void (*store_scanline_t) (bits_image_t *  image,
 				  int             x,
 				  int             y,
@@ -167,15 +167,13 @@ struct bits_image
     uint32_t *                 free_me;
     int                        rowstride;  /* in number of uint32_t's */
 
-    /* Fetch raw pixels, with no regard for transformations, alpha map etc. */
-    fetch_pixels_t             fetch_pixels_raw_32;
-    fetch_pixels_t             fetch_pixels_raw_64;
-
     /* Fetch a pixel, disregarding alpha maps, transformations etc. */
     fetch_pixel_32_t	       fetch_pixel_raw_32;
+    fetch_pixel_64_t	       fetch_pixel_raw_64;
 
     /* Fetch a pixel, taking alpha maps into account */
     fetch_pixel_32_t	       fetch_pixel_32;
+    fetch_pixel_64_t	       fetch_pixel_64;
 
     /* Fetch raw scanlines, with no regard for transformations, alpha maps etc. */
     fetch_scanline_t           fetch_scanline_raw_32;
commit 31096446b6866de0a85ca6eb4fb68a45b21c4b49
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 09:43:12 2009 -0400

    Add fetch_pixel_raw_32 and fetch_pixel_32 virtual functions.
    
    By default both are intialized to bits_image_fetch_pixel_raw(), but if
    there is an alpha map, then fetch_pixel_32() is set to
    bits_image_fetch_pixel_alpha().

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 3bd6338..de88ae9 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -93,7 +93,7 @@ _pixman_image_store_scanline_64 (bits_image_t *  image,
 
 /* Fetch functions */
 
-static force_inline uint32_t
+static uint32_t
 bits_image_fetch_pixel_raw (bits_image_t *image, int x, int y)
 {
     uint32_t pixel[2];
@@ -138,6 +138,12 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
     return pixel;
 }
 
+static force_inline uint32_t
+get_pixel (bits_image_t *image, int x, int y)
+{
+    return image->fetch_pixel_32 (image, x, y);
+}
+
 static force_inline pixman_bool_t
 repeat (pixman_repeat_t repeat, int size, int *coord)
 {
@@ -181,7 +187,7 @@ bits_image_fetch_pixel_nearest (bits_image_t   *image,
     if (repeat (image->common.repeat, image->width, &x0) &&
 	repeat (image->common.repeat, image->height, &y0))
     {
-	return bits_image_fetch_pixel_alpha (image, x0, y0);
+	return get_pixel (image, x0, y0);
     }
     else
     {
@@ -222,16 +228,16 @@ bits_image_fetch_pixel_bilinear (bits_image_t   *image,
     tl = tr = bl = br = 0;
 
     if (x1r && y1r)
-	tl = bits_image_fetch_pixel_alpha (image, x1, y1);
+	tl = get_pixel (image, x1, y1);
 
     if (x1r && y2r)
-	bl = bits_image_fetch_pixel_alpha (image, x1, y2);
+	bl = get_pixel (image, x1, y2);
 
     if (x2r && y1r)
-	tr = bits_image_fetch_pixel_alpha (image, x2, y1);
+	tr = get_pixel (image, x2, y1);
 
     if (x2r && y2r)
-	br = bits_image_fetch_pixel_alpha (image, x2, y2);
+	br = get_pixel (image, x2, y2);
     
     idistx = 256 - distx;
     idisty = 256 - disty;
@@ -293,7 +299,7 @@ bits_image_fetch_pixel_convolution (bits_image_t   *image,
 		if (f)
 		{
 		    uint32_t pixel =
-			bits_image_fetch_pixel_alpha (image, rx, ry);
+			get_pixel (image, rx, ry);
 		    
 		    srtot += RED_8 (pixel) * f;
 		    sgtot += GREEN_8 (pixel) * f;
@@ -646,12 +652,17 @@ bits_image_property_changed (pixman_image_t *image)
 
     _pixman_bits_image_setup_raw_accessors (bits);
 
+    image->bits.fetch_pixel_raw_32 = bits_image_fetch_pixel_raw;
+    image->bits.fetch_pixel_32 = bits_image_fetch_pixel_raw;
+
     if (bits->common.alpha_map)
     {
 	image->common.get_scanline_64 =
 	    _pixman_image_get_scanline_generic_64;
 	image->common.get_scanline_32 =
 	    bits_image_fetch_transformed;
+
+	image->bits.fetch_pixel_32 = bits_image_fetch_pixel_alpha;
     }
     else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
              bits->width == 1 &&
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 8e62d57..dc8e0db 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -38,6 +38,10 @@ typedef void (*fetch_pixels_t)   (bits_image_t *  image,
 				  uint32_t *      buffer,
 				  int             n_pixels);
 
+typedef uint32_t (*fetch_pixel_32_t) (bits_image_t *image,
+				      int           x,
+				      int           y);
+
 typedef void (*store_scanline_t) (bits_image_t *  image,
 				  int             x,
 				  int             y,
@@ -167,6 +171,12 @@ struct bits_image
     fetch_pixels_t             fetch_pixels_raw_32;
     fetch_pixels_t             fetch_pixels_raw_64;
 
+    /* Fetch a pixel, disregarding alpha maps, transformations etc. */
+    fetch_pixel_32_t	       fetch_pixel_raw_32;
+
+    /* Fetch a pixel, taking alpha maps into account */
+    fetch_pixel_32_t	       fetch_pixel_32;
+
     /* Fetch raw scanlines, with no regard for transformations, alpha maps etc. */
     fetch_scanline_t           fetch_scanline_raw_32;
     fetch_scanline_t           fetch_scanline_raw_64;
commit a233b332cd9408d35e57a400874cca6188347cc2
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 09:12:51 2009 -0400

    Various renamings and clean-ups

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 5ef3370..3bd6338 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -93,40 +93,25 @@ _pixman_image_store_scanline_64 (bits_image_t *  image,
 
 /* Fetch functions */
 
-/* On entry, @buffer should contain @n_pixels (x, y) coordinate pairs, where
- * x and y are both uint32_ts. On exit, buffer will contain the corresponding
- * pixels.
- *
- * The coordinates must be within the sample grid. If either x or y is 0xffffffff,
- * the pixel returned will be 0.
- */
-static void
-bits_image_fetch_raw_pixels (bits_image_t *image,
-                             uint32_t *    buffer,
-                             int           n_pixels)
-{
-    image->fetch_pixels_raw_32 (image, buffer, n_pixels);
-}
-
-static uint32_t
-fetch_raw (bits_image_t *image, int x, int y)
+static force_inline uint32_t
+bits_image_fetch_pixel_raw (bits_image_t *image, int x, int y)
 {
     uint32_t pixel[2];
 
     pixel[0] = x;
     pixel[1] = y;
 
-    bits_image_fetch_raw_pixels (image, pixel, 1);
+    image->fetch_pixels_raw_32 (image, pixel, 1);
 
     return pixel[0];
 }
 
 static uint32_t
-bits_image_fetch_alpha_pixel (bits_image_t *image, int x, int y)
+bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
 {
     uint32_t pixel;
     
-    pixel = fetch_raw (image, x, y);
+    pixel = bits_image_fetch_pixel_raw (image, x, y);
     
     if (image->common.alpha_map)
     {
@@ -142,7 +127,8 @@ bits_image_fetch_alpha_pixel (bits_image_t *image, int x, int y)
 	}
 	else
 	{
-	    pixel_a = fetch_raw (image->common.alpha_map, x, y);
+	    pixel_a = bits_image_fetch_pixel_raw (
+		image->common.alpha_map, x, y);
 	    pixel_a = ALPHA_8 (pixel_a);
 	}
 
@@ -184,13 +170,10 @@ repeat (pixman_repeat_t repeat, int size, int *coord)
     return TRUE;
 }
 
-/* Buffer contains list of fixed-point coordinates on input,
- * a list of pixels on output
- */
-static uint32_t
-bits_image_fetch_nearest_pixels (bits_image_t *image,
-				 pixman_fixed_t x,
-				 pixman_fixed_t y)
+static force_inline uint32_t
+bits_image_fetch_pixel_nearest (bits_image_t   *image,
+				pixman_fixed_t  x,
+				pixman_fixed_t  y)
 {
     int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
     int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
@@ -198,7 +181,7 @@ bits_image_fetch_nearest_pixels (bits_image_t *image,
     if (repeat (image->common.repeat, image->width, &x0) &&
 	repeat (image->common.repeat, image->height, &y0))
     {
-	return bits_image_fetch_alpha_pixel (image, x0, y0);
+	return bits_image_fetch_pixel_alpha (image, x0, y0);
     }
     else
     {
@@ -206,15 +189,10 @@ bits_image_fetch_nearest_pixels (bits_image_t *image,
     }
 }
 
-#define N_TMP_PIXELS    (256)
-
-/* Buffer contains list of fixed-point coordinates on input,
- * a list of pixels on output
- */
-static uint32_t
-bits_image_fetch_bilinear_pixels (bits_image_t   *image,
-				  pixman_fixed_t x,
-				  pixman_fixed_t y)
+static force_inline uint32_t
+bits_image_fetch_pixel_bilinear (bits_image_t   *image,
+				 pixman_fixed_t  x,
+				 pixman_fixed_t  y)
 {
     pixman_repeat_t repeat_mode = image->common.repeat;
     int width = image->width;
@@ -244,16 +222,16 @@ bits_image_fetch_bilinear_pixels (bits_image_t   *image,
     tl = tr = bl = br = 0;
 
     if (x1r && y1r)
-	tl = bits_image_fetch_alpha_pixel (image, x1, y1);
+	tl = bits_image_fetch_pixel_alpha (image, x1, y1);
 
     if (x1r && y2r)
-	bl = bits_image_fetch_alpha_pixel (image, x1, y2);
+	bl = bits_image_fetch_pixel_alpha (image, x1, y2);
 
     if (x2r && y1r)
-	tr = bits_image_fetch_alpha_pixel (image, x2, y1);
+	tr = bits_image_fetch_pixel_alpha (image, x2, y1);
 
     if (x2r && y2r)
-	br = bits_image_fetch_alpha_pixel (image, x2, y2);
+	br = bits_image_fetch_pixel_alpha (image, x2, y2);
     
     idistx = 256 - distx;
     idisty = 256 - disty;
@@ -275,13 +253,10 @@ bits_image_fetch_bilinear_pixels (bits_image_t   *image,
     return r;
 }
 
-/* Buffer contains list of fixed-point coordinates on input,
- * a list of pixels on output
- */
-static uint32_t
-bits_image_fetch_convolution_pixels (bits_image_t   *image,
-				     pixman_fixed_t  x,
-				     pixman_fixed_t  y)
+static force_inline uint32_t
+bits_image_fetch_pixel_convolution (bits_image_t   *image,
+				    pixman_fixed_t  x,
+				    pixman_fixed_t  y)
 {
     pixman_fixed_t *params = image->common.filter_params;
     int x_off = (params[0] - pixman_fixed_1) >> 1;
@@ -317,7 +292,8 @@ bits_image_fetch_convolution_pixels (bits_image_t   *image,
 
 		if (f)
 		{
-		    uint32_t pixel = bits_image_fetch_alpha_pixel (image, rx, ry);
+		    uint32_t pixel =
+			bits_image_fetch_pixel_alpha (image, rx, ry);
 		    
 		    srtot += RED_8 (pixel) * f;
 		    sgtot += GREEN_8 (pixel) * f;
@@ -340,41 +316,33 @@ bits_image_fetch_convolution_pixels (bits_image_t   *image,
     sgtot = CLIP (sgtot, 0, 0xff);
     sbtot = CLIP (sbtot, 0, 0xff);
 
-    return ((satot << 24) |
-	    (srtot << 16) |
-	    (sgtot <<  8) |
-	    (sbtot       ));
+    return ((satot << 24) | (srtot << 16) | (sgtot <<  8) | (sbtot));
 }
 
-static inline uint32_t
-bits_image_fetch_filtered (bits_image_t *image,
-			   pixman_fixed_t x,
-			   pixman_fixed_t y)
+static force_inline uint32_t
+bits_image_fetch_pixel_filtered (bits_image_t *image,
+				 pixman_fixed_t x,
+				 pixman_fixed_t y)
 {
-    uint32_t pixel[2];
-
-    pixel[0] = x;
-    pixel[1] = y;
-    
     switch (image->common.filter)
     {
     case PIXMAN_FILTER_NEAREST:
     case PIXMAN_FILTER_FAST:
-	return bits_image_fetch_nearest_pixels (image, x, y);
+	return bits_image_fetch_pixel_nearest (image, x, y);
 	break;
 
     case PIXMAN_FILTER_BILINEAR:
     case PIXMAN_FILTER_GOOD:
     case PIXMAN_FILTER_BEST:
-	return bits_image_fetch_bilinear_pixels (image, x, y);
+	return bits_image_fetch_pixel_bilinear (image, x, y);
 	break;
 
     case PIXMAN_FILTER_CONVOLUTION:
-	return bits_image_fetch_convolution_pixels (image, x, y);
+	return bits_image_fetch_pixel_convolution (image, x, y);
 	break;
     }
 
-    return pixel[0];
+    return 0;
 }
 
 static void
@@ -423,7 +391,10 @@ bits_image_fetch_transformed (pixman_image_t * image,
 	for (i = 0; i < width; ++i)
 	{
 	    if (!mask || (mask[i] & mask_bits))
-		buffer[i] = bits_image_fetch_filtered (&image->bits, x, y);
+	    {
+		buffer[i] =
+		    bits_image_fetch_pixel_filtered (&image->bits, x, y);
+	    }
 
 	    x += ux;
 	    y += uy;
@@ -440,7 +411,8 @@ bits_image_fetch_transformed (pixman_image_t * image,
 		x0 = ((pixman_fixed_48_16_t)x << 16) / w;
 		y0 = ((pixman_fixed_48_16_t)y << 16) / w;
 		
-		buffer[i] = bits_image_fetch_filtered (&image->bits, x0, y0);
+		buffer[i] =
+		    bits_image_fetch_pixel_filtered (&image->bits, x0, y0);
 	    }
 	    
 	    x += ux;
commit 073399b09f073c44dd10b027788c09eddfcdf2e0
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 08:58:41 2009 -0400

    Change bits_image_fetch_alpha_pixels() to fetch just one pixel.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index ee24791..5ef3370 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -108,73 +108,48 @@ bits_image_fetch_raw_pixels (bits_image_t *image,
     image->fetch_pixels_raw_32 (image, buffer, n_pixels);
 }
 
-static void
-bits_image_fetch_alpha_pixels (bits_image_t *image,
-                               uint32_t *    buffer,
-                               int           n_pixels)
+static uint32_t
+fetch_raw (bits_image_t *image, int x, int y)
 {
-#define N_ALPHA_PIXELS 256
+    uint32_t pixel[2];
 
-    uint32_t alpha_pixels[N_ALPHA_PIXELS * 2];
-    int i;
+    pixel[0] = x;
+    pixel[1] = y;
 
-    if (!image->common.alpha_map)
-    {
-	bits_image_fetch_raw_pixels (image, buffer, n_pixels);
-	return;
-    }
+    bits_image_fetch_raw_pixels (image, pixel, 1);
+
+    return pixel[0];
+}
 
-    /* Alpha map */
-    i = 0;
-    while (i < n_pixels)
+static uint32_t
+bits_image_fetch_alpha_pixel (bits_image_t *image, int x, int y)
+{
+    uint32_t pixel;
+    
+    pixel = fetch_raw (image, x, y);
+    
+    if (image->common.alpha_map)
     {
-	int tmp_n_pixels = MIN (N_ALPHA_PIXELS, n_pixels - i);
-	int j;
-	int32_t *coords;
+	uint32_t pixel_a;
+	
+	x -= image->common.alpha_origin_x;
+	y -= image->common.alpha_origin_y;
 
-	memcpy (alpha_pixels, buffer + 2 * i, tmp_n_pixels * 2 * sizeof (int32_t));
-	coords = (int32_t *)alpha_pixels;
-	for (j = 0; j < tmp_n_pixels; ++j)
+	if (x < 0 || x >= image->common.alpha_map->width ||
+	    y < 0 || y >= image->common.alpha_map->height)
 	{
-	    int32_t x = coords[0];
-	    int32_t y = coords[1];
-
-	    if (x != 0xffffffff)
-	    {
-		x -= image->common.alpha_origin_x;
-
-		if (x < 0 || x >= image->common.alpha_map->width)
-		    x = 0xffffffff;
-	    }
-
-	    if (y != 0xffffffff)
-	    {
-		y -= image->common.alpha_origin_y;
-
-		if (y < 0 || y >= image->common.alpha_map->height)
-		    y = 0xffffffff;
-	    }
-
-	    coords[0] = x;
-	    coords[1] = y;
-
-	    coords += 2;
+	    pixel_a = 0;
 	}
-
-	bits_image_fetch_raw_pixels (image->common.alpha_map, alpha_pixels,
-	                             tmp_n_pixels);
-	bits_image_fetch_raw_pixels (image, buffer + 2 * i, tmp_n_pixels);
-
-	for (j = 0; j < tmp_n_pixels; ++j)
+	else
 	{
-	    int a = alpha_pixels[j] >> 24;
-	    uint32_t p = buffer[2 * i - j] | 0xff000000;
-
-	    UN8x4_MUL_UN8 (p, a);
-
-	    buffer[i++] = p;
+	    pixel_a = fetch_raw (image->common.alpha_map, x, y);
+	    pixel_a = ALPHA_8 (pixel_a);
 	}
+
+	UN8x4_MUL_UN8 (pixel, pixel_a);
     }
+
+    return pixel;
 }
 
 static force_inline pixman_bool_t
@@ -209,19 +184,6 @@ repeat (pixman_repeat_t repeat, int size, int *coord)
     return TRUE;
 }
 
-static uint32_t
-fetch_one (bits_image_t *image, int x, int y)
-{
-    uint32_t pixel[2];
-
-    pixel[0] = x;
-    pixel[1] = y;
-
-    bits_image_fetch_alpha_pixels (image, pixel, 1);
-
-    return pixel[0];
-}
-
 /* Buffer contains list of fixed-point coordinates on input,
  * a list of pixels on output
  */
@@ -236,7 +198,7 @@ bits_image_fetch_nearest_pixels (bits_image_t *image,
     if (repeat (image->common.repeat, image->width, &x0) &&
 	repeat (image->common.repeat, image->height, &y0))
     {
-	return fetch_one (image, x0, y0);
+	return bits_image_fetch_alpha_pixel (image, x0, y0);
     }
     else
     {
@@ -282,16 +244,16 @@ bits_image_fetch_bilinear_pixels (bits_image_t   *image,
     tl = tr = bl = br = 0;
 
     if (x1r && y1r)
-	tl = fetch_one (image, x1, y1);
+	tl = bits_image_fetch_alpha_pixel (image, x1, y1);
 
     if (x1r && y2r)
-	bl = fetch_one (image, x1, y2);
+	bl = bits_image_fetch_alpha_pixel (image, x1, y2);
 
     if (x2r && y1r)
-	tr = fetch_one (image, x2, y1);
+	tr = bits_image_fetch_alpha_pixel (image, x2, y1);
 
     if (x2r && y2r)
-	br = fetch_one (image, x2, y2);
+	br = bits_image_fetch_alpha_pixel (image, x2, y2);
     
     idistx = 256 - distx;
     idisty = 256 - disty;
@@ -355,7 +317,7 @@ bits_image_fetch_convolution_pixels (bits_image_t   *image,
 
 		if (f)
 		{
-		    uint32_t pixel = fetch_one (image, rx, ry);
+		    uint32_t pixel = bits_image_fetch_alpha_pixel (image, rx, ry);
 		    
 		    srtot += RED_8 (pixel) * f;
 		    sgtot += GREEN_8 (pixel) * f;
commit 6d1dfc3945917b507d40f1f3c1b1cf07858d18dd
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 08:44:40 2009 -0400

    Change bits_image_fetch_pixels_convolution() to fetch just one pixel.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 8d9ee4c..ee24791 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -177,14 +177,6 @@ bits_image_fetch_alpha_pixels (bits_image_t *image,
     }
 }
 
-static void
-bits_image_fetch_pixels_src_clip (bits_image_t *image,
-                                  uint32_t *    buffer,
-                                  int           n_pixels)
-{
-    bits_image_fetch_alpha_pixels (image, buffer, n_pixels);
-}
-
 static force_inline pixman_bool_t
 repeat (pixman_repeat_t repeat, int size, int *coord)
 {
@@ -324,128 +316,72 @@ bits_image_fetch_bilinear_pixels (bits_image_t   *image,
 /* Buffer contains list of fixed-point coordinates on input,
  * a list of pixels on output
  */
-static void
-bits_image_fetch_convolution_pixels (bits_image_t *image,
-                                     uint32_t *    buffer,
-                                     int           n_pixels)
+static uint32_t
+bits_image_fetch_convolution_pixels (bits_image_t   *image,
+				     pixman_fixed_t  x,
+				     pixman_fixed_t  y)
 {
-    uint32_t tmp_pixels_stack[N_TMP_PIXELS * 2]; /* Two coordinates per pixel */
-    uint32_t *tmp_pixels = tmp_pixels_stack;
     pixman_fixed_t *params = image->common.filter_params;
     int x_off = (params[0] - pixman_fixed_1) >> 1;
     int y_off = (params[1] - pixman_fixed_1) >> 1;
-    int n_tmp_pixels;
-    int32_t *coords;
-    int32_t *t;
-    uint32_t *u;
-    int i;
-    int max_n_kernels;
-
     int32_t cwidth = pixman_fixed_to_int (params[0]);
     int32_t cheight = pixman_fixed_to_int (params[1]);
-    int kernel_size = cwidth * cheight;
+    int32_t srtot, sgtot, sbtot, satot;
+    int32_t i, j, x1, x2, y1, y2;
+    pixman_repeat_t repeat_mode = image->common.repeat;
+    int width = image->width;
+    int height = image->height;
 
     params += 2;
 
-    n_tmp_pixels = N_TMP_PIXELS;
-    if (kernel_size > n_tmp_pixels)
-    {
-	/* Two coordinates per pixel */
-	tmp_pixels = malloc (kernel_size * 2 * sizeof (uint32_t));
-	n_tmp_pixels = kernel_size;
-
-	if (!tmp_pixels)
-	{
-	    /* We ignore out-of-memory during rendering */
-	    return;
-	}
-    }
+    x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
+    y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
+    x2 = x1 + cwidth;
+    y2 = y1 + cheight;
 
-    max_n_kernels = n_tmp_pixels / kernel_size;
-
-    i = 0;
-    coords = (int32_t *)buffer;
-    while (i < n_pixels)
+    srtot = sgtot = sbtot = satot = 0;
+    
+    for (i = y1; i < y2; ++i)
     {
-	int n_kernels = MIN (max_n_kernels, (n_pixels - i));
-	pixman_repeat_t repeat_mode = image->common.repeat;
-	int width = image->width;
-	int height = image->height;
-	int j;
-
-	t = (int32_t *)tmp_pixels;
-	for (j = 0; j < n_kernels; ++j)
+	for (j = x1; j < x2; ++j)
 	{
-	    int32_t x, y, x1, x2, y1, y2;
-
-	    /* Subtract pixman_fixed_e to ensure that 0.5 rounds to 0, not 1 */
-	    x1 = pixman_fixed_to_int (coords[0] - pixman_fixed_e - x_off);
-	    y1 = pixman_fixed_to_int (coords[1] - pixman_fixed_e - y_off);
-	    x2 = x1 + cwidth;
-	    y2 = y1 + cheight;
-
-	    for (y = y1; y < y2; ++y)
+	    int rx = i;
+	    int ry = j;
+	    
+	    if (repeat (repeat_mode, width, &rx)	&&
+		repeat (repeat_mode, height, &ry))
 	    {
-		for (x = x1; x < x2; ++x)
-		{
-		    int rx = x;
-		    int ry = y;
-
-		    repeat (repeat_mode, width, &rx);
-		    repeat (repeat_mode, height, &ry);
+		pixman_fixed_t f = *params;
 
-		    *t++ = rx;
-		    *t++ = ry;
-		}
-	    }
-
-	    coords += 2;
-	}
-
-	bits_image_fetch_pixels_src_clip (image, tmp_pixels, n_kernels * kernel_size);
-
-	u = tmp_pixels;
-	for (j = 0; j < n_kernels; ++j)
-	{
-	    int32_t srtot, sgtot, sbtot, satot;
-	    pixman_fixed_t *p = params;
-	    int k;
-
-	    srtot = sgtot = sbtot = satot = 0;
-
-	    for (k = 0; k < kernel_size; ++k)
-	    {
-		pixman_fixed_t f = *p++;
 		if (f)
 		{
-		    uint32_t c = *u++;
-
-		    srtot += RED_8 (c) * f;
-		    sgtot += GREEN_8 (c) * f;
-		    sbtot += BLUE_8 (c) * f;
-		    satot += ALPHA_8 (c) * f;
+		    uint32_t pixel = fetch_one (image, rx, ry);
+		    
+		    srtot += RED_8 (pixel) * f;
+		    sgtot += GREEN_8 (pixel) * f;
+		    sbtot += BLUE_8 (pixel) * f;
+		    satot += ALPHA_8 (pixel) * f;
 		}
 	    }
 
-	    satot >>= 16;
-	    srtot >>= 16;
-	    sgtot >>= 16;
-	    sbtot >>= 16;
-
-	    satot = CLIP (satot, 0, 0xff);
-	    srtot = CLIP (srtot, 0, 0xff);
-	    sgtot = CLIP (sgtot, 0, 0xff);
-	    sbtot = CLIP (sbtot, 0, 0xff);
-
-	    buffer[i++] = ((satot << 24) |
-	                   (srtot << 16) |
-	                   (sgtot <<  8) |
-	                   (sbtot       ));
+	    params++;
 	}
     }
 
-    if (tmp_pixels != tmp_pixels_stack)
-	free (tmp_pixels);
+    satot >>= 16;
+    srtot >>= 16;
+    sgtot >>= 16;
+    sbtot >>= 16;
+    
+    satot = CLIP (satot, 0, 0xff);
+    srtot = CLIP (srtot, 0, 0xff);
+    sgtot = CLIP (sgtot, 0, 0xff);
+    sbtot = CLIP (sbtot, 0, 0xff);
+
+    return ((satot << 24) |
+	    (srtot << 16) |
+	    (sgtot <<  8) |
+	    (sbtot       ));
 }
 
 static inline uint32_t
@@ -472,7 +408,7 @@ bits_image_fetch_filtered (bits_image_t *image,
 	break;
 
     case PIXMAN_FILTER_CONVOLUTION:
-	bits_image_fetch_convolution_pixels (image, pixel, 1);
+	return bits_image_fetch_convolution_pixels (image, x, y);
 	break;
     }
 
commit b3f849f74f848c407afda1be15b966e1d6eda745
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 08:33:28 2009 -0400

    Change bits_image_fetch_bilinear_pixels() to fetch one pixel at a time.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 3c48504..8d9ee4c 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -257,109 +257,68 @@ bits_image_fetch_nearest_pixels (bits_image_t *image,
 /* Buffer contains list of fixed-point coordinates on input,
  * a list of pixels on output
  */
-static void
-bits_image_fetch_bilinear_pixels (bits_image_t *image,
-                                  uint32_t *    buffer,
-                                  int           n_pixels)
+static uint32_t
+bits_image_fetch_bilinear_pixels (bits_image_t   *image,
+				  pixman_fixed_t x,
+				  pixman_fixed_t y)
 {
-/* (Four pixels * two coordinates) per pixel */
-#define N_TEMPS         (N_TMP_PIXELS * 8)
-#define N_DISTS         (N_TMP_PIXELS * 2)
-
-    uint32_t temps[N_TEMPS];
-    int32_t dists[N_DISTS];
     pixman_repeat_t repeat_mode = image->common.repeat;
     int width = image->width;
     int height = image->height;
-    int32_t *coords;
-    int i;
-
-    i = 0;
-    coords = (int32_t *)buffer;
-    while (i < n_pixels)
-    {
-	int tmp_n_pixels = MIN (N_TMP_PIXELS, n_pixels - i);
-	int32_t distx, disty;
-	uint32_t *u;
-	int32_t *t, *d;
-	int j;
-
-	t = (int32_t *)temps;
-	d = dists;
-	for (j = 0; j < tmp_n_pixels; ++j)
-	{
-	    int32_t x1, y1, x2, y2;
-
-	    x1 = coords[0] - pixman_fixed_1 / 2;
-	    y1 = coords[1] - pixman_fixed_1 / 2;
-
-	    distx = (x1 >> 8) & 0xff;
-	    disty = (y1 >> 8) & 0xff;
+    pixman_bool_t x1r, y1r, x2r, y2r;
+    int x1, y1, x2, y2;
+    uint32_t tl, tr, bl, br, r;
+    int32_t distx, disty, idistx, idisty;
+    uint32_t ft, fb;
 
-	    x1 >>= 16;
-	    y1 >>= 16;
-	    x2 = x1 + 1;
-	    y2 = y1 + 1;
+    x1 = x - pixman_fixed_1 / 2;
+    y1 = y - pixman_fixed_1 / 2;
 
-	    repeat (repeat_mode, width, &x1);
-	    repeat (repeat_mode, height, &y1);
-	    repeat (repeat_mode, width, &x2);
-	    repeat (repeat_mode, height, &y2);
+    distx = (x1 >> 8) & 0xff;
+    disty = (y1 >> 8) & 0xff;
 
-	    *t++ = x1;
-	    *t++ = y1;
-	    *t++ = x2;
-	    *t++ = y1;
-	    *t++ = x1;
-	    *t++ = y2;
-	    *t++ = x2;
-	    *t++ = y2;
+    x1 = pixman_fixed_to_int (x1);
+    y1 = pixman_fixed_to_int (y1);
+    x2 = x1 + 1;
+    y2 = y1 + 1;
 
-	    *d++ = distx;
-	    *d++ = disty;
-
-	    coords += 2;
-	}
+    x1r = repeat (repeat_mode, width, &x1);
+    y1r = repeat (repeat_mode, height, &y1);
+    x2r = repeat (repeat_mode, width, &x2);
+    y2r = repeat (repeat_mode, height, &y2);
 
-	bits_image_fetch_pixels_src_clip (image, temps, tmp_n_pixels * 4);
+    tl = tr = bl = br = 0;
 
-	u = (uint32_t *)temps;
-	d = dists;
-	for (j = 0; j < tmp_n_pixels; ++j)
-	{
-	    uint32_t tl, tr, bl, br, r;
-	    int32_t idistx, idisty;
-	    uint32_t ft, fb;
+    if (x1r && y1r)
+	tl = fetch_one (image, x1, y1);
 
-	    tl = *u++;
-	    tr = *u++;
-	    bl = *u++;
-	    br = *u++;
+    if (x1r && y2r)
+	bl = fetch_one (image, x1, y2);
 
-	    distx = *d++;
-	    disty = *d++;
+    if (x2r && y1r)
+	tr = fetch_one (image, x2, y1);
 
-	    idistx = 256 - distx;
-	    idisty = 256 - disty;
+    if (x2r && y2r)
+	br = fetch_one (image, x2, y2);
+    
+    idistx = 256 - distx;
+    idisty = 256 - disty;
 
 #define GET8(v, i)   ((uint16_t) (uint8_t) ((v) >> i))
-
-	    ft = GET8 (tl, 0) * idistx + GET8 (tr, 0) * distx;
-	    fb = GET8 (bl, 0) * idistx + GET8 (br, 0) * distx;
-	    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
-	    ft = GET8 (tl, 8) * idistx + GET8 (tr, 8) * distx;
-	    fb = GET8 (bl, 8) * idistx + GET8 (br, 8) * distx;
-	    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
-	    ft = GET8 (tl, 16) * idistx + GET8 (tr, 16) * distx;
-	    fb = GET8 (bl, 16) * idistx + GET8 (br, 16) * distx;
-	    r |= (((ft * idisty + fb * disty)) & 0xff0000);
-	    ft = GET8 (tl, 24) * idistx + GET8 (tr, 24) * distx;
-	    fb = GET8 (bl, 24) * idistx + GET8 (br, 24) * distx;
-	    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
-
-	    buffer[i++] = r;
-	}
-    }
+    ft = GET8 (tl, 0) * idistx + GET8 (tr, 0) * distx;
+    fb = GET8 (bl, 0) * idistx + GET8 (br, 0) * distx;
+    r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+    ft = GET8 (tl, 8) * idistx + GET8 (tr, 8) * distx;
+    fb = GET8 (bl, 8) * idistx + GET8 (br, 8) * distx;
+    r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+    ft = GET8 (tl, 16) * idistx + GET8 (tr, 16) * distx;
+    fb = GET8 (bl, 16) * idistx + GET8 (br, 16) * distx;
+    r |= (((ft * idisty + fb * disty)) & 0xff0000);
+    ft = GET8 (tl, 24) * idistx + GET8 (tr, 24) * distx;
+    fb = GET8 (bl, 24) * idistx + GET8 (br, 24) * distx;
+    r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+    
+    return r;
 }
 
 /* Buffer contains list of fixed-point coordinates on input,
@@ -509,7 +468,7 @@ bits_image_fetch_filtered (bits_image_t *image,
     case PIXMAN_FILTER_BILINEAR:
     case PIXMAN_FILTER_GOOD:
     case PIXMAN_FILTER_BEST:
-	bits_image_fetch_bilinear_pixels (image, pixel, 1);
+	return bits_image_fetch_bilinear_pixels (image, x, y);
 	break;
 
     case PIXMAN_FILTER_CONVOLUTION:
commit a37383a2c646ee10ebe36d03df6bd1c0f8a75052
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 08:03:44 2009 -0400

    Make the repeat routine work on only one coordinate at a time.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 6e9a921..3c48504 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -186,45 +186,29 @@ bits_image_fetch_pixels_src_clip (bits_image_t *image,
 }
 
 static force_inline pixman_bool_t
-repeat (pixman_repeat_t repeat,
-        int             width,
-        int             height,
-        int *           x,
-        int *           y)
+repeat (pixman_repeat_t repeat, int size, int *coord)
 {
     switch (repeat)
     {
     case PIXMAN_REPEAT_NORMAL:
-	*x = MOD (*x, width);
-	*y = MOD (*y, height);
+	*coord = MOD (*coord, size);
 	break;
 
     case PIXMAN_REPEAT_PAD:
-	*x = CLIP (*x, 0, width - 1);
-	*y = CLIP (*y, 0, height - 1);
+	*coord = CLIP (*coord, 0, size - 1);
 	break;
 
     case PIXMAN_REPEAT_REFLECT:
-	*x = MOD (*x, width * 2);
-	*y = MOD (*y, height * 2);
+	*coord = MOD (*coord, size * 2);
 
-	if (*x >= width)
-	    *x = width * 2 - *x - 1;
-
-	if (*y >= height)
-	    *y = height * 2 - *y - 1;
+	if (*coord >= size)
+	    *coord = size * 2 - *coord - 1;
 	break;
 
     case PIXMAN_REPEAT_NONE:
-	if (*x < 0 || *x >= width)
-	{
-	    *x = 0xffffffff;
-	    return FALSE;
-	}
-
-	if (*y < 0 || *y >= height)
+	if (*coord < 0 || *coord >= size)
 	{
-	    *y = 0xffffffff;
+	    *coord = 0xffffffff;
 	    return FALSE;
 	}
 	break;
@@ -257,10 +241,8 @@ bits_image_fetch_nearest_pixels (bits_image_t *image,
     int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
     int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
 
-    if (repeat (image->common.repeat,
-		image->width,
-		image->height,
-		&x0, &y0))
+    if (repeat (image->common.repeat, image->width, &x0) &&
+	repeat (image->common.repeat, image->height, &y0))
     {
 	return fetch_one (image, x0, y0);
     }
@@ -319,8 +301,10 @@ bits_image_fetch_bilinear_pixels (bits_image_t *image,
 	    x2 = x1 + 1;
 	    y2 = y1 + 1;
 
-	    repeat (repeat_mode, width, height, &x1, &y1);
-	    repeat (repeat_mode, width, height, &x2, &y2);
+	    repeat (repeat_mode, width, &x1);
+	    repeat (repeat_mode, height, &y1);
+	    repeat (repeat_mode, width, &x2);
+	    repeat (repeat_mode, height, &y2);
 
 	    *t++ = x1;
 	    *t++ = y1;
@@ -448,7 +432,8 @@ bits_image_fetch_convolution_pixels (bits_image_t *image,
 		    int rx = x;
 		    int ry = y;
 
-		    repeat (repeat_mode, width, height, &rx, &ry);
+		    repeat (repeat_mode, width, &rx);
+		    repeat (repeat_mode, height, &ry);
 
 		    *t++ = rx;
 		    *t++ = ry;
commit a4f3fd3b2592b1b4791075187016ad444c2d60d4
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 07:55:27 2009 -0400

    Make bits_image_fetch_nearest() return one pixel.
    
    Previously it would work on a buffer of coordinates.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 6c3e6e7..6e9a921 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -185,7 +185,7 @@ bits_image_fetch_pixels_src_clip (bits_image_t *image,
     bits_image_fetch_alpha_pixels (image, buffer, n_pixels);
 }
 
-static force_inline void
+static force_inline pixman_bool_t
 repeat (pixman_repeat_t repeat,
         int             width,
         int             height,
@@ -217,43 +217,57 @@ repeat (pixman_repeat_t repeat,
 
     case PIXMAN_REPEAT_NONE:
 	if (*x < 0 || *x >= width)
+	{
 	    *x = 0xffffffff;
+	    return FALSE;
+	}
 
 	if (*y < 0 || *y >= height)
+	{
 	    *y = 0xffffffff;
+	    return FALSE;
+	}
 	break;
     }
+
+    return TRUE;
+}
+
+static uint32_t
+fetch_one (bits_image_t *image, int x, int y)
+{
+    uint32_t pixel[2];
+
+    pixel[0] = x;
+    pixel[1] = y;
+
+    bits_image_fetch_alpha_pixels (image, pixel, 1);
+
+    return pixel[0];
 }
 
 /* Buffer contains list of fixed-point coordinates on input,
  * a list of pixels on output
  */
-static void
+static uint32_t
 bits_image_fetch_nearest_pixels (bits_image_t *image,
-                                 uint32_t *    buffer,
-                                 int           n_pixels)
+				 pixman_fixed_t x,
+				 pixman_fixed_t y)
 {
-    pixman_repeat_t repeat_mode = image->common.repeat;
-    int width = image->width;
-    int height = image->height;
-    int i;
+    int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
+    int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
 
-    for (i = 0; i < 2 * n_pixels; i += 2)
+    if (repeat (image->common.repeat,
+		image->width,
+		image->height,
+		&x0, &y0))
     {
-	int32_t *coords = (int32_t *)buffer;
-	int32_t x, y;
-
-	/* Subtract pixman_fixed_e to ensure that 0.5 rounds to 0, not 1 */
-	x = pixman_fixed_to_int (coords[i] - pixman_fixed_e);
-	y = pixman_fixed_to_int (coords[i + 1] - pixman_fixed_e);
-
-	repeat (repeat_mode, width, height, &x, &y);
-
-	coords[i] = x;
-	coords[i + 1] = y;
+	return fetch_one (image, x0, y0);
+    }
+    else
+    {
+	return 0;
     }
-
-    bits_image_fetch_pixels_src_clip (image, buffer, n_pixels);
 }
 
 #define N_TMP_PIXELS    (256)
@@ -504,7 +518,7 @@ bits_image_fetch_filtered (bits_image_t *image,
     {
     case PIXMAN_FILTER_NEAREST:
     case PIXMAN_FILTER_FAST:
-	bits_image_fetch_nearest_pixels (image, pixel, 1);
+	return bits_image_fetch_nearest_pixels (image, x, y);
 	break;
 
     case PIXMAN_FILTER_BILINEAR:
commit f382865ebe5e1e8d4b5299b908dab9b719fcb8ec
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jul 28 07:42:34 2009 -0400

    Change bits_image_fetch_transformed() to work one pixel at a time.
    
    Previously, it would generate a buffer of coordinates, then pass that
    off to a pixel fetcher, but this caused a large performance regression
    with the swfdec-fill-rate-2xfsaa cairo trace.
    
    This is the first step towards fixing that.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index b57299c..6c3e6e7 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -490,49 +490,54 @@ bits_image_fetch_convolution_pixels (bits_image_t *image,
 	free (tmp_pixels);
 }
 
-static void
+static inline uint32_t
 bits_image_fetch_filtered (bits_image_t *image,
-                           uint32_t *    buffer,
-                           int           n_pixels)
+			   pixman_fixed_t x,
+			   pixman_fixed_t y)
 {
+    uint32_t pixel[2];
+
+    pixel[0] = x;
+    pixel[1] = y;
+    
     switch (image->common.filter)
     {
     case PIXMAN_FILTER_NEAREST:
     case PIXMAN_FILTER_FAST:
-	bits_image_fetch_nearest_pixels (image, buffer, n_pixels);
+	bits_image_fetch_nearest_pixels (image, pixel, 1);
 	break;
 
     case PIXMAN_FILTER_BILINEAR:
     case PIXMAN_FILTER_GOOD:
     case PIXMAN_FILTER_BEST:
-	bits_image_fetch_bilinear_pixels (image, buffer, n_pixels);
+	bits_image_fetch_bilinear_pixels (image, pixel, 1);
 	break;
 
     case PIXMAN_FILTER_CONVOLUTION:
-	bits_image_fetch_convolution_pixels (image, buffer, n_pixels);
+	bits_image_fetch_convolution_pixels (image, pixel, 1);
 	break;
     }
+
+    return pixel[0];
 }
 
 static void
 bits_image_fetch_transformed (pixman_image_t * image,
-                              int              x,
-                              int              y,
+                              int              offset,
+                              int              line,
                               int              width,
                               uint32_t *       buffer,
                               const uint32_t * mask,
                               uint32_t         mask_bits)
 {
-    pixman_bool_t affine = TRUE;
-    uint32_t tmp_buffer[2 * N_TMP_PIXELS];
-    pixman_vector_t unit;
+    pixman_fixed_t x, y, w;
+    pixman_fixed_t ux, uy, uw;
     pixman_vector_t v;
-    int32_t *coords;
     int i;
 
     /* reference point is the center of the pixel */
-    v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
-    v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
+    v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
+    v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
     /* when using convolution filters or PIXMAN_REPEAT_PAD one
@@ -542,69 +547,50 @@ bits_image_fetch_transformed (pixman_image_t * image,
 	if (!pixman_transform_point_3d (image->common.transform, &v))
 	    return;
 
-	unit.vector[0] = image->common.transform->matrix[0][0];
-	unit.vector[1] = image->common.transform->matrix[1][0];
-	unit.vector[2] = image->common.transform->matrix[2][0];
-
-	affine = (v.vector[2] == pixman_fixed_1 && unit.vector[2] == 0);
+	ux = image->common.transform->matrix[0][0];
+	uy = image->common.transform->matrix[1][0];
+	uw = image->common.transform->matrix[2][0];
     }
     else
     {
-	unit.vector[0] = pixman_fixed_1;
-	unit.vector[1] = 0;
-	unit.vector[2] = 0;
+	ux = pixman_fixed_1;
+	uy = 0;
+	uw = 0;
     }
 
-    i = 0;
-    while (i < width)
-    {
-	int n_pixels = MIN (N_TMP_PIXELS, width - i);
-	int j;
+    x = v.vector[0];
+    y = v.vector[1];
+    w = v.vector[2];
 
-	coords = (int32_t *)tmp_buffer;
+    if (w == pixman_fixed_1 && uw == 0)
+    {
+	for (i = 0; i < width; ++i)
+	{
+	    if (!mask || (mask[i] & mask_bits))
+		buffer[i] = bits_image_fetch_filtered (&image->bits, x, y);
 
-	for (j = 0; j < n_pixels; ++j)
+	    x += ux;
+	    y += uy;
+	}
+    }
+    else
+    {
+	for (i = 0; i < width; ++i)
 	{
-	    if (affine)
-	    {
-		coords[0] = v.vector[0];
-		coords[1] = v.vector[1];
-	    }
-	    else
+	    pixman_fixed_t x0, y0;
+	
+	    if (!mask || (mask[i] & mask_bits))
 	    {
-		pixman_fixed_48_16_t div;
-
-		div = ((pixman_fixed_48_16_t)v.vector[0] << 16) / v.vector[2];
-
-		if ((div >> 16) > 0x7fff)
-		    coords[0] = 0x7fffffff;
-		else if ((div >> 16) < 0x8000)
-		    coords[0] = 0x80000000;
-		else
-		    coords[0] = div;
-
-		div = ((pixman_fixed_48_16_t)v.vector[1] << 16) / v.vector[2];
-
-		if ((div >> 16) > 0x7fff)
-		    coords[1] = 0x7fffffff;
-		else if ((div >> 16) < 0x8000)
-		    coords[1] = 0x8000000;
-		else
-		    coords[1] = div;
-
-		v.vector[2] += unit.vector[2];
+		x0 = ((pixman_fixed_48_16_t)x << 16) / w;
+		y0 = ((pixman_fixed_48_16_t)y << 16) / w;
+		
+		buffer[i] = bits_image_fetch_filtered (&image->bits, x0, y0);
 	    }
-
-	    coords += 2;
-
-	    v.vector[0] += unit.vector[0];
-	    v.vector[1] += unit.vector[1];
+	    
+	    x += ux;
+	    y += uy;
+	    w += uw;
 	}
-
-	bits_image_fetch_filtered (&image->bits, tmp_buffer, n_pixels);
-
-	for (j = 0; j < n_pixels; ++j)
-	    buffer[i++] = tmp_buffer[j];
     }
 }
 


More information about the xorg-commit mailing list