Home | History | Annotate | Download | only in pixman
      1 /*
      2  * Copyright  2000 Keith Packard, member of The XFree86 Project, Inc.
      3  *             2005 Lars Knoll & Zack Rusin, Trolltech
      4  *             2008 Aaron Plattner, NVIDIA Corporation
      5  * Copyright  2000 SuSE, Inc.
      6  * Copyright  2007, 2009 Red Hat, Inc.
      7  * Copyright  2008 Andr Tupinamb <andrelrt (at) gmail.com>
      8  *
      9  * Permission to use, copy, modify, distribute, and sell this software and its
     10  * documentation for any purpose is hereby granted without fee, provided that
     11  * the above copyright notice appear in all copies and that both that
     12  * copyright notice and this permission notice appear in supporting
     13  * documentation, and that the name of Keith Packard not be used in
     14  * advertising or publicity pertaining to distribution of the software without
     15  * specific, written prior permission.  Keith Packard makes no
     16  * representations about the suitability of this software for any purpose.  It
     17  * is provided "as is" without express or implied warranty.
     18  *
     19  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
     20  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
     21  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
     22  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     23  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
     24  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     25  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     26  * SOFTWARE.
     27  */
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include <config.h>
     31 #endif
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include <string.h>
     35 #include "pixman-private.h"
     36 #include "pixman-combine32.h"
     37 #include "pixman-inlines.h"
     38 
     39 static uint32_t *
     40 _pixman_image_get_scanline_generic_float (pixman_iter_t * iter,
     41 					  const uint32_t *mask)
     42 {
     43     pixman_iter_get_scanline_t fetch_32 = iter->data;
     44     uint32_t *buffer = iter->buffer;
     45 
     46     fetch_32 (iter, NULL);
     47 
     48     pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
     49 
     50     return iter->buffer;
     51 }
     52 
     53 /* Fetch functions */
     54 
     55 static force_inline uint32_t
     56 fetch_pixel_no_alpha (bits_image_t *image,
     57 		      int x, int y, pixman_bool_t check_bounds)
     58 {
     59     if (check_bounds &&
     60 	(x < 0 || x >= image->width || y < 0 || y >= image->height))
     61     {
     62 	return 0;
     63     }
     64 
     65     return image->fetch_pixel_32 (image, x, y);
     66 }
     67 
     68 typedef uint32_t (* get_pixel_t) (bits_image_t *image,
     69 				  int x, int y, pixman_bool_t check_bounds);
     70 
     71 static force_inline uint32_t
     72 bits_image_fetch_pixel_nearest (bits_image_t   *image,
     73 				pixman_fixed_t  x,
     74 				pixman_fixed_t  y,
     75 				get_pixel_t	get_pixel)
     76 {
     77     int x0 = pixman_fixed_to_int (x - pixman_fixed_e);
     78     int y0 = pixman_fixed_to_int (y - pixman_fixed_e);
     79 
     80     if (image->common.repeat != PIXMAN_REPEAT_NONE)
     81     {
     82 	repeat (image->common.repeat, &x0, image->width);
     83 	repeat (image->common.repeat, &y0, image->height);
     84 
     85 	return get_pixel (image, x0, y0, FALSE);
     86     }
     87     else
     88     {
     89 	return get_pixel (image, x0, y0, TRUE);
     90     }
     91 }
     92 
     93 static force_inline uint32_t
     94 bits_image_fetch_pixel_bilinear (bits_image_t   *image,
     95 				 pixman_fixed_t  x,
     96 				 pixman_fixed_t  y,
     97 				 get_pixel_t	 get_pixel)
     98 {
     99     pixman_repeat_t repeat_mode = image->common.repeat;
    100     int width = image->width;
    101     int height = image->height;
    102     int x1, y1, x2, y2;
    103     uint32_t tl, tr, bl, br;
    104     int32_t distx, disty;
    105 
    106     x1 = x - pixman_fixed_1 / 2;
    107     y1 = y - pixman_fixed_1 / 2;
    108 
    109     distx = pixman_fixed_to_bilinear_weight (x1);
    110     disty = pixman_fixed_to_bilinear_weight (y1);
    111 
    112     x1 = pixman_fixed_to_int (x1);
    113     y1 = pixman_fixed_to_int (y1);
    114     x2 = x1 + 1;
    115     y2 = y1 + 1;
    116 
    117     if (repeat_mode != PIXMAN_REPEAT_NONE)
    118     {
    119 	repeat (repeat_mode, &x1, width);
    120 	repeat (repeat_mode, &y1, height);
    121 	repeat (repeat_mode, &x2, width);
    122 	repeat (repeat_mode, &y2, height);
    123 
    124 	tl = get_pixel (image, x1, y1, FALSE);
    125 	bl = get_pixel (image, x1, y2, FALSE);
    126 	tr = get_pixel (image, x2, y1, FALSE);
    127 	br = get_pixel (image, x2, y2, FALSE);
    128     }
    129     else
    130     {
    131 	tl = get_pixel (image, x1, y1, TRUE);
    132 	tr = get_pixel (image, x2, y1, TRUE);
    133 	bl = get_pixel (image, x1, y2, TRUE);
    134 	br = get_pixel (image, x2, y2, TRUE);
    135     }
    136 
    137     return bilinear_interpolation (tl, tr, bl, br, distx, disty);
    138 }
    139 
    140 static uint32_t *
    141 bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
    142 					  const uint32_t *mask)
    143 {
    144 
    145     pixman_image_t * ima = iter->image;
    146     int              offset = iter->x;
    147     int              line = iter->y++;
    148     int              width = iter->width;
    149     uint32_t *       buffer = iter->buffer;
    150 
    151     bits_image_t *bits = &ima->bits;
    152     pixman_fixed_t x_top, x_bottom, x;
    153     pixman_fixed_t ux_top, ux_bottom, ux;
    154     pixman_vector_t v;
    155     uint32_t top_mask, bottom_mask;
    156     uint32_t *top_row;
    157     uint32_t *bottom_row;
    158     uint32_t *end;
    159     uint32_t zero[2] = { 0, 0 };
    160     uint32_t one = 1;
    161     int y, y1, y2;
    162     int disty;
    163     int mask_inc;
    164     int w;
    165 
    166     /* reference point is the center of the pixel */
    167     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
    168     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
    169     v.vector[2] = pixman_fixed_1;
    170 
    171     if (!pixman_transform_point_3d (bits->common.transform, &v))
    172 	return iter->buffer;
    173 
    174     ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
    175     x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
    176 
    177     y = v.vector[1] - pixman_fixed_1/2;
    178     disty = pixman_fixed_to_bilinear_weight (y);
    179 
    180     /* Load the pointers to the first and second lines from the source
    181      * image that bilinear code must read.
    182      *
    183      * The main trick in this code is about the check if any line are
    184      * outside of the image;
    185      *
    186      * When I realize that a line (any one) is outside, I change
    187      * the pointer to a dummy area with zeros. Once I change this, I
    188      * must be sure the pointer will not change, so I set the
    189      * variables to each pointer increments inside the loop.
    190      */
    191     y1 = pixman_fixed_to_int (y);
    192     y2 = y1 + 1;
    193 
    194     if (y1 < 0 || y1 >= bits->height)
    195     {
    196 	top_row = zero;
    197 	x_top = 0;
    198 	ux_top = 0;
    199     }
    200     else
    201     {
    202 	top_row = bits->bits + y1 * bits->rowstride;
    203 	x_top = x;
    204 	ux_top = ux;
    205     }
    206 
    207     if (y2 < 0 || y2 >= bits->height)
    208     {
    209 	bottom_row = zero;
    210 	x_bottom = 0;
    211 	ux_bottom = 0;
    212     }
    213     else
    214     {
    215 	bottom_row = bits->bits + y2 * bits->rowstride;
    216 	x_bottom = x;
    217 	ux_bottom = ux;
    218     }
    219 
    220     /* Instead of checking whether the operation uses the mast in
    221      * each loop iteration, verify this only once and prepare the
    222      * variables to make the code smaller inside the loop.
    223      */
    224     if (!mask)
    225     {
    226         mask_inc = 0;
    227         mask = &one;
    228     }
    229     else
    230     {
    231         /* If have a mask, prepare the variables to check it */
    232         mask_inc = 1;
    233     }
    234 
    235     /* If both are zero, then the whole thing is zero */
    236     if (top_row == zero && bottom_row == zero)
    237     {
    238 	memset (buffer, 0, width * sizeof (uint32_t));
    239 	return iter->buffer;
    240     }
    241     else if (bits->format == PIXMAN_x8r8g8b8)
    242     {
    243 	if (top_row == zero)
    244 	{
    245 	    top_mask = 0;
    246 	    bottom_mask = 0xff000000;
    247 	}
    248 	else if (bottom_row == zero)
    249 	{
    250 	    top_mask = 0xff000000;
    251 	    bottom_mask = 0;
    252 	}
    253 	else
    254 	{
    255 	    top_mask = 0xff000000;
    256 	    bottom_mask = 0xff000000;
    257 	}
    258     }
    259     else
    260     {
    261 	top_mask = 0;
    262 	bottom_mask = 0;
    263     }
    264 
    265     end = buffer + width;
    266 
    267     /* Zero fill to the left of the image */
    268     while (buffer < end && x < pixman_fixed_minus_1)
    269     {
    270 	*buffer++ = 0;
    271 	x += ux;
    272 	x_top += ux_top;
    273 	x_bottom += ux_bottom;
    274 	mask += mask_inc;
    275     }
    276 
    277     /* Left edge
    278      */
    279     while (buffer < end && x < 0)
    280     {
    281 	uint32_t tr, br;
    282 	int32_t distx;
    283 
    284 	tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask;
    285 	br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
    286 
    287 	distx = pixman_fixed_to_bilinear_weight (x);
    288 
    289 	*buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
    290 
    291 	x += ux;
    292 	x_top += ux_top;
    293 	x_bottom += ux_bottom;
    294 	mask += mask_inc;
    295     }
    296 
    297     /* Main part */
    298     w = pixman_int_to_fixed (bits->width - 1);
    299 
    300     while (buffer < end  &&  x < w)
    301     {
    302 	if (*mask)
    303 	{
    304 	    uint32_t tl, tr, bl, br;
    305 	    int32_t distx;
    306 
    307 	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
    308 	    tr = top_row [pixman_fixed_to_int (x_top) + 1] | top_mask;
    309 	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
    310 	    br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
    311 
    312 	    distx = pixman_fixed_to_bilinear_weight (x);
    313 
    314 	    *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
    315 	}
    316 
    317 	buffer++;
    318 	x += ux;
    319 	x_top += ux_top;
    320 	x_bottom += ux_bottom;
    321 	mask += mask_inc;
    322     }
    323 
    324     /* Right Edge */
    325     w = pixman_int_to_fixed (bits->width);
    326     while (buffer < end  &&  x < w)
    327     {
    328 	if (*mask)
    329 	{
    330 	    uint32_t tl, bl;
    331 	    int32_t distx;
    332 
    333 	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
    334 	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
    335 
    336 	    distx = pixman_fixed_to_bilinear_weight (x);
    337 
    338 	    *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
    339 	}
    340 
    341 	buffer++;
    342 	x += ux;
    343 	x_top += ux_top;
    344 	x_bottom += ux_bottom;
    345 	mask += mask_inc;
    346     }
    347 
    348     /* Zero fill to the left of the image */
    349     while (buffer < end)
    350 	*buffer++ = 0;
    351 
    352     return iter->buffer;
    353 }
    354 
    355 static force_inline uint32_t
    356 bits_image_fetch_pixel_convolution (bits_image_t   *image,
    357 				    pixman_fixed_t  x,
    358 				    pixman_fixed_t  y,
    359 				    get_pixel_t     get_pixel)
    360 {
    361     pixman_fixed_t *params = image->common.filter_params;
    362     int x_off = (params[0] - pixman_fixed_1) >> 1;
    363     int y_off = (params[1] - pixman_fixed_1) >> 1;
    364     int32_t cwidth = pixman_fixed_to_int (params[0]);
    365     int32_t cheight = pixman_fixed_to_int (params[1]);
    366     int32_t i, j, x1, x2, y1, y2;
    367     pixman_repeat_t repeat_mode = image->common.repeat;
    368     int width = image->width;
    369     int height = image->height;
    370     int srtot, sgtot, sbtot, satot;
    371 
    372     params += 2;
    373 
    374     x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
    375     y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
    376     x2 = x1 + cwidth;
    377     y2 = y1 + cheight;
    378 
    379     srtot = sgtot = sbtot = satot = 0;
    380 
    381     for (i = y1; i < y2; ++i)
    382     {
    383 	for (j = x1; j < x2; ++j)
    384 	{
    385 	    int rx = j;
    386 	    int ry = i;
    387 
    388 	    pixman_fixed_t f = *params;
    389 
    390 	    if (f)
    391 	    {
    392 		uint32_t pixel;
    393 
    394 		if (repeat_mode != PIXMAN_REPEAT_NONE)
    395 		{
    396 		    repeat (repeat_mode, &rx, width);
    397 		    repeat (repeat_mode, &ry, height);
    398 
    399 		    pixel = get_pixel (image, rx, ry, FALSE);
    400 		}
    401 		else
    402 		{
    403 		    pixel = get_pixel (image, rx, ry, TRUE);
    404 		}
    405 
    406 		srtot += (int)RED_8 (pixel) * f;
    407 		sgtot += (int)GREEN_8 (pixel) * f;
    408 		sbtot += (int)BLUE_8 (pixel) * f;
    409 		satot += (int)ALPHA_8 (pixel) * f;
    410 	    }
    411 
    412 	    params++;
    413 	}
    414     }
    415 
    416     satot = (satot + 0x8000) >> 16;
    417     srtot = (srtot + 0x8000) >> 16;
    418     sgtot = (sgtot + 0x8000) >> 16;
    419     sbtot = (sbtot + 0x8000) >> 16;
    420 
    421     satot = CLIP (satot, 0, 0xff);
    422     srtot = CLIP (srtot, 0, 0xff);
    423     sgtot = CLIP (sgtot, 0, 0xff);
    424     sbtot = CLIP (sbtot, 0, 0xff);
    425 
    426     return ((satot << 24) | (srtot << 16) | (sgtot <<  8) | (sbtot));
    427 }
    428 
    429 static uint32_t
    430 bits_image_fetch_pixel_separable_convolution (bits_image_t *image,
    431                                               pixman_fixed_t x,
    432                                               pixman_fixed_t y,
    433                                               get_pixel_t    get_pixel)
    434 {
    435     pixman_fixed_t *params = image->common.filter_params;
    436     pixman_repeat_t repeat_mode = image->common.repeat;
    437     int width = image->width;
    438     int height = image->height;
    439     int cwidth = pixman_fixed_to_int (params[0]);
    440     int cheight = pixman_fixed_to_int (params[1]);
    441     int x_phase_bits = pixman_fixed_to_int (params[2]);
    442     int y_phase_bits = pixman_fixed_to_int (params[3]);
    443     int x_phase_shift = 16 - x_phase_bits;
    444     int y_phase_shift = 16 - y_phase_bits;
    445     int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
    446     int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
    447     pixman_fixed_t *y_params;
    448     int srtot, sgtot, sbtot, satot;
    449     int32_t x1, x2, y1, y2;
    450     int32_t px, py;
    451     int i, j;
    452 
    453     /* Round x and y to the middle of the closest phase before continuing. This
    454      * ensures that the convolution matrix is aligned right, since it was
    455      * positioned relative to a particular phase (and not relative to whatever
    456      * exact fraction we happen to get here).
    457      */
    458     x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
    459     y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
    460 
    461     px = (x & 0xffff) >> x_phase_shift;
    462     py = (y & 0xffff) >> y_phase_shift;
    463 
    464     y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
    465 
    466     x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
    467     y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
    468     x2 = x1 + cwidth;
    469     y2 = y1 + cheight;
    470 
    471     srtot = sgtot = sbtot = satot = 0;
    472 
    473     for (i = y1; i < y2; ++i)
    474     {
    475         pixman_fixed_48_16_t fy = *y_params++;
    476         pixman_fixed_t *x_params = params + 4 + px * cwidth;
    477 
    478         if (fy)
    479         {
    480             for (j = x1; j < x2; ++j)
    481             {
    482                 pixman_fixed_t fx = *x_params++;
    483 		int rx = j;
    484 		int ry = i;
    485 
    486                 if (fx)
    487                 {
    488                     pixman_fixed_t f;
    489                     uint32_t pixel;
    490 
    491                     if (repeat_mode != PIXMAN_REPEAT_NONE)
    492                     {
    493                         repeat (repeat_mode, &rx, width);
    494                         repeat (repeat_mode, &ry, height);
    495 
    496                         pixel = get_pixel (image, rx, ry, FALSE);
    497                     }
    498                     else
    499                     {
    500                         pixel = get_pixel (image, rx, ry, TRUE);
    501 		    }
    502 
    503                     f = (fy * fx + 0x8000) >> 16;
    504 
    505                     srtot += (int)RED_8 (pixel) * f;
    506                     sgtot += (int)GREEN_8 (pixel) * f;
    507                     sbtot += (int)BLUE_8 (pixel) * f;
    508                     satot += (int)ALPHA_8 (pixel) * f;
    509                 }
    510             }
    511 	}
    512     }
    513 
    514     satot = (satot + 0x8000) >> 16;
    515     srtot = (srtot + 0x8000) >> 16;
    516     sgtot = (sgtot + 0x8000) >> 16;
    517     sbtot = (sbtot + 0x8000) >> 16;
    518 
    519     satot = CLIP (satot, 0, 0xff);
    520     srtot = CLIP (srtot, 0, 0xff);
    521     sgtot = CLIP (sgtot, 0, 0xff);
    522     sbtot = CLIP (sbtot, 0, 0xff);
    523 
    524     return ((satot << 24) | (srtot << 16) | (sgtot <<  8) | (sbtot));
    525 }
    526 
    527 static force_inline uint32_t
    528 bits_image_fetch_pixel_filtered (bits_image_t *image,
    529 				 pixman_fixed_t x,
    530 				 pixman_fixed_t y,
    531 				 get_pixel_t    get_pixel)
    532 {
    533     switch (image->common.filter)
    534     {
    535     case PIXMAN_FILTER_NEAREST:
    536     case PIXMAN_FILTER_FAST:
    537 	return bits_image_fetch_pixel_nearest (image, x, y, get_pixel);
    538 	break;
    539 
    540     case PIXMAN_FILTER_BILINEAR:
    541     case PIXMAN_FILTER_GOOD:
    542     case PIXMAN_FILTER_BEST:
    543 	return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel);
    544 	break;
    545 
    546     case PIXMAN_FILTER_CONVOLUTION:
    547 	return bits_image_fetch_pixel_convolution (image, x, y, get_pixel);
    548 	break;
    549 
    550     case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
    551         return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel);
    552         break;
    553 
    554     default:
    555         break;
    556     }
    557 
    558     return 0;
    559 }
    560 
    561 static uint32_t *
    562 bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
    563 				  const uint32_t * mask)
    564 {
    565     pixman_image_t *image  = iter->image;
    566     int             offset = iter->x;
    567     int             line   = iter->y++;
    568     int             width  = iter->width;
    569     uint32_t *      buffer = iter->buffer;
    570 
    571     pixman_fixed_t x, y;
    572     pixman_fixed_t ux, uy;
    573     pixman_vector_t v;
    574     int i;
    575 
    576     /* reference point is the center of the pixel */
    577     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
    578     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
    579     v.vector[2] = pixman_fixed_1;
    580 
    581     if (image->common.transform)
    582     {
    583 	if (!pixman_transform_point_3d (image->common.transform, &v))
    584 	    return iter->buffer;
    585 
    586 	ux = image->common.transform->matrix[0][0];
    587 	uy = image->common.transform->matrix[1][0];
    588     }
    589     else
    590     {
    591 	ux = pixman_fixed_1;
    592 	uy = 0;
    593     }
    594 
    595     x = v.vector[0];
    596     y = v.vector[1];
    597 
    598     for (i = 0; i < width; ++i)
    599     {
    600 	if (!mask || mask[i])
    601 	{
    602 	    buffer[i] = bits_image_fetch_pixel_filtered (
    603 		&image->bits, x, y, fetch_pixel_no_alpha);
    604 	}
    605 
    606 	x += ux;
    607 	y += uy;
    608     }
    609 
    610     return buffer;
    611 }
    612 
    613 /* General fetcher */
    614 static force_inline uint32_t
    615 fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
    616 {
    617     uint32_t pixel;
    618 
    619     if (check_bounds &&
    620 	(x < 0 || x >= image->width || y < 0 || y >= image->height))
    621     {
    622 	return 0;
    623     }
    624 
    625     pixel = image->fetch_pixel_32 (image, x, y);
    626 
    627     if (image->common.alpha_map)
    628     {
    629 	uint32_t pixel_a;
    630 
    631 	x -= image->common.alpha_origin_x;
    632 	y -= image->common.alpha_origin_y;
    633 
    634 	if (x < 0 || x >= image->common.alpha_map->width ||
    635 	    y < 0 || y >= image->common.alpha_map->height)
    636 	{
    637 	    pixel_a = 0;
    638 	}
    639 	else
    640 	{
    641 	    pixel_a = image->common.alpha_map->fetch_pixel_32 (
    642 		image->common.alpha_map, x, y);
    643 
    644 	    pixel_a = ALPHA_8 (pixel_a);
    645 	}
    646 
    647 	pixel &= 0x00ffffff;
    648 	pixel |= (pixel_a << 24);
    649     }
    650 
    651     return pixel;
    652 }
    653 
    654 static uint32_t *
    655 bits_image_fetch_general (pixman_iter_t  *iter,
    656 			  const uint32_t *mask)
    657 {
    658     pixman_image_t *image  = iter->image;
    659     int             offset = iter->x;
    660     int             line   = iter->y++;
    661     int             width  = iter->width;
    662     uint32_t *      buffer = iter->buffer;
    663 
    664     pixman_fixed_t x, y, w;
    665     pixman_fixed_t ux, uy, uw;
    666     pixman_vector_t v;
    667     int i;
    668 
    669     /* reference point is the center of the pixel */
    670     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
    671     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
    672     v.vector[2] = pixman_fixed_1;
    673 
    674     if (image->common.transform)
    675     {
    676 	if (!pixman_transform_point_3d (image->common.transform, &v))
    677 	    return buffer;
    678 
    679 	ux = image->common.transform->matrix[0][0];
    680 	uy = image->common.transform->matrix[1][0];
    681 	uw = image->common.transform->matrix[2][0];
    682     }
    683     else
    684     {
    685 	ux = pixman_fixed_1;
    686 	uy = 0;
    687 	uw = 0;
    688     }
    689 
    690     x = v.vector[0];
    691     y = v.vector[1];
    692     w = v.vector[2];
    693 
    694     for (i = 0; i < width; ++i)
    695     {
    696 	pixman_fixed_t x0, y0;
    697 
    698 	if (!mask || mask[i])
    699 	{
    700 	    if (w != 0)
    701 	    {
    702 		x0 = ((pixman_fixed_48_16_t)x << 16) / w;
    703 		y0 = ((pixman_fixed_48_16_t)y << 16) / w;
    704 	    }
    705 	    else
    706 	    {
    707 		x0 = 0;
    708 		y0 = 0;
    709 	    }
    710 
    711 	    buffer[i] = bits_image_fetch_pixel_filtered (
    712 		&image->bits, x0, y0, fetch_pixel_general);
    713 	}
    714 
    715 	x += ux;
    716 	y += uy;
    717 	w += uw;
    718     }
    719 
    720     return buffer;
    721 }
    722 
    723 typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
    724 
    725 static force_inline void
    726 bits_image_fetch_separable_convolution_affine (pixman_image_t * image,
    727 					       int              offset,
    728 					       int              line,
    729 					       int              width,
    730 					       uint32_t *       buffer,
    731 					       const uint32_t * mask,
    732 
    733 					       convert_pixel_t	convert_pixel,
    734 					       pixman_format_code_t	format,
    735 					       pixman_repeat_t	repeat_mode)
    736 {
    737     bits_image_t *bits = &image->bits;
    738     pixman_fixed_t *params = image->common.filter_params;
    739     int cwidth = pixman_fixed_to_int (params[0]);
    740     int cheight = pixman_fixed_to_int (params[1]);
    741     int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
    742     int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
    743     int x_phase_bits = pixman_fixed_to_int (params[2]);
    744     int y_phase_bits = pixman_fixed_to_int (params[3]);
    745     int x_phase_shift = 16 - x_phase_bits;
    746     int y_phase_shift = 16 - y_phase_bits;
    747     pixman_fixed_t vx, vy;
    748     pixman_fixed_t ux, uy;
    749     pixman_vector_t v;
    750     int k;
    751 
    752     /* reference point is the center of the pixel */
    753     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
    754     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
    755     v.vector[2] = pixman_fixed_1;
    756 
    757     if (!pixman_transform_point_3d (image->common.transform, &v))
    758 	return;
    759 
    760     ux = image->common.transform->matrix[0][0];
    761     uy = image->common.transform->matrix[1][0];
    762 
    763     vx = v.vector[0];
    764     vy = v.vector[1];
    765 
    766     for (k = 0; k < width; ++k)
    767     {
    768 	pixman_fixed_t *y_params;
    769 	int satot, srtot, sgtot, sbtot;
    770 	pixman_fixed_t x, y;
    771 	int32_t x1, x2, y1, y2;
    772 	int32_t px, py;
    773 	int i, j;
    774 
    775 	if (mask && !mask[k])
    776 	    goto next;
    777 
    778 	/* Round x and y to the middle of the closest phase before continuing. This
    779 	 * ensures that the convolution matrix is aligned right, since it was
    780 	 * positioned relative to a particular phase (and not relative to whatever
    781 	 * exact fraction we happen to get here).
    782 	 */
    783 	x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
    784 	y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
    785 
    786 	px = (x & 0xffff) >> x_phase_shift;
    787 	py = (y & 0xffff) >> y_phase_shift;
    788 
    789 	x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
    790 	y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
    791 	x2 = x1 + cwidth;
    792 	y2 = y1 + cheight;
    793 
    794 	satot = srtot = sgtot = sbtot = 0;
    795 
    796 	y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
    797 
    798 	for (i = y1; i < y2; ++i)
    799 	{
    800 	    pixman_fixed_t fy = *y_params++;
    801 
    802 	    if (fy)
    803 	    {
    804 		pixman_fixed_t *x_params = params + 4 + px * cwidth;
    805 
    806 		for (j = x1; j < x2; ++j)
    807 		{
    808 		    pixman_fixed_t fx = *x_params++;
    809 		    int rx = j;
    810 		    int ry = i;
    811 
    812 		    if (fx)
    813 		    {
    814 			pixman_fixed_t f;
    815 			uint32_t pixel, mask;
    816 			uint8_t *row;
    817 
    818 			mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
    819 
    820 			if (repeat_mode != PIXMAN_REPEAT_NONE)
    821 			{
    822 			    repeat (repeat_mode, &rx, bits->width);
    823 			    repeat (repeat_mode, &ry, bits->height);
    824 
    825 			    row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry;
    826 			    pixel = convert_pixel (row, rx) | mask;
    827 			}
    828 			else
    829 			{
    830 			    if (rx < 0 || ry < 0 || rx >= bits->width || ry >= bits->height)
    831 			    {
    832 				pixel = 0;
    833 			    }
    834 			    else
    835 			    {
    836 				row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry;
    837 				pixel = convert_pixel (row, rx) | mask;
    838 			    }
    839 			}
    840 
    841 			f = ((pixman_fixed_32_32_t)fx * fy + 0x8000) >> 16;
    842 			srtot += (int)RED_8 (pixel) * f;
    843 			sgtot += (int)GREEN_8 (pixel) * f;
    844 			sbtot += (int)BLUE_8 (pixel) * f;
    845 			satot += (int)ALPHA_8 (pixel) * f;
    846 		    }
    847 		}
    848 	    }
    849 	}
    850 
    851 	satot = (satot + 0x8000) >> 16;
    852 	srtot = (srtot + 0x8000) >> 16;
    853 	sgtot = (sgtot + 0x8000) >> 16;
    854 	sbtot = (sbtot + 0x8000) >> 16;
    855 
    856 	satot = CLIP (satot, 0, 0xff);
    857 	srtot = CLIP (srtot, 0, 0xff);
    858 	sgtot = CLIP (sgtot, 0, 0xff);
    859 	sbtot = CLIP (sbtot, 0, 0xff);
    860 
    861 	buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0);
    862 
    863     next:
    864 	vx += ux;
    865 	vy += uy;
    866     }
    867 }
    868 
    869 static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
    870 
    871 static force_inline void
    872 bits_image_fetch_bilinear_affine (pixman_image_t * image,
    873 				  int              offset,
    874 				  int              line,
    875 				  int              width,
    876 				  uint32_t *       buffer,
    877 				  const uint32_t * mask,
    878 
    879 				  convert_pixel_t	convert_pixel,
    880 				  pixman_format_code_t	format,
    881 				  pixman_repeat_t	repeat_mode)
    882 {
    883     pixman_fixed_t x, y;
    884     pixman_fixed_t ux, uy;
    885     pixman_vector_t v;
    886     bits_image_t *bits = &image->bits;
    887     int i;
    888 
    889     /* reference point is the center of the pixel */
    890     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
    891     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
    892     v.vector[2] = pixman_fixed_1;
    893 
    894     if (!pixman_transform_point_3d (image->common.transform, &v))
    895 	return;
    896 
    897     ux = image->common.transform->matrix[0][0];
    898     uy = image->common.transform->matrix[1][0];
    899 
    900     x = v.vector[0];
    901     y = v.vector[1];
    902 
    903     for (i = 0; i < width; ++i)
    904     {
    905 	int x1, y1, x2, y2;
    906 	uint32_t tl, tr, bl, br;
    907 	int32_t distx, disty;
    908 	int width = image->bits.width;
    909 	int height = image->bits.height;
    910 	const uint8_t *row1;
    911 	const uint8_t *row2;
    912 
    913 	if (mask && !mask[i])
    914 	    goto next;
    915 
    916 	x1 = x - pixman_fixed_1 / 2;
    917 	y1 = y - pixman_fixed_1 / 2;
    918 
    919 	distx = pixman_fixed_to_bilinear_weight (x1);
    920 	disty = pixman_fixed_to_bilinear_weight (y1);
    921 
    922 	y1 = pixman_fixed_to_int (y1);
    923 	y2 = y1 + 1;
    924 	x1 = pixman_fixed_to_int (x1);
    925 	x2 = x1 + 1;
    926 
    927 	if (repeat_mode != PIXMAN_REPEAT_NONE)
    928 	{
    929 	    uint32_t mask;
    930 
    931 	    mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
    932 
    933 	    repeat (repeat_mode, &x1, width);
    934 	    repeat (repeat_mode, &y1, height);
    935 	    repeat (repeat_mode, &x2, width);
    936 	    repeat (repeat_mode, &y2, height);
    937 
    938 	    row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
    939 	    row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
    940 
    941 	    tl = convert_pixel (row1, x1) | mask;
    942 	    tr = convert_pixel (row1, x2) | mask;
    943 	    bl = convert_pixel (row2, x1) | mask;
    944 	    br = convert_pixel (row2, x2) | mask;
    945 	}
    946 	else
    947 	{
    948 	    uint32_t mask1, mask2;
    949 	    int bpp;
    950 
    951 	    /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value,
    952 	     * which means if you use it in expressions, those
    953 	     * expressions become unsigned themselves. Since
    954 	     * the variables below can be negative in some cases,
    955 	     * that will lead to crashes on 64 bit architectures.
    956 	     *
    957 	     * So this line makes sure bpp is signed
    958 	     */
    959 	    bpp = PIXMAN_FORMAT_BPP (format);
    960 
    961 	    if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0)
    962 	    {
    963 		buffer[i] = 0;
    964 		goto next;
    965 	    }
    966 
    967 	    if (y2 == 0)
    968 	    {
    969 		row1 = zero;
    970 		mask1 = 0;
    971 	    }
    972 	    else
    973 	    {
    974 		row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
    975 		row1 += bpp / 8 * x1;
    976 
    977 		mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
    978 	    }
    979 
    980 	    if (y1 == height - 1)
    981 	    {
    982 		row2 = zero;
    983 		mask2 = 0;
    984 	    }
    985 	    else
    986 	    {
    987 		row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
    988 		row2 += bpp / 8 * x1;
    989 
    990 		mask2 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
    991 	    }
    992 
    993 	    if (x2 == 0)
    994 	    {
    995 		tl = 0;
    996 		bl = 0;
    997 	    }
    998 	    else
    999 	    {
   1000 		tl = convert_pixel (row1, 0) | mask1;
   1001 		bl = convert_pixel (row2, 0) | mask2;
   1002 	    }
   1003 
   1004 	    if (x1 == width - 1)
   1005 	    {
   1006 		tr = 0;
   1007 		br = 0;
   1008 	    }
   1009 	    else
   1010 	    {
   1011 		tr = convert_pixel (row1, 1) | mask1;
   1012 		br = convert_pixel (row2, 1) | mask2;
   1013 	    }
   1014 	}
   1015 
   1016 	buffer[i] = bilinear_interpolation (
   1017 	    tl, tr, bl, br, distx, disty);
   1018 
   1019     next:
   1020 	x += ux;
   1021 	y += uy;
   1022     }
   1023 }
   1024 
   1025 static force_inline void
   1026 bits_image_fetch_nearest_affine (pixman_image_t * image,
   1027 				 int              offset,
   1028 				 int              line,
   1029 				 int              width,
   1030 				 uint32_t *       buffer,
   1031 				 const uint32_t * mask,
   1032 
   1033 				 convert_pixel_t	convert_pixel,
   1034 				 pixman_format_code_t	format,
   1035 				 pixman_repeat_t	repeat_mode)
   1036 {
   1037     pixman_fixed_t x, y;
   1038     pixman_fixed_t ux, uy;
   1039     pixman_vector_t v;
   1040     bits_image_t *bits = &image->bits;
   1041     int i;
   1042 
   1043     /* reference point is the center of the pixel */
   1044     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
   1045     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
   1046     v.vector[2] = pixman_fixed_1;
   1047 
   1048     if (!pixman_transform_point_3d (image->common.transform, &v))
   1049 	return;
   1050 
   1051     ux = image->common.transform->matrix[0][0];
   1052     uy = image->common.transform->matrix[1][0];
   1053 
   1054     x = v.vector[0];
   1055     y = v.vector[1];
   1056 
   1057     for (i = 0; i < width; ++i)
   1058     {
   1059 	int width, height, x0, y0;
   1060 	const uint8_t *row;
   1061 
   1062 	if (mask && !mask[i])
   1063 	    goto next;
   1064 
   1065 	width = image->bits.width;
   1066 	height = image->bits.height;
   1067 	x0 = pixman_fixed_to_int (x - pixman_fixed_e);
   1068 	y0 = pixman_fixed_to_int (y - pixman_fixed_e);
   1069 
   1070 	if (repeat_mode == PIXMAN_REPEAT_NONE &&
   1071 	    (y0 < 0 || y0 >= height || x0 < 0 || x0 >= width))
   1072 	{
   1073 	    buffer[i] = 0;
   1074 	}
   1075 	else
   1076 	{
   1077 	    uint32_t mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
   1078 
   1079 	    if (repeat_mode != PIXMAN_REPEAT_NONE)
   1080 	    {
   1081 		repeat (repeat_mode, &x0, width);
   1082 		repeat (repeat_mode, &y0, height);
   1083 	    }
   1084 
   1085 	    row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0;
   1086 
   1087 	    buffer[i] = convert_pixel (row, x0) | mask;
   1088 	}
   1089 
   1090     next:
   1091 	x += ux;
   1092 	y += uy;
   1093     }
   1094 }
   1095 
   1096 static force_inline uint32_t
   1097 convert_a8r8g8b8 (const uint8_t *row, int x)
   1098 {
   1099     return *(((uint32_t *)row) + x);
   1100 }
   1101 
   1102 static force_inline uint32_t
   1103 convert_x8r8g8b8 (const uint8_t *row, int x)
   1104 {
   1105     return *(((uint32_t *)row) + x);
   1106 }
   1107 
   1108 static force_inline uint32_t
   1109 convert_a8 (const uint8_t *row, int x)
   1110 {
   1111     return *(row + x) << 24;
   1112 }
   1113 
   1114 static force_inline uint32_t
   1115 convert_r5g6b5 (const uint8_t *row, int x)
   1116 {
   1117     return convert_0565_to_0888 (*((uint16_t *)row + x));
   1118 }
   1119 
   1120 #define MAKE_SEPARABLE_CONVOLUTION_FETCHER(name, format, repeat_mode)  \
   1121     static uint32_t *							\
   1122     bits_image_fetch_separable_convolution_affine_ ## name (pixman_iter_t   *iter, \
   1123 							    const uint32_t * mask) \
   1124     {									\
   1125 	bits_image_fetch_separable_convolution_affine (                 \
   1126 	    iter->image,                                                \
   1127 	    iter->x, iter->y++,                                         \
   1128 	    iter->width,                                                \
   1129 	    iter->buffer, mask,                                         \
   1130 	    convert_ ## format,                                         \
   1131 	    PIXMAN_ ## format,                                          \
   1132 	    repeat_mode);                                               \
   1133 									\
   1134 	return iter->buffer;                                            \
   1135     }
   1136 
   1137 #define MAKE_BILINEAR_FETCHER(name, format, repeat_mode)		\
   1138     static uint32_t *							\
   1139     bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t   *iter,	\
   1140 					       const uint32_t * mask)	\
   1141     {									\
   1142 	bits_image_fetch_bilinear_affine (iter->image,			\
   1143 					  iter->x, iter->y++,		\
   1144 					  iter->width,			\
   1145 					  iter->buffer, mask,		\
   1146 					  convert_ ## format,		\
   1147 					  PIXMAN_ ## format,		\
   1148 					  repeat_mode);			\
   1149 	return iter->buffer;						\
   1150     }
   1151 
   1152 #define MAKE_NEAREST_FETCHER(name, format, repeat_mode)			\
   1153     static uint32_t *							\
   1154     bits_image_fetch_nearest_affine_ ## name (pixman_iter_t   *iter,	\
   1155 					      const uint32_t * mask)	\
   1156     {									\
   1157 	bits_image_fetch_nearest_affine (iter->image,			\
   1158 					 iter->x, iter->y++,		\
   1159 					 iter->width,			\
   1160 					 iter->buffer, mask,		\
   1161 					 convert_ ## format,		\
   1162 					 PIXMAN_ ## format,		\
   1163 					 repeat_mode);			\
   1164 	return iter->buffer;						\
   1165     }
   1166 
   1167 #define MAKE_FETCHERS(name, format, repeat_mode)			\
   1168     MAKE_NEAREST_FETCHER (name, format, repeat_mode)			\
   1169     MAKE_BILINEAR_FETCHER (name, format, repeat_mode)			\
   1170     MAKE_SEPARABLE_CONVOLUTION_FETCHER (name, format, repeat_mode)
   1171 
   1172 MAKE_FETCHERS (pad_a8r8g8b8,     a8r8g8b8, PIXMAN_REPEAT_PAD)
   1173 MAKE_FETCHERS (none_a8r8g8b8,    a8r8g8b8, PIXMAN_REPEAT_NONE)
   1174 MAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT)
   1175 MAKE_FETCHERS (normal_a8r8g8b8,  a8r8g8b8, PIXMAN_REPEAT_NORMAL)
   1176 MAKE_FETCHERS (pad_x8r8g8b8,     x8r8g8b8, PIXMAN_REPEAT_PAD)
   1177 MAKE_FETCHERS (none_x8r8g8b8,    x8r8g8b8, PIXMAN_REPEAT_NONE)
   1178 MAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT)
   1179 MAKE_FETCHERS (normal_x8r8g8b8,  x8r8g8b8, PIXMAN_REPEAT_NORMAL)
   1180 MAKE_FETCHERS (pad_a8,           a8,       PIXMAN_REPEAT_PAD)
   1181 MAKE_FETCHERS (none_a8,          a8,       PIXMAN_REPEAT_NONE)
   1182 MAKE_FETCHERS (reflect_a8,	 a8,       PIXMAN_REPEAT_REFLECT)
   1183 MAKE_FETCHERS (normal_a8,	 a8,       PIXMAN_REPEAT_NORMAL)
   1184 MAKE_FETCHERS (pad_r5g6b5,       r5g6b5,   PIXMAN_REPEAT_PAD)
   1185 MAKE_FETCHERS (none_r5g6b5,      r5g6b5,   PIXMAN_REPEAT_NONE)
   1186 MAKE_FETCHERS (reflect_r5g6b5,   r5g6b5,   PIXMAN_REPEAT_REFLECT)
   1187 MAKE_FETCHERS (normal_r5g6b5,    r5g6b5,   PIXMAN_REPEAT_NORMAL)
   1188 
   1189 static void
   1190 replicate_pixel_32 (bits_image_t *   bits,
   1191 		    int              x,
   1192 		    int              y,
   1193 		    int              width,
   1194 		    uint32_t *       buffer)
   1195 {
   1196     uint32_t color;
   1197     uint32_t *end;
   1198 
   1199     color = bits->fetch_pixel_32 (bits, x, y);
   1200 
   1201     end = buffer + width;
   1202     while (buffer < end)
   1203 	*(buffer++) = color;
   1204 }
   1205 
   1206 static void
   1207 replicate_pixel_float (bits_image_t *   bits,
   1208 		       int              x,
   1209 		       int              y,
   1210 		       int              width,
   1211 		       uint32_t *       b)
   1212 {
   1213     argb_t color;
   1214     argb_t *buffer = (argb_t *)b;
   1215     argb_t *end;
   1216 
   1217     color = bits->fetch_pixel_float (bits, x, y);
   1218 
   1219     end = buffer + width;
   1220     while (buffer < end)
   1221 	*(buffer++) = color;
   1222 }
   1223 
   1224 static void
   1225 bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
   1226                                             pixman_bool_t wide,
   1227                                             int           x,
   1228                                             int           y,
   1229                                             int           width,
   1230                                             uint32_t *    buffer)
   1231 {
   1232     uint32_t w;
   1233 
   1234     if (y < 0 || y >= image->height)
   1235     {
   1236 	memset (buffer, 0, width * (wide? sizeof (argb_t) : 4));
   1237 	return;
   1238     }
   1239 
   1240     if (x < 0)
   1241     {
   1242 	w = MIN (width, -x);
   1243 
   1244 	memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4));
   1245 
   1246 	width -= w;
   1247 	buffer += w * (wide? 4 : 1);
   1248 	x += w;
   1249     }
   1250 
   1251     if (x < image->width)
   1252     {
   1253 	w = MIN (width, image->width - x);
   1254 
   1255 	if (wide)
   1256 	    image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL);
   1257 	else
   1258 	    image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL);
   1259 
   1260 	width -= w;
   1261 	buffer += w * (wide? 4 : 1);
   1262 	x += w;
   1263     }
   1264 
   1265     memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4));
   1266 }
   1267 
   1268 static void
   1269 bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
   1270                                               pixman_bool_t wide,
   1271                                               int           x,
   1272                                               int           y,
   1273                                               int           width,
   1274                                               uint32_t *    buffer)
   1275 {
   1276     uint32_t w;
   1277 
   1278     while (y < 0)
   1279 	y += image->height;
   1280 
   1281     while (y >= image->height)
   1282 	y -= image->height;
   1283 
   1284     if (image->width == 1)
   1285     {
   1286 	if (wide)
   1287 	    replicate_pixel_float (image, 0, y, width, buffer);
   1288 	else
   1289 	    replicate_pixel_32 (image, 0, y, width, buffer);
   1290 
   1291 	return;
   1292     }
   1293 
   1294     while (width)
   1295     {
   1296 	while (x < 0)
   1297 	    x += image->width;
   1298 	while (x >= image->width)
   1299 	    x -= image->width;
   1300 
   1301 	w = MIN (width, image->width - x);
   1302 
   1303 	if (wide)
   1304 	    image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL);
   1305 	else
   1306 	    image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL);
   1307 
   1308 	buffer += w * (wide? 4 : 1);
   1309 	x += w;
   1310 	width -= w;
   1311     }
   1312 }
   1313 
   1314 static uint32_t *
   1315 bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
   1316 				   const uint32_t *mask)
   1317 {
   1318     pixman_image_t *image  = iter->image;
   1319     int             x      = iter->x;
   1320     int             y      = iter->y;
   1321     int             width  = iter->width;
   1322     uint32_t *      buffer = iter->buffer;
   1323 
   1324     if (image->common.repeat == PIXMAN_REPEAT_NONE)
   1325     {
   1326 	bits_image_fetch_untransformed_repeat_none (
   1327 	    &image->bits, FALSE, x, y, width, buffer);
   1328     }
   1329     else
   1330     {
   1331 	bits_image_fetch_untransformed_repeat_normal (
   1332 	    &image->bits, FALSE, x, y, width, buffer);
   1333     }
   1334 
   1335     iter->y++;
   1336     return buffer;
   1337 }
   1338 
   1339 static uint32_t *
   1340 bits_image_fetch_untransformed_float (pixman_iter_t * iter,
   1341 				      const uint32_t *mask)
   1342 {
   1343     pixman_image_t *image  = iter->image;
   1344     int             x      = iter->x;
   1345     int             y      = iter->y;
   1346     int             width  = iter->width;
   1347     uint32_t *      buffer = iter->buffer;
   1348 
   1349     if (image->common.repeat == PIXMAN_REPEAT_NONE)
   1350     {
   1351 	bits_image_fetch_untransformed_repeat_none (
   1352 	    &image->bits, TRUE, x, y, width, buffer);
   1353     }
   1354     else
   1355     {
   1356 	bits_image_fetch_untransformed_repeat_normal (
   1357 	    &image->bits, TRUE, x, y, width, buffer);
   1358     }
   1359 
   1360     iter->y++;
   1361     return buffer;
   1362 }
   1363 
   1364 typedef struct
   1365 {
   1366     pixman_format_code_t	format;
   1367     uint32_t			flags;
   1368     pixman_iter_get_scanline_t	get_scanline_32;
   1369     pixman_iter_get_scanline_t  get_scanline_float;
   1370 } fetcher_info_t;
   1371 
   1372 static const fetcher_info_t fetcher_info[] =
   1373 {
   1374     { PIXMAN_any,
   1375       (FAST_PATH_NO_ALPHA_MAP			|
   1376        FAST_PATH_ID_TRANSFORM			|
   1377        FAST_PATH_NO_CONVOLUTION_FILTER		|
   1378        FAST_PATH_NO_PAD_REPEAT			|
   1379        FAST_PATH_NO_REFLECT_REPEAT),
   1380       bits_image_fetch_untransformed_32,
   1381       bits_image_fetch_untransformed_float
   1382     },
   1383 
   1384 #define FAST_BILINEAR_FLAGS						\
   1385     (FAST_PATH_NO_ALPHA_MAP		|				\
   1386      FAST_PATH_NO_ACCESSORS		|				\
   1387      FAST_PATH_HAS_TRANSFORM		|				\
   1388      FAST_PATH_AFFINE_TRANSFORM		|				\
   1389      FAST_PATH_X_UNIT_POSITIVE		|				\
   1390      FAST_PATH_Y_UNIT_ZERO		|				\
   1391      FAST_PATH_NONE_REPEAT		|				\
   1392      FAST_PATH_BILINEAR_FILTER)
   1393 
   1394     { PIXMAN_a8r8g8b8,
   1395       FAST_BILINEAR_FLAGS,
   1396       bits_image_fetch_bilinear_no_repeat_8888,
   1397       _pixman_image_get_scanline_generic_float
   1398     },
   1399 
   1400     { PIXMAN_x8r8g8b8,
   1401       FAST_BILINEAR_FLAGS,
   1402       bits_image_fetch_bilinear_no_repeat_8888,
   1403       _pixman_image_get_scanline_generic_float
   1404     },
   1405 
   1406 #define GENERAL_BILINEAR_FLAGS						\
   1407     (FAST_PATH_NO_ALPHA_MAP		|				\
   1408      FAST_PATH_NO_ACCESSORS		|				\
   1409      FAST_PATH_HAS_TRANSFORM		|				\
   1410      FAST_PATH_AFFINE_TRANSFORM		|				\
   1411      FAST_PATH_BILINEAR_FILTER)
   1412 
   1413 #define GENERAL_NEAREST_FLAGS						\
   1414     (FAST_PATH_NO_ALPHA_MAP		|				\
   1415      FAST_PATH_NO_ACCESSORS		|				\
   1416      FAST_PATH_HAS_TRANSFORM		|				\
   1417      FAST_PATH_AFFINE_TRANSFORM		|				\
   1418      FAST_PATH_NEAREST_FILTER)
   1419 
   1420 #define GENERAL_SEPARABLE_CONVOLUTION_FLAGS				\
   1421     (FAST_PATH_NO_ALPHA_MAP            |				\
   1422      FAST_PATH_NO_ACCESSORS            |				\
   1423      FAST_PATH_HAS_TRANSFORM           |				\
   1424      FAST_PATH_AFFINE_TRANSFORM        |				\
   1425      FAST_PATH_SEPARABLE_CONVOLUTION_FILTER)
   1426 
   1427 #define SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat)   \
   1428     { PIXMAN_ ## format,                                               \
   1429       GENERAL_SEPARABLE_CONVOLUTION_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \
   1430       bits_image_fetch_separable_convolution_affine_ ## name,          \
   1431       _pixman_image_get_scanline_generic_float			       \
   1432     },
   1433 
   1434 #define BILINEAR_AFFINE_FAST_PATH(name, format, repeat)			\
   1435     { PIXMAN_ ## format,						\
   1436       GENERAL_BILINEAR_FLAGS | FAST_PATH_ ## repeat ## _REPEAT,		\
   1437       bits_image_fetch_bilinear_affine_ ## name,			\
   1438       _pixman_image_get_scanline_generic_float				\
   1439     },
   1440 
   1441 #define NEAREST_AFFINE_FAST_PATH(name, format, repeat)			\
   1442     { PIXMAN_ ## format,						\
   1443       GENERAL_NEAREST_FLAGS | FAST_PATH_ ## repeat ## _REPEAT,		\
   1444       bits_image_fetch_nearest_affine_ ## name,				\
   1445       _pixman_image_get_scanline_generic_float				\
   1446     },
   1447 
   1448 #define AFFINE_FAST_PATHS(name, format, repeat)				\
   1449     SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat)	\
   1450     BILINEAR_AFFINE_FAST_PATH(name, format, repeat)			\
   1451     NEAREST_AFFINE_FAST_PATH(name, format, repeat)
   1452 
   1453     AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD)
   1454     AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE)
   1455     AFFINE_FAST_PATHS (reflect_a8r8g8b8, a8r8g8b8, REFLECT)
   1456     AFFINE_FAST_PATHS (normal_a8r8g8b8, a8r8g8b8, NORMAL)
   1457     AFFINE_FAST_PATHS (pad_x8r8g8b8, x8r8g8b8, PAD)
   1458     AFFINE_FAST_PATHS (none_x8r8g8b8, x8r8g8b8, NONE)
   1459     AFFINE_FAST_PATHS (reflect_x8r8g8b8, x8r8g8b8, REFLECT)
   1460     AFFINE_FAST_PATHS (normal_x8r8g8b8, x8r8g8b8, NORMAL)
   1461     AFFINE_FAST_PATHS (pad_a8, a8, PAD)
   1462     AFFINE_FAST_PATHS (none_a8, a8, NONE)
   1463     AFFINE_FAST_PATHS (reflect_a8, a8, REFLECT)
   1464     AFFINE_FAST_PATHS (normal_a8, a8, NORMAL)
   1465     AFFINE_FAST_PATHS (pad_r5g6b5, r5g6b5, PAD)
   1466     AFFINE_FAST_PATHS (none_r5g6b5, r5g6b5, NONE)
   1467     AFFINE_FAST_PATHS (reflect_r5g6b5, r5g6b5, REFLECT)
   1468     AFFINE_FAST_PATHS (normal_r5g6b5, r5g6b5, NORMAL)
   1469 
   1470     /* Affine, no alpha */
   1471     { PIXMAN_any,
   1472       (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM),
   1473       bits_image_fetch_affine_no_alpha,
   1474       _pixman_image_get_scanline_generic_float
   1475     },
   1476 
   1477     /* General */
   1478     { PIXMAN_any,
   1479       0,
   1480       bits_image_fetch_general,
   1481       _pixman_image_get_scanline_generic_float
   1482     },
   1483 
   1484     { PIXMAN_null },
   1485 };
   1486 
   1487 static void
   1488 bits_image_property_changed (pixman_image_t *image)
   1489 {
   1490     _pixman_bits_image_setup_accessors (&image->bits);
   1491 }
   1492 
   1493 void
   1494 _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
   1495 {
   1496     pixman_format_code_t format = image->common.extended_format_code;
   1497     uint32_t flags = image->common.flags;
   1498     const fetcher_info_t *info;
   1499 
   1500     for (info = fetcher_info; info->format != PIXMAN_null; ++info)
   1501     {
   1502 	if ((info->format == format || info->format == PIXMAN_any)	&&
   1503 	    (info->flags & flags) == info->flags)
   1504 	{
   1505 	    if (iter->iter_flags & ITER_NARROW)
   1506 	    {
   1507 		iter->get_scanline = info->get_scanline_32;
   1508 	    }
   1509 	    else
   1510 	    {
   1511 		iter->data = info->get_scanline_32;
   1512 		iter->get_scanline = info->get_scanline_float;
   1513 	    }
   1514 	    return;
   1515 	}
   1516     }
   1517 
   1518     /* Just in case we somehow didn't find a scanline function */
   1519     iter->get_scanline = _pixman_iter_get_scanline_noop;
   1520 }
   1521 
   1522 static uint32_t *
   1523 dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
   1524 {
   1525     pixman_image_t *image  = iter->image;
   1526     int             x      = iter->x;
   1527     int             y      = iter->y;
   1528     int             width  = iter->width;
   1529     uint32_t *	    buffer = iter->buffer;
   1530 
   1531     image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
   1532     if (image->common.alpha_map)
   1533     {
   1534 	uint32_t *alpha;
   1535 
   1536 	if ((alpha = malloc (width * sizeof (uint32_t))))
   1537 	{
   1538 	    int i;
   1539 
   1540 	    x -= image->common.alpha_origin_x;
   1541 	    y -= image->common.alpha_origin_y;
   1542 
   1543 	    image->common.alpha_map->fetch_scanline_32 (
   1544 		(pixman_image_t *)image->common.alpha_map,
   1545 		x, y, width, alpha, mask);
   1546 
   1547 	    for (i = 0; i < width; ++i)
   1548 	    {
   1549 		buffer[i] &= ~0xff000000;
   1550 		buffer[i] |= (alpha[i] & 0xff000000);
   1551 	    }
   1552 
   1553 	    free (alpha);
   1554 	}
   1555     }
   1556 
   1557     return iter->buffer;
   1558 }
   1559 
   1560 static uint32_t *
   1561 dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
   1562 {
   1563     bits_image_t *  image  = &iter->image->bits;
   1564     int             x      = iter->x;
   1565     int             y      = iter->y;
   1566     int             width  = iter->width;
   1567     argb_t *	    buffer = (argb_t *)iter->buffer;
   1568 
   1569     image->fetch_scanline_float (
   1570 	(pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask);
   1571     if (image->common.alpha_map)
   1572     {
   1573 	argb_t *alpha;
   1574 
   1575 	if ((alpha = malloc (width * sizeof (argb_t))))
   1576 	{
   1577 	    int i;
   1578 
   1579 	    x -= image->common.alpha_origin_x;
   1580 	    y -= image->common.alpha_origin_y;
   1581 
   1582 	    image->common.alpha_map->fetch_scanline_float (
   1583 		(pixman_image_t *)image->common.alpha_map,
   1584 		x, y, width, (uint32_t *)alpha, mask);
   1585 
   1586 	    for (i = 0; i < width; ++i)
   1587 		buffer[i].a = alpha[i].a;
   1588 
   1589 	    free (alpha);
   1590 	}
   1591     }
   1592 
   1593     return iter->buffer;
   1594 }
   1595 
   1596 static void
   1597 dest_write_back_narrow (pixman_iter_t *iter)
   1598 {
   1599     bits_image_t *  image  = &iter->image->bits;
   1600     int             x      = iter->x;
   1601     int             y      = iter->y;
   1602     int             width  = iter->width;
   1603     const uint32_t *buffer = iter->buffer;
   1604 
   1605     image->store_scanline_32 (image, x, y, width, buffer);
   1606 
   1607     if (image->common.alpha_map)
   1608     {
   1609 	x -= image->common.alpha_origin_x;
   1610 	y -= image->common.alpha_origin_y;
   1611 
   1612 	image->common.alpha_map->store_scanline_32 (
   1613 	    image->common.alpha_map, x, y, width, buffer);
   1614     }
   1615 
   1616     iter->y++;
   1617 }
   1618 
   1619 static void
   1620 dest_write_back_wide (pixman_iter_t *iter)
   1621 {
   1622     bits_image_t *  image  = &iter->image->bits;
   1623     int             x      = iter->x;
   1624     int             y      = iter->y;
   1625     int             width  = iter->width;
   1626     const uint32_t *buffer = iter->buffer;
   1627 
   1628     image->store_scanline_float (image, x, y, width, buffer);
   1629 
   1630     if (image->common.alpha_map)
   1631     {
   1632 	x -= image->common.alpha_origin_x;
   1633 	y -= image->common.alpha_origin_y;
   1634 
   1635 	image->common.alpha_map->store_scanline_float (
   1636 	    image->common.alpha_map, x, y, width, buffer);
   1637     }
   1638 
   1639     iter->y++;
   1640 }
   1641 
   1642 void
   1643 _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
   1644 {
   1645     if (iter->iter_flags & ITER_NARROW)
   1646     {
   1647 	if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
   1648 	    (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
   1649 	{
   1650 	    iter->get_scanline = _pixman_iter_get_scanline_noop;
   1651 	}
   1652 	else
   1653 	{
   1654 	    iter->get_scanline = dest_get_scanline_narrow;
   1655 	}
   1656 
   1657 	iter->write_back = dest_write_back_narrow;
   1658     }
   1659     else
   1660     {
   1661 	iter->get_scanline = dest_get_scanline_wide;
   1662 	iter->write_back = dest_write_back_wide;
   1663     }
   1664 }
   1665 
   1666 static uint32_t *
   1667 create_bits (pixman_format_code_t format,
   1668              int                  width,
   1669              int                  height,
   1670              int *		  rowstride_bytes,
   1671 	     pixman_bool_t	  clear)
   1672 {
   1673     int stride;
   1674     size_t buf_size;
   1675     int bpp;
   1676 
   1677     /* what follows is a long-winded way, avoiding any possibility of integer
   1678      * overflows, of saying:
   1679      * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t);
   1680      */
   1681 
   1682     bpp = PIXMAN_FORMAT_BPP (format);
   1683     if (_pixman_multiply_overflows_int (width, bpp))
   1684 	return NULL;
   1685 
   1686     stride = width * bpp;
   1687     if (_pixman_addition_overflows_int (stride, 0x1f))
   1688 	return NULL;
   1689 
   1690     stride += 0x1f;
   1691     stride >>= 5;
   1692 
   1693     stride *= sizeof (uint32_t);
   1694 
   1695     if (_pixman_multiply_overflows_size (height, stride))
   1696 	return NULL;
   1697 
   1698     buf_size = height * stride;
   1699 
   1700     if (rowstride_bytes)
   1701 	*rowstride_bytes = stride;
   1702 
   1703     if (clear)
   1704 	return calloc (buf_size, 1);
   1705     else
   1706 	return malloc (buf_size);
   1707 }
   1708 
   1709 pixman_bool_t
   1710 _pixman_bits_image_init (pixman_image_t *     image,
   1711                          pixman_format_code_t format,
   1712                          int                  width,
   1713                          int                  height,
   1714                          uint32_t *           bits,
   1715                          int                  rowstride,
   1716 			 pixman_bool_t	      clear)
   1717 {
   1718     uint32_t *free_me = NULL;
   1719 
   1720     if (!bits && width && height)
   1721     {
   1722 	int rowstride_bytes;
   1723 
   1724 	free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear);
   1725 
   1726 	if (!bits)
   1727 	    return FALSE;
   1728 
   1729 	rowstride = rowstride_bytes / (int) sizeof (uint32_t);
   1730     }
   1731 
   1732     _pixman_image_init (image);
   1733 
   1734     image->type = BITS;
   1735     image->bits.format = format;
   1736     image->bits.width = width;
   1737     image->bits.height = height;
   1738     image->bits.bits = bits;
   1739     image->bits.free_me = free_me;
   1740     image->bits.read_func = NULL;
   1741     image->bits.write_func = NULL;
   1742     image->bits.rowstride = rowstride;
   1743     image->bits.indexed = NULL;
   1744 
   1745     image->common.property_changed = bits_image_property_changed;
   1746 
   1747     _pixman_image_reset_clip_region (image);
   1748 
   1749     return TRUE;
   1750 }
   1751 
   1752 static pixman_image_t *
   1753 create_bits_image_internal (pixman_format_code_t format,
   1754 			    int                  width,
   1755 			    int                  height,
   1756 			    uint32_t *           bits,
   1757 			    int                  rowstride_bytes,
   1758 			    pixman_bool_t	 clear)
   1759 {
   1760     pixman_image_t *image;
   1761 
   1762     /* must be a whole number of uint32_t's
   1763      */
   1764     return_val_if_fail (
   1765 	bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
   1766 
   1767     return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
   1768 
   1769     image = _pixman_image_allocate ();
   1770 
   1771     if (!image)
   1772 	return NULL;
   1773 
   1774     if (!_pixman_bits_image_init (image, format, width, height, bits,
   1775 				  rowstride_bytes / (int) sizeof (uint32_t),
   1776 				  clear))
   1777     {
   1778 	free (image);
   1779 	return NULL;
   1780     }
   1781 
   1782     return image;
   1783 }
   1784 
   1785 /* If bits is NULL, a buffer will be allocated and initialized to 0 */
   1786 PIXMAN_EXPORT pixman_image_t *
   1787 pixman_image_create_bits (pixman_format_code_t format,
   1788                           int                  width,
   1789                           int                  height,
   1790                           uint32_t *           bits,
   1791                           int                  rowstride_bytes)
   1792 {
   1793     return create_bits_image_internal (
   1794 	format, width, height, bits, rowstride_bytes, TRUE);
   1795 }
   1796 
   1797 
   1798 /* If bits is NULL, a buffer will be allocated and _not_ initialized */
   1799 PIXMAN_EXPORT pixman_image_t *
   1800 pixman_image_create_bits_no_clear (pixman_format_code_t format,
   1801 				   int                  width,
   1802 				   int                  height,
   1803 				   uint32_t *           bits,
   1804 				   int                  rowstride_bytes)
   1805 {
   1806     return create_bits_image_internal (
   1807 	format, width, height, bits, rowstride_bytes, FALSE);
   1808 }
   1809