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