Delete simple repeat code
[profile/ivi/pixman.git] / pixman / pixman.c
1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
2 /*
3  * Copyright © 2000 SuSE, Inc.
4  * Copyright © 2007 Red Hat, Inc.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of SuSE not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  SuSE makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author:  Keith Packard, SuSE, Inc.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 #include "pixman-private.h"
30
31 #include <stdlib.h>
32
33 static force_inline pixman_implementation_t *
34 get_implementation (void)
35 {
36     static pixman_implementation_t *global_implementation;
37
38     if (!global_implementation)
39         global_implementation = _pixman_choose_implementation ();
40
41     return global_implementation;
42 }
43
44 typedef struct operator_info_t operator_info_t;
45
46 struct operator_info_t
47 {
48     uint8_t     opaque_info[4];
49 };
50
51 #define PACK(neither, src, dest, both)                  \
52     {{      (uint8_t)PIXMAN_OP_ ## neither,             \
53             (uint8_t)PIXMAN_OP_ ## src,                 \
54             (uint8_t)PIXMAN_OP_ ## dest,                \
55             (uint8_t)PIXMAN_OP_ ## both         }}
56
57 static const operator_info_t operator_table[] =
58 {
59     /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
60     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
61     PACK (SRC,                   SRC,                   SRC,                   SRC),
62     PACK (DST,                   DST,                   DST,                   DST),
63     PACK (OVER,                  SRC,                   OVER,                  SRC),
64     PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
65     PACK (IN,                    IN,                    SRC,                   SRC),
66     PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
67     PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
68     PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
69     PACK (ATOP,                  IN,                    OVER,                  SRC),
70     PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
71     PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
72     PACK (ADD,                   ADD,                   ADD,                   ADD),
73     PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
74
75     {{ 0 /* 0x0e */ }},
76     {{ 0 /* 0x0f */ }},
77
78     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
79     PACK (SRC,                   SRC,                   SRC,                   SRC),
80     PACK (DST,                   DST,                   DST,                   DST),
81     PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
82     PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
83     PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
84     PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
85     PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
86     PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
87     PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
88     PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
89     PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
90
91     {{ 0 /* 0x1c */ }},
92     {{ 0 /* 0x1d */ }},
93     {{ 0 /* 0x1e */ }},
94     {{ 0 /* 0x1f */ }},
95
96     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
97     PACK (SRC,                   SRC,                   SRC,                   SRC),
98     PACK (DST,                   DST,                   DST,                   DST),
99     PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
100     PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
101     PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
102     PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
103     PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
104     PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
105     PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
106     PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
107     PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
108
109     {{ 0 /* 0x2c */ }},
110     {{ 0 /* 0x2d */ }},
111     {{ 0 /* 0x2e */ }},
112     {{ 0 /* 0x2f */ }},
113
114     PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
115     PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
116     PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
117     PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
118     PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
119     PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
120     PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
121     PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
122     PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
123     PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
124     PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
125     PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
126     PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
127     PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
128     PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
129 };
130
131 /*
132  * Optimize the current operator based on opacity of source or destination
133  * The output operator should be mathematically equivalent to the source.
134  */
135 static pixman_op_t
136 optimize_operator (pixman_op_t     op,
137                    uint32_t        src_flags,
138                    uint32_t        mask_flags,
139                    uint32_t        dst_flags)
140 {
141     pixman_bool_t is_source_opaque, is_dest_opaque;
142
143 #define OPAQUE_SHIFT 13
144     
145     COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
146     
147     is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
148     is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
149
150     is_dest_opaque >>= OPAQUE_SHIFT - 1;
151     is_source_opaque >>= OPAQUE_SHIFT;
152
153     return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
154 }
155
156 static void
157 apply_workaround (pixman_image_t *image,
158                   int32_t *       x,
159                   int32_t *       y,
160                   uint32_t **     save_bits,
161                   int *           save_dx,
162                   int *           save_dy)
163 {
164     if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
165     {
166         /* Some X servers generate images that point to the
167          * wrong place in memory, but then set the clip region
168          * to point to the right place. Because of an old bug
169          * in pixman, this would actually work.
170          *
171          * Here we try and undo the damage
172          */
173         int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
174         pixman_box32_t *extents;
175         uint8_t *t;
176         int dx, dy;
177         
178         extents = pixman_region32_extents (&(image->common.clip_region));
179         dx = extents->x1;
180         dy = extents->y1;
181         
182         *save_bits = image->bits.bits;
183         
184         *x -= dx;
185         *y -= dy;
186         pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
187         
188         t = (uint8_t *)image->bits.bits;
189         t += dy * image->bits.rowstride * 4 + dx * bpp;
190         image->bits.bits = (uint32_t *)t;
191         
192         *save_dx = dx;
193         *save_dy = dy;
194     }
195 }
196
197 static void
198 unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
199 {
200     if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
201     {
202         image->bits.bits = bits;
203         pixman_region32_translate (&image->common.clip_region, dx, dy);
204     }
205 }
206
207 /*
208  * Computing composite region
209  */
210 static inline pixman_bool_t
211 clip_general_image (pixman_region32_t * region,
212                     pixman_region32_t * clip,
213                     int                 dx,
214                     int                 dy)
215 {
216     if (pixman_region32_n_rects (region) == 1 &&
217         pixman_region32_n_rects (clip) == 1)
218     {
219         pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
220         pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
221         int v;
222
223         if (rbox->x1 < (v = cbox->x1 + dx))
224             rbox->x1 = v;
225         if (rbox->x2 > (v = cbox->x2 + dx))
226             rbox->x2 = v;
227         if (rbox->y1 < (v = cbox->y1 + dy))
228             rbox->y1 = v;
229         if (rbox->y2 > (v = cbox->y2 + dy))
230             rbox->y2 = v;
231         if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
232         {
233             pixman_region32_init (region);
234             return FALSE;
235         }
236     }
237     else if (!pixman_region32_not_empty (clip))
238     {
239         return FALSE;
240     }
241     else
242     {
243         if (dx || dy)
244             pixman_region32_translate (region, -dx, -dy);
245
246         if (!pixman_region32_intersect (region, region, clip))
247             return FALSE;
248
249         if (dx || dy)
250             pixman_region32_translate (region, dx, dy);
251     }
252
253     return pixman_region32_not_empty (region);
254 }
255
256 static inline pixman_bool_t
257 clip_source_image (pixman_region32_t * region,
258                    pixman_image_t *    image,
259                    int                 dx,
260                    int                 dy)
261 {
262     /* Source clips are ignored, unless they are explicitly turned on
263      * and the clip in question was set by an X client. (Because if
264      * the clip was not set by a client, then it is a hierarchy
265      * clip and those should always be ignored for sources).
266      */
267     if (!image->common.clip_sources || !image->common.client_clip)
268         return TRUE;
269
270     return clip_general_image (region,
271                                &image->common.clip_region,
272                                dx, dy);
273 }
274
275 /*
276  * returns FALSE if the final region is empty.  Indistinguishable from
277  * an allocation failure, but rendering ignores those anyways.
278  */
279 static pixman_bool_t
280 pixman_compute_composite_region32 (pixman_region32_t * region,
281                                    pixman_image_t *    src_image,
282                                    pixman_image_t *    mask_image,
283                                    pixman_image_t *    dst_image,
284                                    int32_t             src_x,
285                                    int32_t             src_y,
286                                    int32_t             mask_x,
287                                    int32_t             mask_y,
288                                    int32_t             dest_x,
289                                    int32_t             dest_y,
290                                    int32_t             width,
291                                    int32_t             height)
292 {
293     region->extents.x1 = dest_x;
294     region->extents.x2 = dest_x + width;
295     region->extents.y1 = dest_y;
296     region->extents.y2 = dest_y + height;
297
298     region->extents.x1 = MAX (region->extents.x1, 0);
299     region->extents.y1 = MAX (region->extents.y1, 0);
300     region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
301     region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
302
303     region->data = 0;
304
305     /* Check for empty operation */
306     if (region->extents.x1 >= region->extents.x2 ||
307         region->extents.y1 >= region->extents.y2)
308     {
309         region->extents.x1 = 0;
310         region->extents.x2 = 0;
311         region->extents.y1 = 0;
312         region->extents.y2 = 0;
313         return FALSE;
314     }
315
316     if (dst_image->common.have_clip_region)
317     {
318         if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
319             return FALSE;
320     }
321
322     if (dst_image->common.alpha_map)
323     {
324         if (!pixman_region32_intersect_rect (region, region,
325                                              dst_image->common.alpha_origin_x,
326                                              dst_image->common.alpha_origin_y,
327                                              dst_image->common.alpha_map->width,
328                                              dst_image->common.alpha_map->height))
329         {
330             return FALSE;
331         }
332         if (!pixman_region32_not_empty (region))
333             return FALSE;
334         if (dst_image->common.alpha_map->common.have_clip_region)
335         {
336             if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
337                                      -dst_image->common.alpha_origin_x,
338                                      -dst_image->common.alpha_origin_y))
339             {
340                 return FALSE;
341             }
342         }
343     }
344
345     /* clip against src */
346     if (src_image->common.have_clip_region)
347     {
348         if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
349             return FALSE;
350     }
351     if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
352     {
353         if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
354                                 dest_x - (src_x - src_image->common.alpha_origin_x),
355                                 dest_y - (src_y - src_image->common.alpha_origin_y)))
356         {
357             return FALSE;
358         }
359     }
360     /* clip against mask */
361     if (mask_image && mask_image->common.have_clip_region)
362     {
363         if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
364             return FALSE;
365
366         if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
367         {
368             if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
369                                     dest_x - (mask_x - mask_image->common.alpha_origin_x),
370                                     dest_y - (mask_y - mask_image->common.alpha_origin_y)))
371             {
372                 return FALSE;
373             }
374         }
375     }
376
377     return TRUE;
378 }
379
380 #define N_CACHED_FAST_PATHS 8
381
382 typedef struct
383 {
384     struct
385     {
386         pixman_implementation_t *       imp;
387         pixman_fast_path_t              fast_path;
388     } cache [N_CACHED_FAST_PATHS];
389 } cache_t;
390
391 PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
392
393 static force_inline pixman_bool_t
394 lookup_composite_function (pixman_op_t                  op,
395                            pixman_format_code_t         src_format,
396                            uint32_t                     src_flags,
397                            pixman_format_code_t         mask_format,
398                            uint32_t                     mask_flags,
399                            pixman_format_code_t         dest_format,
400                            uint32_t                     dest_flags,
401                            pixman_implementation_t    **out_imp,
402                            pixman_composite_func_t     *out_func)
403 {
404     pixman_implementation_t *imp;
405     cache_t *cache;
406     int i;
407
408     /* Check cache for fast paths */
409     cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
410
411     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
412     {
413         const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
414
415         /* Note that we check for equality here, not whether
416          * the cached fast path matches. This is to prevent
417          * us from selecting an overly general fast path
418          * when a more specific one would work.
419          */
420         if (info->op == op                      &&
421             info->src_format == src_format      &&
422             info->mask_format == mask_format    &&
423             info->dest_format == dest_format    &&
424             info->src_flags == src_flags        &&
425             info->mask_flags == mask_flags      &&
426             info->dest_flags == dest_flags      &&
427             info->func)
428         {
429             *out_imp = cache->cache[i].imp;
430             *out_func = cache->cache[i].fast_path.func;
431
432             goto update_cache;
433         }
434     }
435
436     for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
437     {
438         const pixman_fast_path_t *info = imp->fast_paths;
439
440         while (info->op != PIXMAN_OP_NONE)
441         {
442             if ((info->op == op || info->op == PIXMAN_OP_any)           &&
443                 /* Formats */
444                 ((info->src_format == src_format) ||
445                  (info->src_format == PIXMAN_any))                      &&
446                 ((info->mask_format == mask_format) ||
447                  (info->mask_format == PIXMAN_any))                     &&
448                 ((info->dest_format == dest_format) ||
449                  (info->dest_format == PIXMAN_any))                     &&
450                 /* Flags */
451                 (info->src_flags & src_flags) == info->src_flags        &&
452                 (info->mask_flags & mask_flags) == info->mask_flags     &&
453                 (info->dest_flags & dest_flags) == info->dest_flags)
454             {
455                 *out_imp = imp;
456                 *out_func = info->func;
457
458                 /* Set i to the last spot in the cache so that the
459                  * move-to-front code below will work
460                  */
461                 i = N_CACHED_FAST_PATHS - 1;
462
463                 goto update_cache;
464             }
465
466             ++info;
467         }
468     }
469     return FALSE;
470
471 update_cache:
472     if (i)
473     {
474         while (i--)
475             cache->cache[i + 1] = cache->cache[i];
476
477         cache->cache[0].imp = *out_imp;
478         cache->cache[0].fast_path.op = op;
479         cache->cache[0].fast_path.src_format = src_format;
480         cache->cache[0].fast_path.src_flags = src_flags;
481         cache->cache[0].fast_path.mask_format = mask_format;
482         cache->cache[0].fast_path.mask_flags = mask_flags;
483         cache->cache[0].fast_path.dest_format = dest_format;
484         cache->cache[0].fast_path.dest_flags = dest_flags;
485         cache->cache[0].fast_path.func = *out_func;
486     }
487
488     return TRUE;
489 }
490
491 static pixman_bool_t
492 compute_sample_extents (pixman_transform_t *transform,
493                         pixman_box32_t *extents, int x, int y, 
494                         pixman_fixed_t x_off, pixman_fixed_t y_off,
495                         pixman_fixed_t width, pixman_fixed_t height)
496 {
497     pixman_fixed_t x1, y1, x2, y2;
498     pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
499
500     /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
501     x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
502     y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
503     x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
504     y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
505
506     if (!transform)
507     {
508         tx1 = (pixman_fixed_48_16_t)x1;
509         ty1 = (pixman_fixed_48_16_t)y1;
510         tx2 = (pixman_fixed_48_16_t)x2;
511         ty2 = (pixman_fixed_48_16_t)y2;
512     }
513     else
514     {
515         int i;
516
517         /* Silence GCC */
518         tx1 = ty1 = tx2 = ty2 = 0;
519     
520         for (i = 0; i < 4; ++i)
521         {
522             pixman_fixed_48_16_t tx, ty;
523             pixman_vector_t v;
524
525             v.vector[0] = (i & 0x01)? x1 : x2;
526             v.vector[1] = (i & 0x02)? y1 : y2;
527             v.vector[2] = pixman_fixed_1;
528
529             if (!pixman_transform_point (transform, &v))
530                 return FALSE;
531
532             tx = (pixman_fixed_48_16_t)v.vector[0];
533             ty = (pixman_fixed_48_16_t)v.vector[1];
534
535             if (i == 0)
536             {
537                 tx1 = tx;
538                 ty1 = ty;
539                 tx2 = tx;
540                 ty2 = ty;
541             }
542             else
543             {
544                 if (tx < tx1)
545                     tx1 = tx;
546                 if (ty < ty1)
547                     ty1 = ty;
548                 if (tx > tx2)
549                     tx2 = tx;
550                 if (ty > ty2)
551                     ty2 = ty;
552             }
553         }
554     }
555
556     /* Expand the source area by a tiny bit so account of different rounding that
557      * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
558      * 0.5 so this won't cause the area computed to be overly pessimistic.
559      */
560     tx1 += x_off - 8 * pixman_fixed_e;
561     ty1 += y_off - 8 * pixman_fixed_e;
562     tx2 += x_off + width + 8 * pixman_fixed_e;
563     ty2 += y_off + height + 8 * pixman_fixed_e;
564
565     if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
566         ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
567         tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
568         ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
569     {
570         return FALSE;
571     }
572     else
573     {
574         extents->x1 = pixman_fixed_to_int (tx1);
575         extents->y1 = pixman_fixed_to_int (ty1);
576         extents->x2 = pixman_fixed_to_int (tx2) + 1;
577         extents->y2 = pixman_fixed_to_int (ty2) + 1;
578
579         return TRUE;
580     }
581 }
582
583 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
584
585 static pixman_bool_t
586 analyze_extent (pixman_image_t *image, int x, int y,
587                 const pixman_box32_t *extents, uint32_t *flags)
588 {
589     pixman_transform_t *transform;
590     pixman_fixed_t *params;
591     pixman_fixed_t x_off, y_off;
592     pixman_fixed_t width, height;
593     pixman_box32_t ex;
594
595     if (!image)
596         return TRUE;
597
598     /* Some compositing functions walk one step
599      * outside the destination rectangle, so we
600      * check here that the expanded-by-one source
601      * extents in destination space fits in 16 bits
602      */
603     if (!IS_16BIT (extents->x1 - x - 1)         ||
604         !IS_16BIT (extents->y1 - y - 1)         ||
605         !IS_16BIT (extents->x2 - x + 1)         ||
606         !IS_16BIT (extents->y2 - y + 1))
607     {
608         return FALSE;
609     }
610
611     transform = image->common.transform;
612     if (image->common.type == BITS)
613     {
614         /* During repeat mode calculations we might convert the
615          * width/height of an image to fixed 16.16, so we need
616          * them to be smaller than 16 bits.
617          */
618         if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
619             return FALSE;
620
621 #define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
622         
623         if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
624             extents->x1 - x >= 0 &&
625             extents->y1 - y >= 0 &&
626             extents->x2 - x <= image->bits.width &&
627             extents->y2 - y <= image->bits.height)
628         {
629             *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
630             return TRUE;
631         }
632     
633         switch (image->common.filter)
634         {
635         case PIXMAN_FILTER_CONVOLUTION:
636             params = image->common.filter_params;
637             x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
638             y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
639             width = params[0];
640             height = params[1];
641             break;
642
643         case PIXMAN_FILTER_GOOD:
644         case PIXMAN_FILTER_BEST:
645         case PIXMAN_FILTER_BILINEAR:
646             x_off = - pixman_fixed_1 / 2;
647             y_off = - pixman_fixed_1 / 2;
648             width = pixman_fixed_1;
649             height = pixman_fixed_1;
650             break;
651
652         case PIXMAN_FILTER_FAST:
653         case PIXMAN_FILTER_NEAREST:
654             x_off = - pixman_fixed_e;
655             y_off = - pixman_fixed_e;
656             width = 0;
657             height = 0;
658             break;
659
660         default:
661             return FALSE;
662         }
663
664         /* Check whether the non-expanded, transformed extent is entirely within
665          * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
666          */
667         ex = *extents;
668         if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
669             ex.x1 >= 0 && ex.y1 >= 0 &&
670             ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
671         {
672             *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
673         }
674     }
675     else
676     {
677         x_off = 0;
678         y_off = 0;
679         width = 0;
680         height = 0;
681     }
682
683     /* Check that the extents expanded by one don't overflow. This ensures that
684      * compositing functions can simply walk the source space using 16.16
685      * variables without worrying about overflow.
686      */
687     ex.x1 = extents->x1 - 1;
688     ex.y1 = extents->y1 - 1;
689     ex.x2 = extents->x2 + 1;
690     ex.y2 = extents->y2 + 1;
691
692     if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
693         return FALSE;
694
695     return TRUE;
696 }
697
698 /*
699  * Work around GCC bug causing crashes in Mozilla with SSE2
700  *
701  * When using -msse, gcc generates movdqa instructions assuming that
702  * the stack is 16 byte aligned. Unfortunately some applications, such
703  * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
704  * causes the movdqa instructions to fail.
705  *
706  * The __force_align_arg_pointer__ makes gcc generate a prologue that
707  * realigns the stack pointer to 16 bytes.
708  *
709  * On x86-64 this is not necessary because the standard ABI already
710  * calls for a 16 byte aligned stack.
711  *
712  * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
713  */
714 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
715 __attribute__((__force_align_arg_pointer__))
716 #endif
717 PIXMAN_EXPORT void
718 pixman_image_composite32 (pixman_op_t      op,
719                           pixman_image_t * src,
720                           pixman_image_t * mask,
721                           pixman_image_t * dest,
722                           int32_t          src_x,
723                           int32_t          src_y,
724                           int32_t          mask_x,
725                           int32_t          mask_y,
726                           int32_t          dest_x,
727                           int32_t          dest_y,
728                           int32_t          width,
729                           int32_t          height)
730 {
731     pixman_format_code_t src_format, mask_format, dest_format;
732     uint32_t src_flags, mask_flags, dest_flags;
733     pixman_region32_t region;
734     pixman_box32_t *extents;
735     uint32_t *src_bits;
736     int src_dx, src_dy;
737     uint32_t *mask_bits;
738     int mask_dx, mask_dy;
739     uint32_t *dest_bits;
740     int dest_dx, dest_dy;
741     pixman_bool_t need_workaround;
742     pixman_implementation_t *imp;
743     pixman_composite_func_t func;
744
745     _pixman_image_validate (src);
746     if (mask)
747         _pixman_image_validate (mask);
748     _pixman_image_validate (dest);
749
750     src_format = src->common.extended_format_code;
751     src_flags = src->common.flags;
752
753     if (mask)
754     {
755         mask_format = mask->common.extended_format_code;
756         mask_flags = mask->common.flags;
757     }
758     else
759     {
760         mask_format = PIXMAN_null;
761         mask_flags = FAST_PATH_IS_OPAQUE;
762     }
763
764     dest_format = dest->common.extended_format_code;
765     dest_flags = dest->common.flags;
766
767     /* Check for pixbufs */
768     if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
769         (src->type == BITS && src->bits.bits == mask->bits.bits)           &&
770         (src->common.repeat == mask->common.repeat)                        &&
771         (src_x == mask_x && src_y == mask_y))
772     {
773         if (src_format == PIXMAN_x8b8g8r8)
774             src_format = mask_format = PIXMAN_pixbuf;
775         else if (src_format == PIXMAN_x8r8g8b8)
776             src_format = mask_format = PIXMAN_rpixbuf;
777     }
778
779     /* Check for workaround */
780     need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
781
782     if (need_workaround)
783     {
784         apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
785         apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
786         apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
787     }
788
789     pixman_region32_init (&region);
790
791     if (!pixman_compute_composite_region32 (
792             &region, src, mask, dest,
793             src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
794     {
795         goto out;
796     }
797
798     extents = pixman_region32_extents (&region);
799
800     if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
801         goto out;
802
803     if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
804         goto out;
805
806     /* If the clip is within the source samples, and the samples are opaque,
807      * then the source is effectively opaque.
808      */
809 #define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
810
811     if ((src_flags & BOTH) == BOTH)
812         src_flags |= FAST_PATH_IS_OPAQUE;
813     
814     if ((mask_flags & BOTH) == BOTH)
815         mask_flags |= FAST_PATH_IS_OPAQUE;
816     
817     /*
818      * Check if we can replace our operator by a simpler one
819      * if the src or dest are opaque. The output operator should be
820      * mathematically equivalent to the source.
821      */
822     op = optimize_operator (op, src_flags, mask_flags, dest_flags);
823     if (op == PIXMAN_OP_DST)
824         goto out;
825
826     if (lookup_composite_function (op,
827                                    src_format, src_flags,
828                                    mask_format, mask_flags,
829                                    dest_format, dest_flags,
830                                    &imp, &func))
831     {
832         const pixman_box32_t *pbox;
833         int n;
834
835         pbox = pixman_region32_rectangles (&region, &n);
836         
837         while (n--)
838         {
839             func (imp, op,
840                   src, mask, dest,
841                   pbox->x1 + src_x - dest_x,
842                   pbox->y1 + src_y - dest_y,
843                   pbox->x1 + mask_x - dest_x,
844                   pbox->y1 + mask_y - dest_y,
845                   pbox->x1,
846                   pbox->y1,
847                   pbox->x2 - pbox->x1,
848                   pbox->y2 - pbox->y1);
849             
850             pbox++;
851         }
852     }
853
854 out:
855     if (need_workaround)
856     {
857         unapply_workaround (src, src_bits, src_dx, src_dy);
858         unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
859         unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
860     }
861
862     pixman_region32_fini (&region);
863 }
864
865 PIXMAN_EXPORT void
866 pixman_image_composite (pixman_op_t      op,
867                         pixman_image_t * src,
868                         pixman_image_t * mask,
869                         pixman_image_t * dest,
870                         int16_t          src_x,
871                         int16_t          src_y,
872                         int16_t          mask_x,
873                         int16_t          mask_y,
874                         int16_t          dest_x,
875                         int16_t          dest_y,
876                         uint16_t         width,
877                         uint16_t         height)
878 {
879     pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
880                               mask_x, mask_y, dest_x, dest_y, width, height);
881 }
882
883 PIXMAN_EXPORT pixman_bool_t
884 pixman_blt (uint32_t *src_bits,
885             uint32_t *dst_bits,
886             int       src_stride,
887             int       dst_stride,
888             int       src_bpp,
889             int       dst_bpp,
890             int       src_x,
891             int       src_y,
892             int       dst_x,
893             int       dst_y,
894             int       width,
895             int       height)
896 {
897     return _pixman_implementation_blt (get_implementation(),
898                                        src_bits, dst_bits, src_stride, dst_stride,
899                                        src_bpp, dst_bpp,
900                                        src_x, src_y,
901                                        dst_x, dst_y,
902                                        width, height);
903 }
904
905 PIXMAN_EXPORT pixman_bool_t
906 pixman_fill (uint32_t *bits,
907              int       stride,
908              int       bpp,
909              int       x,
910              int       y,
911              int       width,
912              int       height,
913              uint32_t xor)
914 {
915     return _pixman_implementation_fill (
916         get_implementation(), bits, stride, bpp, x, y, width, height, xor);
917 }
918
919 static uint32_t
920 color_to_uint32 (const pixman_color_t *color)
921 {
922     return
923         (color->alpha >> 8 << 24) |
924         (color->red >> 8 << 16) |
925         (color->green & 0xff00) |
926         (color->blue >> 8);
927 }
928
929 static pixman_bool_t
930 color_to_pixel (pixman_color_t *     color,
931                 uint32_t *           pixel,
932                 pixman_format_code_t format)
933 {
934     uint32_t c = color_to_uint32 (color);
935
936     if (!(format == PIXMAN_a8r8g8b8     ||
937           format == PIXMAN_x8r8g8b8     ||
938           format == PIXMAN_a8b8g8r8     ||
939           format == PIXMAN_x8b8g8r8     ||
940           format == PIXMAN_b8g8r8a8     ||
941           format == PIXMAN_b8g8r8x8     ||
942           format == PIXMAN_r5g6b5       ||
943           format == PIXMAN_b5g6r5       ||
944           format == PIXMAN_a8))
945     {
946         return FALSE;
947     }
948
949     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
950     {
951         c = ((c & 0xff000000) >>  0) |
952             ((c & 0x00ff0000) >> 16) |
953             ((c & 0x0000ff00) >>  0) |
954             ((c & 0x000000ff) << 16);
955     }
956     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
957     {
958         c = ((c & 0xff000000) >> 24) |
959             ((c & 0x00ff0000) >>  8) |
960             ((c & 0x0000ff00) <<  8) |
961             ((c & 0x000000ff) << 24);
962     }
963
964     if (format == PIXMAN_a8)
965         c = c >> 24;
966     else if (format == PIXMAN_r5g6b5 ||
967              format == PIXMAN_b5g6r5)
968         c = CONVERT_8888_TO_0565 (c);
969
970 #if 0
971     printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
972     printf ("pixel: %x\n", c);
973 #endif
974
975     *pixel = c;
976     return TRUE;
977 }
978
979 PIXMAN_EXPORT pixman_bool_t
980 pixman_image_fill_rectangles (pixman_op_t                 op,
981                               pixman_image_t *            dest,
982                               pixman_color_t *            color,
983                               int                         n_rects,
984                               const pixman_rectangle16_t *rects)
985 {
986     pixman_box32_t stack_boxes[6];
987     pixman_box32_t *boxes;
988     pixman_bool_t result;
989     int i;
990
991     if (n_rects > 6)
992     {
993         boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
994         if (boxes == NULL)
995             return FALSE;
996     }
997     else
998     {
999         boxes = stack_boxes;
1000     }
1001
1002     for (i = 0; i < n_rects; ++i)
1003     {
1004         boxes[i].x1 = rects[i].x;
1005         boxes[i].y1 = rects[i].y;
1006         boxes[i].x2 = boxes[i].x1 + rects[i].width;
1007         boxes[i].y2 = boxes[i].y1 + rects[i].height;
1008     }
1009
1010     result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
1011
1012     if (boxes != stack_boxes)
1013         free (boxes);
1014     
1015     return result;
1016 }
1017
1018 PIXMAN_EXPORT pixman_bool_t
1019 pixman_image_fill_boxes (pixman_op_t           op,
1020                          pixman_image_t *      dest,
1021                          pixman_color_t *      color,
1022                          int                   n_boxes,
1023                          const pixman_box32_t *boxes)
1024 {
1025     pixman_image_t *solid;
1026     pixman_color_t c;
1027     int i;
1028
1029     _pixman_image_validate (dest);
1030     
1031     if (color->alpha == 0xffff)
1032     {
1033         if (op == PIXMAN_OP_OVER)
1034             op = PIXMAN_OP_SRC;
1035     }
1036
1037     if (op == PIXMAN_OP_CLEAR)
1038     {
1039         c.red = 0;
1040         c.green = 0;
1041         c.blue = 0;
1042         c.alpha = 0;
1043
1044         color = &c;
1045
1046         op = PIXMAN_OP_SRC;
1047     }
1048
1049     if (op == PIXMAN_OP_SRC)
1050     {
1051         uint32_t pixel;
1052
1053         if (color_to_pixel (color, &pixel, dest->bits.format))
1054         {
1055             pixman_region32_t fill_region;
1056             int n_rects, j;
1057             pixman_box32_t *rects;
1058
1059             if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
1060                 return FALSE;
1061
1062             if (dest->common.have_clip_region)
1063             {
1064                 if (!pixman_region32_intersect (&fill_region,
1065                                                 &fill_region,
1066                                                 &dest->common.clip_region))
1067                     return FALSE;
1068             }
1069
1070             rects = pixman_region32_rectangles (&fill_region, &n_rects);
1071             for (j = 0; j < n_rects; ++j)
1072             {
1073                 const pixman_box32_t *rect = &(rects[j]);
1074                 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
1075                              rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
1076                              pixel);
1077             }
1078
1079             pixman_region32_fini (&fill_region);
1080             return TRUE;
1081         }
1082     }
1083
1084     solid = pixman_image_create_solid_fill (color);
1085     if (!solid)
1086         return FALSE;
1087
1088     for (i = 0; i < n_boxes; ++i)
1089     {
1090         const pixman_box32_t *box = &(boxes[i]);
1091
1092         pixman_image_composite32 (op, solid, NULL, dest,
1093                                   0, 0, 0, 0,
1094                                   box->x1, box->y1,
1095                                   box->x2 - box->x1, box->y2 - box->y1);
1096     }
1097
1098     pixman_image_unref (solid);
1099
1100     return TRUE;
1101 }
1102
1103 /**
1104  * pixman_version:
1105  *
1106  * Returns the version of the pixman library encoded in a single
1107  * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
1108  * later versions compare greater than earlier versions.
1109  *
1110  * A run-time comparison to check that pixman's version is greater than
1111  * or equal to version X.Y.Z could be performed as follows:
1112  *
1113  * <informalexample><programlisting>
1114  * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1115  * </programlisting></informalexample>
1116  *
1117  * See also pixman_version_string() as well as the compile-time
1118  * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1119  *
1120  * Return value: the encoded version.
1121  **/
1122 PIXMAN_EXPORT int
1123 pixman_version (void)
1124 {
1125     return PIXMAN_VERSION;
1126 }
1127
1128 /**
1129  * pixman_version_string:
1130  *
1131  * Returns the version of the pixman library as a human-readable string
1132  * of the form "X.Y.Z".
1133  *
1134  * See also pixman_version() as well as the compile-time equivalents
1135  * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1136  *
1137  * Return value: a string containing the version.
1138  **/
1139 PIXMAN_EXPORT const char*
1140 pixman_version_string (void)
1141 {
1142     return PIXMAN_VERSION_STRING;
1143 }
1144
1145 /**
1146  * pixman_format_supported_source:
1147  * @format: A pixman_format_code_t format
1148  *
1149  * Return value: whether the provided format code is a supported
1150  * format for a pixman surface used as a source in
1151  * rendering.
1152  *
1153  * Currently, all pixman_format_code_t values are supported.
1154  **/
1155 PIXMAN_EXPORT pixman_bool_t
1156 pixman_format_supported_source (pixman_format_code_t format)
1157 {
1158     switch (format)
1159     {
1160     /* 32 bpp formats */
1161     case PIXMAN_a2b10g10r10:
1162     case PIXMAN_x2b10g10r10:
1163     case PIXMAN_a2r10g10b10:
1164     case PIXMAN_x2r10g10b10:
1165     case PIXMAN_a8r8g8b8:
1166     case PIXMAN_x8r8g8b8:
1167     case PIXMAN_a8b8g8r8:
1168     case PIXMAN_x8b8g8r8:
1169     case PIXMAN_b8g8r8a8:
1170     case PIXMAN_b8g8r8x8:
1171     case PIXMAN_r8g8b8:
1172     case PIXMAN_b8g8r8:
1173     case PIXMAN_r5g6b5:
1174     case PIXMAN_b5g6r5:
1175     case PIXMAN_x14r6g6b6:
1176     /* 16 bpp formats */
1177     case PIXMAN_a1r5g5b5:
1178     case PIXMAN_x1r5g5b5:
1179     case PIXMAN_a1b5g5r5:
1180     case PIXMAN_x1b5g5r5:
1181     case PIXMAN_a4r4g4b4:
1182     case PIXMAN_x4r4g4b4:
1183     case PIXMAN_a4b4g4r4:
1184     case PIXMAN_x4b4g4r4:
1185     /* 8bpp formats */
1186     case PIXMAN_a8:
1187     case PIXMAN_r3g3b2:
1188     case PIXMAN_b2g3r3:
1189     case PIXMAN_a2r2g2b2:
1190     case PIXMAN_a2b2g2r2:
1191     case PIXMAN_c8:
1192     case PIXMAN_g8:
1193     case PIXMAN_x4a4:
1194     /* Collides with PIXMAN_c8
1195        case PIXMAN_x4c4:
1196      */
1197     /* Collides with PIXMAN_g8
1198        case PIXMAN_x4g4:
1199      */
1200     /* 4bpp formats */
1201     case PIXMAN_a4:
1202     case PIXMAN_r1g2b1:
1203     case PIXMAN_b1g2r1:
1204     case PIXMAN_a1r1g1b1:
1205     case PIXMAN_a1b1g1r1:
1206     case PIXMAN_c4:
1207     case PIXMAN_g4:
1208     /* 1bpp formats */
1209     case PIXMAN_a1:
1210     case PIXMAN_g1:
1211     /* YUV formats */
1212     case PIXMAN_yuy2:
1213     case PIXMAN_yv12:
1214         return TRUE;
1215
1216     default:
1217         return FALSE;
1218     }
1219 }
1220
1221 /**
1222  * pixman_format_supported_destination:
1223  * @format: A pixman_format_code_t format
1224  *
1225  * Return value: whether the provided format code is a supported
1226  * format for a pixman surface used as a destination in
1227  * rendering.
1228  *
1229  * Currently, all pixman_format_code_t values are supported
1230  * except for the YUV formats.
1231  **/
1232 PIXMAN_EXPORT pixman_bool_t
1233 pixman_format_supported_destination (pixman_format_code_t format)
1234 {
1235     /* YUV formats cannot be written to at the moment */
1236     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1237         return FALSE;
1238
1239     return pixman_format_supported_source (format);
1240 }
1241
1242 PIXMAN_EXPORT pixman_bool_t
1243 pixman_compute_composite_region (pixman_region16_t * region,
1244                                  pixman_image_t *    src_image,
1245                                  pixman_image_t *    mask_image,
1246                                  pixman_image_t *    dst_image,
1247                                  int16_t             src_x,
1248                                  int16_t             src_y,
1249                                  int16_t             mask_x,
1250                                  int16_t             mask_y,
1251                                  int16_t             dest_x,
1252                                  int16_t             dest_y,
1253                                  uint16_t            width,
1254                                  uint16_t            height)
1255 {
1256     pixman_region32_t r32;
1257     pixman_bool_t retval;
1258
1259     pixman_region32_init (&r32);
1260
1261     retval = pixman_compute_composite_region32 (
1262         &r32, src_image, mask_image, dst_image,
1263         src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1264         width, height);
1265
1266     if (retval)
1267     {
1268         if (!pixman_region16_copy_from_region32 (region, &r32))
1269             retval = FALSE;
1270     }
1271
1272     pixman_region32_fini (&r32);
1273     return retval;
1274 }