pixman-image.c: Fix typo in pixman_image_set_transform()
[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 *    dest_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, dest_image->bits.width);
259     region->extents.y2 = MIN (region->extents.y2, dest_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 (dest_image->common.have_clip_region)
275     {
276         if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
277             return FALSE;
278     }
279
280     if (dest_image->common.alpha_map)
281     {
282         if (!pixman_region32_intersect_rect (region, region,
283                                              dest_image->common.alpha_origin_x,
284                                              dest_image->common.alpha_origin_y,
285                                              dest_image->common.alpha_map->width,
286                                              dest_image->common.alpha_map->height))
287         {
288             return FALSE;
289         }
290         if (!pixman_region32_not_empty (region))
291             return FALSE;
292         if (dest_image->common.alpha_map->common.have_clip_region)
293         {
294             if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
295                                      -dest_image->common.alpha_origin_x,
296                                      -dest_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 typedef struct
339 {
340     pixman_fixed_48_16_t        x1;
341     pixman_fixed_48_16_t        y1;
342     pixman_fixed_48_16_t        x2;
343     pixman_fixed_48_16_t        y2;
344 } box_48_16_t;
345
346 static pixman_bool_t
347 compute_transformed_extents (pixman_transform_t *transform,
348                              const pixman_box32_t *extents,
349                              box_48_16_t *transformed)
350 {
351     pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
352     pixman_fixed_t x1, y1, x2, y2;
353     int i;
354
355     x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
356     y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
357     x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
358     y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
359
360     if (!transform)
361     {
362         transformed->x1 = x1;
363         transformed->y1 = y1;
364         transformed->x2 = x2;
365         transformed->y2 = y2;
366
367         return TRUE;
368     }
369
370     tx1 = ty1 = INT64_MAX;
371     tx2 = ty2 = INT64_MIN;
372
373     for (i = 0; i < 4; ++i)
374     {
375         pixman_fixed_48_16_t tx, ty;
376         pixman_vector_t v;
377
378         v.vector[0] = (i & 0x01)? x1 : x2;
379         v.vector[1] = (i & 0x02)? y1 : y2;
380         v.vector[2] = pixman_fixed_1;
381
382         if (!pixman_transform_point (transform, &v))
383             return FALSE;
384
385         tx = (pixman_fixed_48_16_t)v.vector[0];
386         ty = (pixman_fixed_48_16_t)v.vector[1];
387
388         if (tx < tx1)
389             tx1 = tx;
390         if (ty < ty1)
391             ty1 = ty;
392         if (tx > tx2)
393             tx2 = tx;
394         if (ty > ty2)
395             ty2 = ty;
396     }
397
398     transformed->x1 = tx1;
399     transformed->y1 = ty1;
400     transformed->x2 = tx2;
401     transformed->y2 = ty2;
402
403     return TRUE;
404 }
405
406 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
407 #define ABS(f)      (((f) < 0)?  (-(f)) : (f))
408 #define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
409
410 static pixman_bool_t
411 analyze_extent (pixman_image_t       *image,
412                 const pixman_box32_t *extents,
413                 uint32_t             *flags)
414 {
415     pixman_transform_t *transform;
416     pixman_fixed_t x_off, y_off;
417     pixman_fixed_t width, height;
418     pixman_fixed_t *params;
419     box_48_16_t transformed;
420     pixman_box32_t exp_extents;
421
422     if (!image)
423         return TRUE;
424
425     /* Some compositing functions walk one step
426      * outside the destination rectangle, so we
427      * check here that the expanded-by-one source
428      * extents in destination space fits in 16 bits
429      */
430     if (!IS_16BIT (extents->x1 - 1)             ||
431         !IS_16BIT (extents->y1 - 1)             ||
432         !IS_16BIT (extents->x2 + 1)             ||
433         !IS_16BIT (extents->y2 + 1))
434     {
435         return FALSE;
436     }
437
438     transform = image->common.transform;
439     if (image->common.type == BITS)
440     {
441         /* During repeat mode calculations we might convert the
442          * width/height of an image to fixed 16.16, so we need
443          * them to be smaller than 16 bits.
444          */
445         if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
446             return FALSE;
447
448         if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
449             extents->x1 >= 0 &&
450             extents->y1 >= 0 &&
451             extents->x2 <= image->bits.width &&
452             extents->y2 <= image->bits.height)
453         {
454             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
455             return TRUE;
456         }
457
458         switch (image->common.filter)
459         {
460         case PIXMAN_FILTER_CONVOLUTION:
461             params = image->common.filter_params;
462             x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
463             y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
464             width = params[0];
465             height = params[1];
466             break;
467
468         case PIXMAN_FILTER_GOOD:
469         case PIXMAN_FILTER_BEST:
470         case PIXMAN_FILTER_BILINEAR:
471             x_off = - pixman_fixed_1 / 2;
472             y_off = - pixman_fixed_1 / 2;
473             width = pixman_fixed_1;
474             height = pixman_fixed_1;
475             break;
476
477         case PIXMAN_FILTER_FAST:
478         case PIXMAN_FILTER_NEAREST:
479             x_off = - pixman_fixed_e;
480             y_off = - pixman_fixed_e;
481             width = 0;
482             height = 0;
483             break;
484
485         default:
486             return FALSE;
487         }
488     }
489     else
490     {
491         x_off = 0;
492         y_off = 0;
493         width = 0;
494         height = 0;
495     }
496
497     if (!compute_transformed_extents (transform, extents, &transformed))
498         return FALSE;
499
500     /* Expand the source area by a tiny bit so account of different rounding that
501      * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
502      * 0.5 so this won't cause the area computed to be overly pessimistic.
503      */
504     transformed.x1 -= 8 * pixman_fixed_e;
505     transformed.y1 -= 8 * pixman_fixed_e;
506     transformed.x2 += 8 * pixman_fixed_e;
507     transformed.y2 += 8 * pixman_fixed_e;
508
509     if (image->common.type == BITS)
510     {
511         if (pixman_fixed_to_int (transformed.x1) >= 0                   &&
512             pixman_fixed_to_int (transformed.y1) >= 0                   &&
513             pixman_fixed_to_int (transformed.x2) < image->bits.width    &&
514             pixman_fixed_to_int (transformed.y2) < image->bits.height)
515         {
516             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
517         }
518
519         if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0                &&
520             pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0                &&
521             pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
522             pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
523         {
524             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
525         }
526     }
527
528     /* Check we don't overflow when the destination extents are expanded by one.
529      * This ensures that compositing functions can simply walk the source space
530      * using 16.16 variables without worrying about overflow.
531      */
532     exp_extents = *extents;
533     exp_extents.x1 -= 1;
534     exp_extents.y1 -= 1;
535     exp_extents.x2 += 1;
536     exp_extents.y2 += 1;
537
538     if (!compute_transformed_extents (transform, &exp_extents, &transformed))
539         return FALSE;
540     
541     if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) ||
542         !IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) ||
543         !IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) ||
544         !IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
545     {
546         return FALSE;
547     }
548
549     return TRUE;
550 }
551
552 /*
553  * Work around GCC bug causing crashes in Mozilla with SSE2
554  *
555  * When using -msse, gcc generates movdqa instructions assuming that
556  * the stack is 16 byte aligned. Unfortunately some applications, such
557  * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
558  * causes the movdqa instructions to fail.
559  *
560  * The __force_align_arg_pointer__ makes gcc generate a prologue that
561  * realigns the stack pointer to 16 bytes.
562  *
563  * On x86-64 this is not necessary because the standard ABI already
564  * calls for a 16 byte aligned stack.
565  *
566  * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
567  */
568 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
569 __attribute__((__force_align_arg_pointer__))
570 #endif
571 PIXMAN_EXPORT void
572 pixman_image_composite32 (pixman_op_t      op,
573                           pixman_image_t * src,
574                           pixman_image_t * mask,
575                           pixman_image_t * dest,
576                           int32_t          src_x,
577                           int32_t          src_y,
578                           int32_t          mask_x,
579                           int32_t          mask_y,
580                           int32_t          dest_x,
581                           int32_t          dest_y,
582                           int32_t          width,
583                           int32_t          height)
584 {
585     pixman_format_code_t src_format, mask_format, dest_format;
586     uint32_t src_flags, mask_flags, dest_flags;
587     pixman_region32_t region;
588     pixman_box32_t extents;
589     pixman_implementation_t *imp;
590     pixman_composite_func_t func;
591
592     _pixman_image_validate (src);
593     if (mask)
594         _pixman_image_validate (mask);
595     _pixman_image_validate (dest);
596
597     src_format = src->common.extended_format_code;
598     src_flags = src->common.flags;
599
600     if (mask)
601     {
602         mask_format = mask->common.extended_format_code;
603         mask_flags = mask->common.flags;
604     }
605     else
606     {
607         mask_format = PIXMAN_null;
608         mask_flags = FAST_PATH_IS_OPAQUE;
609     }
610
611     dest_format = dest->common.extended_format_code;
612     dest_flags = dest->common.flags;
613
614     /* Check for pixbufs */
615     if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
616         (src->type == BITS && src->bits.bits == mask->bits.bits)           &&
617         (src->common.repeat == mask->common.repeat)                        &&
618         (src_x == mask_x && src_y == mask_y))
619     {
620         if (src_format == PIXMAN_x8b8g8r8)
621             src_format = mask_format = PIXMAN_pixbuf;
622         else if (src_format == PIXMAN_x8r8g8b8)
623             src_format = mask_format = PIXMAN_rpixbuf;
624     }
625
626     pixman_region32_init (&region);
627
628     if (!pixman_compute_composite_region32 (
629             &region, src, mask, dest,
630             src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
631     {
632         goto out;
633     }
634
635     extents = *pixman_region32_extents (&region);
636
637     extents.x1 -= dest_x - src_x;
638     extents.y1 -= dest_y - src_y;
639     extents.x2 -= dest_x - src_x;
640     extents.y2 -= dest_y - src_y;
641
642     if (!analyze_extent (src, &extents, &src_flags))
643         goto out;
644
645     extents.x1 -= src_x - mask_x;
646     extents.y1 -= src_y - mask_y;
647     extents.x2 -= src_x - mask_x;
648     extents.y2 -= src_y - mask_y;
649
650     if (!analyze_extent (mask, &extents, &mask_flags))
651         goto out;
652
653     /* If the clip is within the source samples, and the samples are
654      * opaque, then the source is effectively opaque.
655      */
656 #define NEAREST_OPAQUE  (FAST_PATH_SAMPLES_OPAQUE |                     \
657                          FAST_PATH_NEAREST_FILTER |                     \
658                          FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
659 #define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE |                     \
660                          FAST_PATH_BILINEAR_FILTER |                    \
661                          FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
662
663     if ((src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
664         (src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
665     {
666         src_flags |= FAST_PATH_IS_OPAQUE;
667     }
668
669     if ((mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
670         (mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
671     {
672         mask_flags |= FAST_PATH_IS_OPAQUE;
673     }
674
675     /*
676      * Check if we can replace our operator by a simpler one
677      * if the src or dest are opaque. The output operator should be
678      * mathematically equivalent to the source.
679      */
680     op = optimize_operator (op, src_flags, mask_flags, dest_flags);
681
682     if (_pixman_lookup_composite_function (
683             get_implementation (), op,
684             src_format, src_flags, mask_format, mask_flags, dest_format, dest_flags,
685             &imp, &func))
686     {
687         pixman_composite_info_t info;
688         const pixman_box32_t *pbox;
689         int n;
690
691         info.op = op;
692         info.src_image = src;
693         info.mask_image = mask;
694         info.dest_image = dest;
695         info.src_flags = src_flags;
696         info.mask_flags = mask_flags;
697         info.dest_flags = dest_flags;
698
699         pbox = pixman_region32_rectangles (&region, &n);
700
701         while (n--)
702         {
703             info.src_x = pbox->x1 + src_x - dest_x;
704             info.src_y = pbox->y1 + src_y - dest_y;
705             info.mask_x = pbox->x1 + mask_x - dest_x;
706             info.mask_y = pbox->y1 + mask_y - dest_y;
707             info.dest_x = pbox->x1;
708             info.dest_y = pbox->y1;
709             info.width = pbox->x2 - pbox->x1;
710             info.height = pbox->y2 - pbox->y1;
711
712             func (imp, &info);
713
714             pbox++;
715         }
716     }
717
718 out:
719     pixman_region32_fini (&region);
720 }
721
722 PIXMAN_EXPORT void
723 pixman_image_composite (pixman_op_t      op,
724                         pixman_image_t * src,
725                         pixman_image_t * mask,
726                         pixman_image_t * dest,
727                         int16_t          src_x,
728                         int16_t          src_y,
729                         int16_t          mask_x,
730                         int16_t          mask_y,
731                         int16_t          dest_x,
732                         int16_t          dest_y,
733                         uint16_t         width,
734                         uint16_t         height)
735 {
736     pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
737                               mask_x, mask_y, dest_x, dest_y, width, height);
738 }
739
740 PIXMAN_EXPORT pixman_bool_t
741 pixman_blt (uint32_t *src_bits,
742             uint32_t *dst_bits,
743             int       src_stride,
744             int       dst_stride,
745             int       src_bpp,
746             int       dst_bpp,
747             int       src_x,
748             int       src_y,
749             int       dest_x,
750             int       dest_y,
751             int       width,
752             int       height)
753 {
754     return _pixman_implementation_blt (get_implementation(),
755                                        src_bits, dst_bits, src_stride, dst_stride,
756                                        src_bpp, dst_bpp,
757                                        src_x, src_y,
758                                        dest_x, dest_y,
759                                        width, height);
760 }
761
762 PIXMAN_EXPORT pixman_bool_t
763 pixman_fill (uint32_t *bits,
764              int       stride,
765              int       bpp,
766              int       x,
767              int       y,
768              int       width,
769              int       height,
770              uint32_t xor)
771 {
772     return _pixman_implementation_fill (
773         get_implementation(), bits, stride, bpp, x, y, width, height, xor);
774 }
775
776 static uint32_t
777 color_to_uint32 (const pixman_color_t *color)
778 {
779     return
780         (color->alpha >> 8 << 24) |
781         (color->red >> 8 << 16) |
782         (color->green & 0xff00) |
783         (color->blue >> 8);
784 }
785
786 static pixman_bool_t
787 color_to_pixel (pixman_color_t *     color,
788                 uint32_t *           pixel,
789                 pixman_format_code_t format)
790 {
791     uint32_t c = color_to_uint32 (color);
792
793     if (!(format == PIXMAN_a8r8g8b8     ||
794           format == PIXMAN_x8r8g8b8     ||
795           format == PIXMAN_a8b8g8r8     ||
796           format == PIXMAN_x8b8g8r8     ||
797           format == PIXMAN_b8g8r8a8     ||
798           format == PIXMAN_b8g8r8x8     ||
799           format == PIXMAN_r8g8b8a8     ||
800           format == PIXMAN_r8g8b8x8     ||
801           format == PIXMAN_r5g6b5       ||
802           format == PIXMAN_b5g6r5       ||
803           format == PIXMAN_a8           ||
804           format == PIXMAN_a1))
805     {
806         return FALSE;
807     }
808
809     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
810     {
811         c = ((c & 0xff000000) >>  0) |
812             ((c & 0x00ff0000) >> 16) |
813             ((c & 0x0000ff00) >>  0) |
814             ((c & 0x000000ff) << 16);
815     }
816     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
817     {
818         c = ((c & 0xff000000) >> 24) |
819             ((c & 0x00ff0000) >>  8) |
820             ((c & 0x0000ff00) <<  8) |
821             ((c & 0x000000ff) << 24);
822     }
823     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
824         c = ((c & 0xff000000) >> 24) | (c << 8);
825
826     if (format == PIXMAN_a1)
827         c = c >> 31;
828     else if (format == PIXMAN_a8)
829         c = c >> 24;
830     else if (format == PIXMAN_r5g6b5 ||
831              format == PIXMAN_b5g6r5)
832         c = CONVERT_8888_TO_0565 (c);
833
834 #if 0
835     printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
836     printf ("pixel: %x\n", c);
837 #endif
838
839     *pixel = c;
840     return TRUE;
841 }
842
843 PIXMAN_EXPORT pixman_bool_t
844 pixman_image_fill_rectangles (pixman_op_t                 op,
845                               pixman_image_t *            dest,
846                               pixman_color_t *            color,
847                               int                         n_rects,
848                               const pixman_rectangle16_t *rects)
849 {
850     pixman_box32_t stack_boxes[6];
851     pixman_box32_t *boxes;
852     pixman_bool_t result;
853     int i;
854
855     if (n_rects > 6)
856     {
857         boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
858         if (boxes == NULL)
859             return FALSE;
860     }
861     else
862     {
863         boxes = stack_boxes;
864     }
865
866     for (i = 0; i < n_rects; ++i)
867     {
868         boxes[i].x1 = rects[i].x;
869         boxes[i].y1 = rects[i].y;
870         boxes[i].x2 = boxes[i].x1 + rects[i].width;
871         boxes[i].y2 = boxes[i].y1 + rects[i].height;
872     }
873
874     result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
875
876     if (boxes != stack_boxes)
877         free (boxes);
878     
879     return result;
880 }
881
882 PIXMAN_EXPORT pixman_bool_t
883 pixman_image_fill_boxes (pixman_op_t           op,
884                          pixman_image_t *      dest,
885                          pixman_color_t *      color,
886                          int                   n_boxes,
887                          const pixman_box32_t *boxes)
888 {
889     pixman_image_t *solid;
890     pixman_color_t c;
891     int i;
892
893     _pixman_image_validate (dest);
894     
895     if (color->alpha == 0xffff)
896     {
897         if (op == PIXMAN_OP_OVER)
898             op = PIXMAN_OP_SRC;
899     }
900
901     if (op == PIXMAN_OP_CLEAR)
902     {
903         c.red = 0;
904         c.green = 0;
905         c.blue = 0;
906         c.alpha = 0;
907
908         color = &c;
909
910         op = PIXMAN_OP_SRC;
911     }
912
913     if (op == PIXMAN_OP_SRC)
914     {
915         uint32_t pixel;
916
917         if (color_to_pixel (color, &pixel, dest->bits.format))
918         {
919             pixman_region32_t fill_region;
920             int n_rects, j;
921             pixman_box32_t *rects;
922
923             if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
924                 return FALSE;
925
926             if (dest->common.have_clip_region)
927             {
928                 if (!pixman_region32_intersect (&fill_region,
929                                                 &fill_region,
930                                                 &dest->common.clip_region))
931                     return FALSE;
932             }
933
934             rects = pixman_region32_rectangles (&fill_region, &n_rects);
935             for (j = 0; j < n_rects; ++j)
936             {
937                 const pixman_box32_t *rect = &(rects[j]);
938                 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
939                              rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
940                              pixel);
941             }
942
943             pixman_region32_fini (&fill_region);
944             return TRUE;
945         }
946     }
947
948     solid = pixman_image_create_solid_fill (color);
949     if (!solid)
950         return FALSE;
951
952     for (i = 0; i < n_boxes; ++i)
953     {
954         const pixman_box32_t *box = &(boxes[i]);
955
956         pixman_image_composite32 (op, solid, NULL, dest,
957                                   0, 0, 0, 0,
958                                   box->x1, box->y1,
959                                   box->x2 - box->x1, box->y2 - box->y1);
960     }
961
962     pixman_image_unref (solid);
963
964     return TRUE;
965 }
966
967 /**
968  * pixman_version:
969  *
970  * Returns the version of the pixman library encoded in a single
971  * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
972  * later versions compare greater than earlier versions.
973  *
974  * A run-time comparison to check that pixman's version is greater than
975  * or equal to version X.Y.Z could be performed as follows:
976  *
977  * <informalexample><programlisting>
978  * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
979  * </programlisting></informalexample>
980  *
981  * See also pixman_version_string() as well as the compile-time
982  * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
983  *
984  * Return value: the encoded version.
985  **/
986 PIXMAN_EXPORT int
987 pixman_version (void)
988 {
989     return PIXMAN_VERSION;
990 }
991
992 /**
993  * pixman_version_string:
994  *
995  * Returns the version of the pixman library as a human-readable string
996  * of the form "X.Y.Z".
997  *
998  * See also pixman_version() as well as the compile-time equivalents
999  * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1000  *
1001  * Return value: a string containing the version.
1002  **/
1003 PIXMAN_EXPORT const char*
1004 pixman_version_string (void)
1005 {
1006     return PIXMAN_VERSION_STRING;
1007 }
1008
1009 /**
1010  * pixman_format_supported_source:
1011  * @format: A pixman_format_code_t format
1012  *
1013  * Return value: whether the provided format code is a supported
1014  * format for a pixman surface used as a source in
1015  * rendering.
1016  *
1017  * Currently, all pixman_format_code_t values are supported.
1018  **/
1019 PIXMAN_EXPORT pixman_bool_t
1020 pixman_format_supported_source (pixman_format_code_t format)
1021 {
1022     switch (format)
1023     {
1024     /* 32 bpp formats */
1025     case PIXMAN_a2b10g10r10:
1026     case PIXMAN_x2b10g10r10:
1027     case PIXMAN_a2r10g10b10:
1028     case PIXMAN_x2r10g10b10:
1029     case PIXMAN_a8r8g8b8:
1030     case PIXMAN_x8r8g8b8:
1031     case PIXMAN_a8b8g8r8:
1032     case PIXMAN_x8b8g8r8:
1033     case PIXMAN_b8g8r8a8:
1034     case PIXMAN_b8g8r8x8:
1035     case PIXMAN_r8g8b8a8:
1036     case PIXMAN_r8g8b8x8:
1037     case PIXMAN_r8g8b8:
1038     case PIXMAN_b8g8r8:
1039     case PIXMAN_r5g6b5:
1040     case PIXMAN_b5g6r5:
1041     case PIXMAN_x14r6g6b6:
1042     /* 16 bpp formats */
1043     case PIXMAN_a1r5g5b5:
1044     case PIXMAN_x1r5g5b5:
1045     case PIXMAN_a1b5g5r5:
1046     case PIXMAN_x1b5g5r5:
1047     case PIXMAN_a4r4g4b4:
1048     case PIXMAN_x4r4g4b4:
1049     case PIXMAN_a4b4g4r4:
1050     case PIXMAN_x4b4g4r4:
1051     /* 8bpp formats */
1052     case PIXMAN_a8:
1053     case PIXMAN_r3g3b2:
1054     case PIXMAN_b2g3r3:
1055     case PIXMAN_a2r2g2b2:
1056     case PIXMAN_a2b2g2r2:
1057     case PIXMAN_c8:
1058     case PIXMAN_g8:
1059     case PIXMAN_x4a4:
1060     /* Collides with PIXMAN_c8
1061        case PIXMAN_x4c4:
1062      */
1063     /* Collides with PIXMAN_g8
1064        case PIXMAN_x4g4:
1065      */
1066     /* 4bpp formats */
1067     case PIXMAN_a4:
1068     case PIXMAN_r1g2b1:
1069     case PIXMAN_b1g2r1:
1070     case PIXMAN_a1r1g1b1:
1071     case PIXMAN_a1b1g1r1:
1072     case PIXMAN_c4:
1073     case PIXMAN_g4:
1074     /* 1bpp formats */
1075     case PIXMAN_a1:
1076     case PIXMAN_g1:
1077     /* YUV formats */
1078     case PIXMAN_yuy2:
1079     case PIXMAN_yv12:
1080         return TRUE;
1081
1082     default:
1083         return FALSE;
1084     }
1085 }
1086
1087 /**
1088  * pixman_format_supported_destination:
1089  * @format: A pixman_format_code_t format
1090  *
1091  * Return value: whether the provided format code is a supported
1092  * format for a pixman surface used as a destination in
1093  * rendering.
1094  *
1095  * Currently, all pixman_format_code_t values are supported
1096  * except for the YUV formats.
1097  **/
1098 PIXMAN_EXPORT pixman_bool_t
1099 pixman_format_supported_destination (pixman_format_code_t format)
1100 {
1101     /* YUV formats cannot be written to at the moment */
1102     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1103         return FALSE;
1104
1105     return pixman_format_supported_source (format);
1106 }
1107
1108 PIXMAN_EXPORT pixman_bool_t
1109 pixman_compute_composite_region (pixman_region16_t * region,
1110                                  pixman_image_t *    src_image,
1111                                  pixman_image_t *    mask_image,
1112                                  pixman_image_t *    dest_image,
1113                                  int16_t             src_x,
1114                                  int16_t             src_y,
1115                                  int16_t             mask_x,
1116                                  int16_t             mask_y,
1117                                  int16_t             dest_x,
1118                                  int16_t             dest_y,
1119                                  uint16_t            width,
1120                                  uint16_t            height)
1121 {
1122     pixman_region32_t r32;
1123     pixman_bool_t retval;
1124
1125     pixman_region32_init (&r32);
1126
1127     retval = pixman_compute_composite_region32 (
1128         &r32, src_image, mask_image, dest_image,
1129         src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1130         width, height);
1131
1132     if (retval)
1133     {
1134         if (!pixman_region16_copy_from_region32 (region, &r32))
1135             retval = FALSE;
1136     }
1137
1138     pixman_region32_fini (&r32);
1139     return retval;
1140 }