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@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
39static 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
55static force_inline uint32_t
56fetch_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
68typedef uint32_t (* get_pixel_t) (bits_image_t *image,
69				  int x, int y, pixman_bool_t check_bounds);
70
71static force_inline uint32_t
72bits_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
93static force_inline uint32_t
94bits_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
140static uint32_t *
141bits_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
355static force_inline uint32_t
356bits_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
429static uint32_t
430bits_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
527static force_inline uint32_t
528bits_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
561static uint32_t *
562bits_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 */
614static force_inline uint32_t
615fetch_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
654static uint32_t *
655bits_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
723typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
724
725static force_inline void
726bits_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
869static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
870
871static force_inline void
872bits_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
1025static force_inline void
1026bits_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
1096static force_inline uint32_t
1097convert_a8r8g8b8 (const uint8_t *row, int x)
1098{
1099    return *(((uint32_t *)row) + x);
1100}
1101
1102static force_inline uint32_t
1103convert_x8r8g8b8 (const uint8_t *row, int x)
1104{
1105    return *(((uint32_t *)row) + x);
1106}
1107
1108static force_inline uint32_t
1109convert_a8 (const uint8_t *row, int x)
1110{
1111    return *(row + x) << 24;
1112}
1113
1114static force_inline uint32_t
1115convert_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
1172MAKE_FETCHERS (pad_a8r8g8b8,     a8r8g8b8, PIXMAN_REPEAT_PAD)
1173MAKE_FETCHERS (none_a8r8g8b8,    a8r8g8b8, PIXMAN_REPEAT_NONE)
1174MAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT)
1175MAKE_FETCHERS (normal_a8r8g8b8,  a8r8g8b8, PIXMAN_REPEAT_NORMAL)
1176MAKE_FETCHERS (pad_x8r8g8b8,     x8r8g8b8, PIXMAN_REPEAT_PAD)
1177MAKE_FETCHERS (none_x8r8g8b8,    x8r8g8b8, PIXMAN_REPEAT_NONE)
1178MAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT)
1179MAKE_FETCHERS (normal_x8r8g8b8,  x8r8g8b8, PIXMAN_REPEAT_NORMAL)
1180MAKE_FETCHERS (pad_a8,           a8,       PIXMAN_REPEAT_PAD)
1181MAKE_FETCHERS (none_a8,          a8,       PIXMAN_REPEAT_NONE)
1182MAKE_FETCHERS (reflect_a8,	 a8,       PIXMAN_REPEAT_REFLECT)
1183MAKE_FETCHERS (normal_a8,	 a8,       PIXMAN_REPEAT_NORMAL)
1184MAKE_FETCHERS (pad_r5g6b5,       r5g6b5,   PIXMAN_REPEAT_PAD)
1185MAKE_FETCHERS (none_r5g6b5,      r5g6b5,   PIXMAN_REPEAT_NONE)
1186MAKE_FETCHERS (reflect_r5g6b5,   r5g6b5,   PIXMAN_REPEAT_REFLECT)
1187MAKE_FETCHERS (normal_r5g6b5,    r5g6b5,   PIXMAN_REPEAT_NORMAL)
1188
1189static void
1190replicate_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
1206static void
1207replicate_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
1224static void
1225bits_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
1268static void
1269bits_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
1314static uint32_t *
1315bits_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
1339static uint32_t *
1340bits_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
1364typedef 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
1372static 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
1487static void
1488bits_image_property_changed (pixman_image_t *image)
1489{
1490    _pixman_bits_image_setup_accessors (&image->bits);
1491}
1492
1493void
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
1522static uint32_t *
1523dest_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
1560static uint32_t *
1561dest_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
1596static void
1597dest_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
1619static void
1620dest_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
1642void
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
1666static uint32_t *
1667create_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
1709pixman_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
1752static pixman_image_t *
1753create_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 */
1786PIXMAN_EXPORT pixman_image_t *
1787pixman_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 */
1799PIXMAN_EXPORT pixman_image_t *
1800pixman_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