Add qemu 2.4.0
[kvmfornfv.git] / qemu / pixman / pixman / pixman-combine32.c
1 /*
2  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
3  *             2005 Lars Knoll & Zack Rusin, Trolltech
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of Keith Packard not be used in
10  * advertising or publicity pertaining to distribution of the software without
11  * specific, written prior permission.  Keith Packard makes no
12  * representations about the suitability of this software for any purpose.  It
13  * is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
21  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22  * SOFTWARE.
23  */
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <math.h>
29 #include <string.h>
30
31 #include "pixman-private.h"
32 #include "pixman-combine32.h"
33
34 /* component alpha helper functions */
35
36 static void
37 combine_mask_ca (uint32_t *src, uint32_t *mask)
38 {
39     uint32_t a = *mask;
40
41     uint32_t x;
42     uint16_t xa;
43
44     if (!a)
45     {
46         *(src) = 0;
47         return;
48     }
49
50     x = *(src);
51     if (a == ~0)
52     {
53         x = x >> A_SHIFT;
54         x |= x << G_SHIFT;
55         x |= x << R_SHIFT;
56         *(mask) = x;
57         return;
58     }
59
60     xa = x >> A_SHIFT;
61     UN8x4_MUL_UN8x4 (x, a);
62     *(src) = x;
63     
64     UN8x4_MUL_UN8 (a, xa);
65     *(mask) = a;
66 }
67
68 static void
69 combine_mask_value_ca (uint32_t *src, const uint32_t *mask)
70 {
71     uint32_t a = *mask;
72     uint32_t x;
73
74     if (!a)
75     {
76         *(src) = 0;
77         return;
78     }
79
80     if (a == ~0)
81         return;
82
83     x = *(src);
84     UN8x4_MUL_UN8x4 (x, a);
85     *(src) = x;
86 }
87
88 static void
89 combine_mask_alpha_ca (const uint32_t *src, uint32_t *mask)
90 {
91     uint32_t a = *(mask);
92     uint32_t x;
93
94     if (!a)
95         return;
96
97     x = *(src) >> A_SHIFT;
98     if (x == MASK)
99         return;
100
101     if (a == ~0)
102     {
103         x |= x << G_SHIFT;
104         x |= x << R_SHIFT;
105         *(mask) = x;
106         return;
107     }
108
109     UN8x4_MUL_UN8 (a, x);
110     *(mask) = a;
111 }
112
113 /*
114  * There are two ways of handling alpha -- either as a single unified value or
115  * a separate value for each component, hence each macro must have two
116  * versions.  The unified alpha version has a 'u' at the end of the name,
117  * the component version has a 'ca'.  Similarly, functions which deal with
118  * this difference will have two versions using the same convention.
119  */
120
121 static force_inline uint32_t
122 combine_mask (const uint32_t *src, const uint32_t *mask, int i)
123 {
124     uint32_t s, m;
125
126     if (mask)
127     {
128         m = *(mask + i) >> A_SHIFT;
129
130         if (!m)
131             return 0;
132     }
133
134     s = *(src + i);
135
136     if (mask)
137         UN8x4_MUL_UN8 (s, m);
138
139     return s;
140 }
141
142 static void
143 combine_clear (pixman_implementation_t *imp,
144                pixman_op_t              op,
145                uint32_t *               dest,
146                const uint32_t *         src,
147                const uint32_t *         mask,
148                int                      width)
149 {
150     memset (dest, 0, width * sizeof (uint32_t));
151 }
152
153 static void
154 combine_dst (pixman_implementation_t *imp,
155              pixman_op_t              op,
156              uint32_t *               dest,
157              const uint32_t *         src,
158              const uint32_t *         mask,
159              int                      width)
160 {
161     return;
162 }
163
164 static void
165 combine_src_u (pixman_implementation_t *imp,
166                pixman_op_t              op,
167                uint32_t *               dest,
168                const uint32_t *         src,
169                const uint32_t *         mask,
170                int                      width)
171 {
172     int i;
173
174     if (!mask)
175     {
176         memcpy (dest, src, width * sizeof (uint32_t));
177     }
178     else
179     {
180         for (i = 0; i < width; ++i)
181         {
182             uint32_t s = combine_mask (src, mask, i);
183
184             *(dest + i) = s;
185         }
186     }
187 }
188
189 static void
190 combine_over_u (pixman_implementation_t *imp,
191                 pixman_op_t              op,
192                 uint32_t *               dest,
193                 const uint32_t *         src,
194                 const uint32_t *         mask,
195                 int                      width)
196 {
197     int i;
198
199     if (!mask)
200     {
201         for (i = 0; i < width; ++i)
202         {
203             uint32_t s = *(src + i);
204             uint32_t a = ALPHA_8 (s);
205             if (a == 0xFF)
206             {
207                 *(dest + i) = s;
208             }
209             else if (s)
210             {
211                 uint32_t d = *(dest + i);
212                 uint32_t ia = a ^ 0xFF;
213                 UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
214                 *(dest + i) = d;
215             }
216         }
217     }
218     else
219     {
220         for (i = 0; i < width; ++i)
221         {
222             uint32_t m = ALPHA_8 (*(mask + i));
223             if (m == 0xFF)
224             {
225                 uint32_t s = *(src + i);
226                 uint32_t a = ALPHA_8 (s);
227                 if (a == 0xFF)
228                 {
229                     *(dest + i) = s;
230                 }
231                 else if (s)
232                 {
233                     uint32_t d = *(dest + i);
234                     uint32_t ia = a ^ 0xFF;
235                     UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
236                     *(dest + i) = d;
237                 }
238             }
239             else if (m)
240             {
241                 uint32_t s = *(src + i);
242                 if (s)
243                 {
244                     uint32_t d = *(dest + i);
245                     UN8x4_MUL_UN8 (s, m);
246                     UN8x4_MUL_UN8_ADD_UN8x4 (d, ALPHA_8 (~s), s);
247                     *(dest + i) = d;
248                 }
249             }
250         }
251     }
252 }
253
254 static void
255 combine_over_reverse_u (pixman_implementation_t *imp,
256                         pixman_op_t              op,
257                         uint32_t *               dest,
258                         const uint32_t *         src,
259                         const uint32_t *         mask,
260                         int                      width)
261 {
262     int i;
263
264     for (i = 0; i < width; ++i)
265     {
266         uint32_t s = combine_mask (src, mask, i);
267         uint32_t d = *(dest + i);
268         uint32_t ia = ALPHA_8 (~*(dest + i));
269         UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d);
270         *(dest + i) = s;
271     }
272 }
273
274 static void
275 combine_in_u (pixman_implementation_t *imp,
276               pixman_op_t              op,
277               uint32_t *               dest,
278               const uint32_t *         src,
279               const uint32_t *         mask,
280               int                      width)
281 {
282     int i;
283
284     for (i = 0; i < width; ++i)
285     {
286         uint32_t s = combine_mask (src, mask, i);
287         uint32_t a = ALPHA_8 (*(dest + i));
288         UN8x4_MUL_UN8 (s, a);
289         *(dest + i) = s;
290     }
291 }
292
293 static void
294 combine_in_reverse_u (pixman_implementation_t *imp,
295                       pixman_op_t              op,
296                       uint32_t *               dest,
297                       const uint32_t *         src,
298                       const uint32_t *         mask,
299                       int                      width)
300 {
301     int i;
302
303     for (i = 0; i < width; ++i)
304     {
305         uint32_t s = combine_mask (src, mask, i);
306         uint32_t d = *(dest + i);
307         uint32_t a = ALPHA_8 (s);
308         UN8x4_MUL_UN8 (d, a);
309         *(dest + i) = d;
310     }
311 }
312
313 static void
314 combine_out_u (pixman_implementation_t *imp,
315                pixman_op_t              op,
316                uint32_t *               dest,
317                const uint32_t *         src,
318                const uint32_t *         mask,
319                int                      width)
320 {
321     int i;
322
323     for (i = 0; i < width; ++i)
324     {
325         uint32_t s = combine_mask (src, mask, i);
326         uint32_t a = ALPHA_8 (~*(dest + i));
327         UN8x4_MUL_UN8 (s, a);
328         *(dest + i) = s;
329     }
330 }
331
332 static void
333 combine_out_reverse_u (pixman_implementation_t *imp,
334                        pixman_op_t              op,
335                        uint32_t *               dest,
336                        const uint32_t *         src,
337                        const uint32_t *         mask,
338                        int                      width)
339 {
340     int i;
341
342     for (i = 0; i < width; ++i)
343     {
344         uint32_t s = combine_mask (src, mask, i);
345         uint32_t d = *(dest + i);
346         uint32_t a = ALPHA_8 (~s);
347         UN8x4_MUL_UN8 (d, a);
348         *(dest + i) = d;
349     }
350 }
351
352 static void
353 combine_atop_u (pixman_implementation_t *imp,
354                 pixman_op_t              op,
355                 uint32_t *               dest,
356                 const uint32_t *         src,
357                 const uint32_t *         mask,
358                 int                      width)
359 {
360     int i;
361
362     for (i = 0; i < width; ++i)
363     {
364         uint32_t s = combine_mask (src, mask, i);
365         uint32_t d = *(dest + i);
366         uint32_t dest_a = ALPHA_8 (d);
367         uint32_t src_ia = ALPHA_8 (~s);
368
369         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia);
370         *(dest + i) = s;
371     }
372 }
373
374 static void
375 combine_atop_reverse_u (pixman_implementation_t *imp,
376                         pixman_op_t              op,
377                         uint32_t *               dest,
378                         const uint32_t *         src,
379                         const uint32_t *         mask,
380                         int                      width)
381 {
382     int i;
383
384     for (i = 0; i < width; ++i)
385     {
386         uint32_t s = combine_mask (src, mask, i);
387         uint32_t d = *(dest + i);
388         uint32_t src_a = ALPHA_8 (s);
389         uint32_t dest_ia = ALPHA_8 (~d);
390
391         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a);
392         *(dest + i) = s;
393     }
394 }
395
396 static void
397 combine_xor_u (pixman_implementation_t *imp,
398                pixman_op_t              op,
399                uint32_t *               dest,
400                const uint32_t *         src,
401                const uint32_t *         mask,
402                int                      width)
403 {
404     int i;
405
406     for (i = 0; i < width; ++i)
407     {
408         uint32_t s = combine_mask (src, mask, i);
409         uint32_t d = *(dest + i);
410         uint32_t src_ia = ALPHA_8 (~s);
411         uint32_t dest_ia = ALPHA_8 (~d);
412
413         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia);
414         *(dest + i) = s;
415     }
416 }
417
418 static void
419 combine_add_u (pixman_implementation_t *imp,
420                pixman_op_t              op,
421                uint32_t *               dest,
422                const uint32_t *         src,
423                const uint32_t *         mask,
424                int                      width)
425 {
426     int i;
427
428     for (i = 0; i < width; ++i)
429     {
430         uint32_t s = combine_mask (src, mask, i);
431         uint32_t d = *(dest + i);
432         UN8x4_ADD_UN8x4 (d, s);
433         *(dest + i) = d;
434     }
435 }
436
437 static void
438 combine_saturate_u (pixman_implementation_t *imp,
439                     pixman_op_t              op,
440                     uint32_t *               dest,
441                     const uint32_t *         src,
442                     const uint32_t *         mask,
443                     int                      width)
444 {
445     int i;
446
447     for (i = 0; i < width; ++i)
448     {
449         uint32_t s = combine_mask (src, mask, i);
450         uint32_t d = *(dest + i);
451         uint16_t sa, da;
452
453         sa = s >> A_SHIFT;
454         da = ~d >> A_SHIFT;
455         if (sa > da)
456         {
457             sa = DIV_UN8 (da, sa);
458             UN8x4_MUL_UN8 (s, sa);
459         }
460         ;
461         UN8x4_ADD_UN8x4 (d, s);
462         *(dest + i) = d;
463     }
464 }
465
466
467 /*
468  * PDF blend modes:
469  *
470  * The following blend modes have been taken from the PDF ISO 32000
471  * specification, which at this point in time is available from
472  *
473  *     http://www.adobe.com/devnet/pdf/pdf_reference.html
474  *
475  * The specific documents of interest are the PDF spec itself:
476  *
477  *     http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf
478  *
479  * chapters 11.3.5 and 11.3.6 and a later supplement for Adobe Acrobat
480  * 9.1 and Reader 9.1:
481  *
482  *     http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf
483  *
484  * that clarifies the specifications for blend modes ColorDodge and
485  * ColorBurn.
486  *
487  * The formula for computing the final pixel color given in 11.3.6 is:
488  *
489  *     αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs)
490  *
491  * with B() is the blend function. When B(Cb, Cs) = Cs, this formula
492  * reduces to the regular OVER operator.
493  *
494  * Cs and Cb are not premultiplied, so in our implementation we instead
495  * use:
496  *
497  *     cr = (1 – αs) × cb  +  (1 – αb) × cs  +  αb × αs × B (cb/αb, cs/αs)
498  *
499  * where cr, cs, and cb are premultiplied colors, and where the
500  *
501  *     αb × αs × B(cb/αb, cs/αs)
502  *
503  * part is first arithmetically simplified under the assumption that αb
504  * and αs are not 0, and then updated to produce a meaningful result when
505  * they are.
506  *
507  * For all the blend mode operators, the alpha channel is given by
508  *
509  *     αr = αs + αb + αb × αs
510  */
511
512 /*
513  * Multiply
514  *
515  *      ad * as * B(d / ad, s / as)
516  *    = ad * as * d/ad * s/as
517  *    = d * s
518  *
519  */
520 static void
521 combine_multiply_u (pixman_implementation_t *imp,
522                     pixman_op_t              op,
523                     uint32_t *               dest,
524                     const uint32_t *         src,
525                     const uint32_t *         mask,
526                     int                      width)
527 {
528     int i;
529
530     for (i = 0; i < width; ++i)
531     {
532         uint32_t s = combine_mask (src, mask, i);
533         uint32_t d = *(dest + i);
534         uint32_t ss = s;
535         uint32_t src_ia = ALPHA_8 (~s);
536         uint32_t dest_ia = ALPHA_8 (~d);
537
538         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (ss, dest_ia, d, src_ia);
539         UN8x4_MUL_UN8x4 (d, s);
540         UN8x4_ADD_UN8x4 (d, ss);
541
542         *(dest + i) = d;
543     }
544 }
545
546 static void
547 combine_multiply_ca (pixman_implementation_t *imp,
548                      pixman_op_t              op,
549                      uint32_t *               dest,
550                      const uint32_t *         src,
551                      const uint32_t *         mask,
552                      int                      width)
553 {
554     int i;
555
556     for (i = 0; i < width; ++i)
557     {
558         uint32_t m = *(mask + i);
559         uint32_t s = *(src + i);
560         uint32_t d = *(dest + i);
561         uint32_t r = d;
562         uint32_t dest_ia = ALPHA_8 (~d);
563
564         combine_mask_ca (&s, &m);
565
566         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (r, ~m, s, dest_ia);
567         UN8x4_MUL_UN8x4 (d, s);
568         UN8x4_ADD_UN8x4 (r, d);
569
570         *(dest + i) = r;
571     }
572 }
573
574 #define PDF_SEPARABLE_BLEND_MODE(name)                                  \
575     static void                                                         \
576     combine_ ## name ## _u (pixman_implementation_t *imp,               \
577                             pixman_op_t              op,                \
578                             uint32_t *               dest,              \
579                             const uint32_t *         src,               \
580                             const uint32_t *         mask,              \
581                             int                      width)             \
582     {                                                                   \
583         int i;                                                          \
584         for (i = 0; i < width; ++i)                                     \
585         {                                                               \
586             uint32_t s = combine_mask (src, mask, i);                   \
587             uint32_t d = *(dest + i);                                   \
588             uint8_t sa = ALPHA_8 (s);                                   \
589             uint8_t isa = ~sa;                                          \
590             uint8_t da = ALPHA_8 (d);                                   \
591             uint8_t ida = ~da;                                          \
592             uint32_t result;                                            \
593                                                                         \
594             result = d;                                                 \
595             UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida);      \
596                                                                         \
597             *(dest + i) = result +                                      \
598                 (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) +          \
599                 (blend_ ## name (RED_8 (d), da, RED_8 (s), sa) << R_SHIFT) + \
600                 (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa) << G_SHIFT) + \
601                 (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa));      \
602         }                                                               \
603     }                                                                   \
604                                                                         \
605     static void                                                         \
606     combine_ ## name ## _ca (pixman_implementation_t *imp,              \
607                              pixman_op_t              op,               \
608                              uint32_t *               dest,             \
609                              const uint32_t *         src,              \
610                              const uint32_t *         mask,             \
611                              int                      width)            \
612     {                                                                   \
613         int i;                                                          \
614         for (i = 0; i < width; ++i)                                     \
615         {                                                               \
616             uint32_t m = *(mask + i);                                   \
617             uint32_t s = *(src + i);                                    \
618             uint32_t d = *(dest + i);                                   \
619             uint8_t da = ALPHA_8 (d);                                   \
620             uint8_t ida = ~da;                                          \
621             uint32_t result;                                            \
622                                                                         \
623             combine_mask_ca (&s, &m);                                   \
624                                                                         \
625             result = d;                                                 \
626             UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (result, ~m, s, ida);     \
627                                                                         \
628             result +=                                                   \
629                 (DIV_ONE_UN8 (ALPHA_8 (m) * (uint32_t)da) << A_SHIFT) + \
630                 (blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)) << R_SHIFT) + \
631                 (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)) << G_SHIFT) + \
632                 (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m))); \
633                                                                         \
634             *(dest + i) = result;                                       \
635         }                                                               \
636     }
637
638 /*
639  * Screen
640  *
641  *      ad * as * B(d/ad, s/as)
642  *    = ad * as * (d/ad + s/as - s/as * d/ad)
643  *    = ad * s + as * d - s * d
644  */
645 static inline uint32_t
646 blend_screen (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
647 {
648     return DIV_ONE_UN8 (s * ad + d * as - s * d);
649 }
650
651 PDF_SEPARABLE_BLEND_MODE (screen)
652
653 /*
654  * Overlay
655  *
656  *     ad * as * B(d/ad, s/as)
657  *   = ad * as * Hardlight (s, d)
658  *   = if (d / ad < 0.5)
659  *         as * ad * Multiply (s/as, 2 * d/ad)
660  *     else
661  *         as * ad * Screen (s/as, 2 * d / ad - 1)
662  *   = if (d < 0.5 * ad)
663  *         as * ad * s/as * 2 * d /ad
664  *     else
665  *         as * ad * (s/as + 2 * d / ad - 1 - s / as * (2 * d / ad - 1))
666  *   = if (2 * d < ad)
667  *         2 * s * d
668  *     else
669  *         ad * s + 2 * as * d - as * ad - ad * s * (2 * d / ad - 1)
670  *   = if (2 * d < ad)
671  *         2 * s * d
672  *     else
673  *         as * ad - 2 * (ad - d) * (as - s)
674  */
675 static inline uint32_t
676 blend_overlay (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
677 {
678     uint32_t r;
679
680     if (2 * d < ad)
681         r = 2 * s * d;
682     else
683         r = as * ad - 2 * (ad - d) * (as - s);
684
685     return DIV_ONE_UN8 (r);
686 }
687
688 PDF_SEPARABLE_BLEND_MODE (overlay)
689
690 /*
691  * Darken
692  *
693  *     ad * as * B(d/ad, s/as)
694  *   = ad * as * MIN(d/ad, s/as)
695  *   = MIN (as * d, ad * s)
696  */
697 static inline uint32_t
698 blend_darken (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
699 {
700     s = ad * s;
701     d = as * d;
702
703     return DIV_ONE_UN8 (s > d ? d : s);
704 }
705
706 PDF_SEPARABLE_BLEND_MODE (darken)
707
708 /*
709  * Lighten
710  *
711  *     ad * as * B(d/ad, s/as)
712  *   = ad * as * MAX(d/ad, s/as)
713  *   = MAX (as * d, ad * s)
714  */
715 static inline uint32_t
716 blend_lighten (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
717 {
718     s = ad * s;
719     d = as * d;
720     
721     return DIV_ONE_UN8 (s > d ? s : d);
722 }
723
724 PDF_SEPARABLE_BLEND_MODE (lighten)
725
726 /*
727  * Color dodge
728  *
729  *     ad * as * B(d/ad, s/as)
730  *   = if d/ad = 0
731  *         ad * as * 0
732  *     else if (d/ad >= (1 - s/as)
733  *         ad * as * 1
734  *     else
735  *         ad * as * ((d/ad) / (1 - s/as))
736  *   = if d = 0
737  *         0
738  *     elif as * d >= ad * (as - s)
739  *         ad * as
740  *     else
741  *         as * (as * d / (as - s))
742  *
743  */
744 static inline uint32_t
745 blend_color_dodge (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
746 {
747     if (d == 0)
748         return 0;
749     else if (as * d >= ad * (as - s))
750         return DIV_ONE_UN8 (as * ad);
751     else if (as - s == 0)
752         return DIV_ONE_UN8 (as * ad);
753     else
754         return DIV_ONE_UN8 (as * ((d * as) / ((as - s))));
755 }
756
757 PDF_SEPARABLE_BLEND_MODE (color_dodge)
758
759 /*
760  * Color burn
761  *
762  * We modify the first clause "if d = 1" to "if d >= 1" since with
763  * premultiplied colors d > 1 can actually happen.
764  *
765  *     ad * as * B(d/ad, s/as)
766  *   = if d/ad >= 1
767  *         ad * as * 1
768  *     elif (1 - d/ad) >= s/as
769  *         ad * as * 0
770  *     else
771  *         ad * as * (1 - ((1 - d/ad) / (s/as)))
772  *   = if d >= ad
773  *         ad * as
774  *     elif as * ad - as * d >= ad * s
775  *         0
776  *     else
777  *         ad * as  - as * as * (ad - d) / s
778  */
779 static inline uint32_t
780 blend_color_burn (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
781 {
782     if (d >= ad)
783         return DIV_ONE_UN8 (ad * as);
784     else if (as * ad - as * d >= ad * s)
785         return 0;
786     else if (s == 0)
787         return 0;
788     else
789         return DIV_ONE_UN8 (ad * as - (as * as * (ad - d)) / s);
790 }
791
792 PDF_SEPARABLE_BLEND_MODE (color_burn)
793
794 /*
795  * Hard light
796  *
797  *     ad * as * B(d/ad, s/as)
798  *   = if (s/as <= 0.5)
799  *         ad * as * Multiply (d/ad, 2 * s/as)
800  *     else
801  *         ad * as * Screen (d/ad, 2 * s/as - 1)
802  *   = if 2 * s <= as
803  *         ad * as * d/ad * 2 * s / as
804  *     else
805  *         ad * as * (d/ad + (2 * s/as - 1) + d/ad * (2 * s/as - 1))
806  *   = if 2 * s <= as
807  *         2 * s * d
808  *     else
809  *         as * ad - 2 * (ad - d) * (as - s)
810  */
811 static inline uint32_t
812 blend_hard_light (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
813 {
814     if (2 * s < as)
815         return DIV_ONE_UN8 (2 * s * d);
816     else
817         return DIV_ONE_UN8 (as * ad - 2 * (ad - d) * (as - s));
818 }
819
820 PDF_SEPARABLE_BLEND_MODE (hard_light)
821
822 /*
823  * Soft light
824  *
825  *     ad * as * B(d/ad, s/as)
826  *   = if (s/as <= 0.5)
827  *         ad * as * (d/ad - (1 - 2 * s/as) * d/ad * (1 - d/ad))
828  *     else if (d/ad <= 0.25)
829  *         ad * as * (d/ad + (2 * s/as - 1) * ((((16 * d/ad - 12) * d/ad + 4) * d/ad) - d/ad))
830  *     else
831  *         ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad))
832  *   = if (2 * s <= as)
833  *         d * as - d * (ad - d) * (as - 2 * s) / ad;
834  *     else if (4 * d <= ad)
835  *         (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3);
836  *     else
837  *         d * as + (sqrt (d * ad) - d) * (2 * s - as);
838  */
839 static inline uint32_t
840 blend_soft_light (uint32_t d_org,
841                   uint32_t ad_org,
842                   uint32_t s_org,
843                   uint32_t as_org)
844 {
845     double d = d_org * (1.0 / MASK);
846     double ad = ad_org * (1.0 / MASK);
847     double s = s_org * (1.0 / MASK);
848     double as = as_org * (1.0 / MASK);
849     double r;
850
851     if (2 * s < as)
852     {
853         if (ad == 0)
854             r = d * as;
855         else
856             r = d * as - d * (ad - d) * (as - 2 * s) / ad;
857     }
858     else if (ad == 0)
859     {
860         r = 0;
861     }
862     else if (4 * d <= ad)
863     {
864         r = d * as +
865             (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3);
866     }
867     else
868     {
869         r = d * as + (sqrt (d * ad) - d) * (2 * s - as);
870     }
871     return r * MASK + 0.5;
872 }
873
874 PDF_SEPARABLE_BLEND_MODE (soft_light)
875
876 /*
877  * Difference
878  *
879  *     ad * as * B(s/as, d/ad)
880  *   = ad * as * abs (s/as - d/ad)
881  *   = if (s/as <= d/ad)
882  *         ad * as * (d/ad - s/as)
883  *     else
884  *         ad * as * (s/as - d/ad)
885  *   = if (ad * s <= as * d)
886  *        as * d - ad * s
887  *     else
888  *        ad * s - as * d
889  */
890 static inline uint32_t
891 blend_difference (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
892 {
893     uint32_t das = d * as;
894     uint32_t sad = s * ad;
895
896     if (sad < das)
897         return DIV_ONE_UN8 (das - sad);
898     else
899         return DIV_ONE_UN8 (sad - das);
900 }
901
902 PDF_SEPARABLE_BLEND_MODE (difference)
903
904 /*
905  * Exclusion
906  *
907  *     ad * as * B(s/as, d/ad)
908  *   = ad * as * (d/ad + s/as - 2 * d/ad * s/as)
909  *   = as * d + ad * s - 2 * s * d
910  */
911
912 /* This can be made faster by writing it directly and not using
913  * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
914
915 static inline uint32_t
916 blend_exclusion (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
917 {
918     return DIV_ONE_UN8 (s * ad + d * as - 2 * d * s);
919 }
920
921 PDF_SEPARABLE_BLEND_MODE (exclusion)
922
923 #undef PDF_SEPARABLE_BLEND_MODE
924
925 /*
926  * PDF nonseperable blend modes are implemented using the following functions
927  * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid
928  * and min value of the red, green and blue components.
929  *
930  * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
931  *
932  * clip_color (C):
933  *     l = LUM (C)
934  *     min = Cmin
935  *     max = Cmax
936  *     if n < 0.0
937  *         C = l + (((C – l) × l) ⁄ (l – min))
938  *     if x > 1.0
939  *         C = l + (((C – l) × (1 – l) ) ⁄ (max – l))
940  *     return C
941  *
942  * set_lum (C, l):
943  *     d = l – LUM (C)
944  *     C += d
945  *     return clip_color (C)
946  *
947  * SAT (C) = CH_MAX (C) - CH_MIN (C)
948  *
949  * set_sat (C, s):
950  *     if Cmax > Cmin
951  *         Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
952  *         Cmax = s
953  *     else
954  *         Cmid = Cmax = 0.0
955  *         Cmin = 0.0
956  *     return C
957  */
958
959 /* For premultiplied colors, we need to know what happens when C is
960  * multiplied by a real number. LUM and SAT are linear:
961  *
962  *     LUM (r × C) = r × LUM (C)      SAT (r * C) = r * SAT (C)
963  *
964  * If we extend clip_color with an extra argument a and change
965  *
966  *     if x >= 1.0
967  *
968  * into
969  *
970  *     if x >= a
971  *
972  * then clip_color is also linear:
973  *
974  *     r * clip_color (C, a) = clip_color (r * C, r * a);
975  *
976  * for positive r.
977  *
978  * Similarly, we can extend set_lum with an extra argument that is just passed
979  * on to clip_color:
980  *
981  *       r * set_lum (C, l, a)
982  *
983  *     = r × clip_color (C + l - LUM (C), a)
984  *
985  *     = clip_color (r * C + r × l - r * LUM (C), r * a)
986  *
987  *     = set_lum (r * C, r * l, r * a)
988  *
989  * Finally, set_sat:
990  *
991  *       r * set_sat (C, s) = set_sat (x * C, r * s)
992  *
993  * The above holds for all non-zero x, because the x'es in the fraction for
994  * C_mid cancel out. Specifically, it holds for x = r:
995  *
996  *       r * set_sat (C, s) = set_sat (r * C, r * s)
997  *
998  */
999
1000 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2]))
1001 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2]))
1002 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100)
1003 #define SAT(c) (CH_MAX (c) - CH_MIN (c))
1004
1005 #define PDF_NON_SEPARABLE_BLEND_MODE(name)                              \
1006     static void                                                         \
1007     combine_ ## name ## _u (pixman_implementation_t *imp,               \
1008                             pixman_op_t              op,                \
1009                             uint32_t *               dest,              \
1010                             const uint32_t *         src,               \
1011                             const uint32_t *         mask,              \
1012                             int                      width)             \
1013     {                                                                   \
1014         int i;                                                          \
1015         for (i = 0; i < width; ++i)                                     \
1016         {                                                               \
1017             uint32_t s = combine_mask (src, mask, i);                   \
1018             uint32_t d = *(dest + i);                                   \
1019             uint8_t sa = ALPHA_8 (s);                                   \
1020             uint8_t isa = ~sa;                                          \
1021             uint8_t da = ALPHA_8 (d);                                   \
1022             uint8_t ida = ~da;                                          \
1023             uint32_t result;                                            \
1024             uint32_t sc[3], dc[3], c[3];                                \
1025                                                                         \
1026             result = d;                                                 \
1027             UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida);      \
1028             dc[0] = RED_8 (d);                                          \
1029             sc[0] = RED_8 (s);                                          \
1030             dc[1] = GREEN_8 (d);                                        \
1031             sc[1] = GREEN_8 (s);                                        \
1032             dc[2] = BLUE_8 (d);                                         \
1033             sc[2] = BLUE_8 (s);                                         \
1034             blend_ ## name (c, dc, da, sc, sa);                         \
1035                                                                         \
1036             *(dest + i) = result +                                      \
1037                 (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) +          \
1038                 (DIV_ONE_UN8 (c[0]) << R_SHIFT) +                       \
1039                 (DIV_ONE_UN8 (c[1]) << G_SHIFT) +                       \
1040                 (DIV_ONE_UN8 (c[2]));                                   \
1041         }                                                               \
1042     }
1043
1044 static void
1045 set_lum (uint32_t dest[3], uint32_t src[3], uint32_t sa, uint32_t lum)
1046 {
1047     double a, l, min, max;
1048     double tmp[3];
1049
1050     a = sa * (1.0 / MASK);
1051
1052     l = lum * (1.0 / MASK);
1053     tmp[0] = src[0] * (1.0 / MASK);
1054     tmp[1] = src[1] * (1.0 / MASK);
1055     tmp[2] = src[2] * (1.0 / MASK);
1056
1057     l = l - LUM (tmp);
1058     tmp[0] += l;
1059     tmp[1] += l;
1060     tmp[2] += l;
1061
1062     /* clip_color */
1063     l = LUM (tmp);
1064     min = CH_MIN (tmp);
1065     max = CH_MAX (tmp);
1066
1067     if (min < 0)
1068     {
1069         if (l - min == 0.0)
1070         {
1071             tmp[0] = 0;
1072             tmp[1] = 0;
1073             tmp[2] = 0;
1074         }
1075         else
1076         {
1077             tmp[0] = l + (tmp[0] - l) * l / (l - min);
1078             tmp[1] = l + (tmp[1] - l) * l / (l - min);
1079             tmp[2] = l + (tmp[2] - l) * l / (l - min);
1080         }
1081     }
1082     if (max > a)
1083     {
1084         if (max - l == 0.0)
1085         {
1086             tmp[0] = a;
1087             tmp[1] = a;
1088             tmp[2] = a;
1089         }
1090         else
1091         {
1092             tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
1093             tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
1094             tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
1095         }
1096     }
1097
1098     dest[0] = tmp[0] * MASK + 0.5;
1099     dest[1] = tmp[1] * MASK + 0.5;
1100     dest[2] = tmp[2] * MASK + 0.5;
1101 }
1102
1103 static void
1104 set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat)
1105 {
1106     int id[3];
1107     uint32_t min, max;
1108
1109     if (src[0] > src[1])
1110     {
1111         if (src[0] > src[2])
1112         {
1113             id[0] = 0;
1114             if (src[1] > src[2])
1115             {
1116                 id[1] = 1;
1117                 id[2] = 2;
1118             }
1119             else
1120             {
1121                 id[1] = 2;
1122                 id[2] = 1;
1123             }
1124         }
1125         else
1126         {
1127             id[0] = 2;
1128             id[1] = 0;
1129             id[2] = 1;
1130         }
1131     }
1132     else
1133     {
1134         if (src[0] > src[2])
1135         {
1136             id[0] = 1;
1137             id[1] = 0;
1138             id[2] = 2;
1139         }
1140         else
1141         {
1142             id[2] = 0;
1143             if (src[1] > src[2])
1144             {
1145                 id[0] = 1;
1146                 id[1] = 2;
1147             }
1148             else
1149             {
1150                 id[0] = 2;
1151                 id[1] = 1;
1152             }
1153         }
1154     }
1155
1156     max = dest[id[0]];
1157     min = dest[id[2]];
1158     if (max > min)
1159     {
1160         dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
1161         dest[id[0]] = sat;
1162         dest[id[2]] = 0;
1163     }
1164     else
1165     {
1166         dest[0] = dest[1] = dest[2] = 0;
1167     }
1168 }
1169
1170 /* Hue:
1171  *
1172  *       as * ad * B(s/as, d/as)
1173  *     = as * ad * set_lum (set_sat (s/as, SAT (d/ad)), LUM (d/ad), 1)
1174  *     = set_lum (set_sat (ad * s, as * SAT (d)), as * LUM (d), as * ad)
1175  *
1176  */
1177 static inline void
1178 blend_hsl_hue (uint32_t r[3],
1179                uint32_t d[3],
1180                uint32_t ad,
1181                uint32_t s[3],
1182                uint32_t as)
1183 {
1184     r[0] = s[0] * ad;
1185     r[1] = s[1] * ad;
1186     r[2] = s[2] * ad;
1187     set_sat (r, r, SAT (d) * as);
1188     set_lum (r, r, as * ad, LUM (d) * as);
1189 }
1190
1191 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
1192
1193 /* 
1194  * Saturation
1195  *
1196  *     as * ad * B(s/as, d/ad)
1197  *   = as * ad * set_lum (set_sat (d/ad, SAT (s/as)), LUM (d/ad), 1)
1198  *   = set_lum (as * ad * set_sat (d/ad, SAT (s/as)),
1199  *                                       as * LUM (d), as * ad)
1200  *   = set_lum (set_sat (as * d, ad * SAT (s), as * LUM (d), as * ad))
1201  */
1202 static inline void
1203 blend_hsl_saturation (uint32_t r[3],
1204                       uint32_t d[3],
1205                       uint32_t ad,
1206                       uint32_t s[3],
1207                       uint32_t as)
1208 {
1209     r[0] = d[0] * as;
1210     r[1] = d[1] * as;
1211     r[2] = d[2] * as;
1212     set_sat (r, r, SAT (s) * ad);
1213     set_lum (r, r, as * ad, LUM (d) * as);
1214 }
1215
1216 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
1217
1218 /* 
1219  * Color
1220  *
1221  *     as * ad * B(s/as, d/as)
1222  *   = as * ad * set_lum (s/as, LUM (d/ad), 1)
1223  *   = set_lum (s * ad, as * LUM (d), as * ad)
1224  */
1225 static inline void
1226 blend_hsl_color (uint32_t r[3],
1227                  uint32_t d[3],
1228                  uint32_t ad,
1229                  uint32_t s[3],
1230                  uint32_t as)
1231 {
1232     r[0] = s[0] * ad;
1233     r[1] = s[1] * ad;
1234     r[2] = s[2] * ad;
1235     set_lum (r, r, as * ad, LUM (d) * as);
1236 }
1237
1238 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
1239
1240 /*
1241  * Luminosity
1242  *
1243  *     as * ad * B(s/as, d/ad)
1244  *   = as * ad * set_lum (d/ad, LUM (s/as), 1)
1245  *   = set_lum (as * d, ad * LUM (s), as * ad)
1246  */
1247 static inline void
1248 blend_hsl_luminosity (uint32_t r[3],
1249                       uint32_t d[3],
1250                       uint32_t ad,
1251                       uint32_t s[3],
1252                       uint32_t as)
1253 {
1254     r[0] = d[0] * as;
1255     r[1] = d[1] * as;
1256     r[2] = d[2] * as;
1257     set_lum (r, r, as * ad, LUM (s) * ad);
1258 }
1259
1260 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
1261
1262 #undef SAT
1263 #undef LUM
1264 #undef CH_MAX
1265 #undef CH_MIN
1266 #undef PDF_NON_SEPARABLE_BLEND_MODE
1267
1268 /* All of the disjoint/conjoint composing functions
1269  *
1270  * The four entries in the first column indicate what source contributions
1271  * come from each of the four areas of the picture -- areas covered by neither
1272  * A nor B, areas covered only by A, areas covered only by B and finally
1273  * areas covered by both A and B.
1274  *
1275  * Disjoint                     Conjoint
1276  * Fa           Fb              Fa              Fb
1277  * (0,0,0,0)    0               0               0               0
1278  * (0,A,0,A)    1               0               1               0
1279  * (0,0,B,B)    0               1               0               1
1280  * (0,A,B,A)    1               min((1-a)/b,1)  1               max(1-a/b,0)
1281  * (0,A,B,B)    min((1-b)/a,1)  1               max(1-b/a,0)    1
1282  * (0,0,0,A)    max(1-(1-b)/a,0) 0              min(1,b/a)      0
1283  * (0,0,0,B)    0               max(1-(1-a)/b,0) 0              min(a/b,1)
1284  * (0,A,0,0)    min(1,(1-b)/a)  0               max(1-b/a,0)    0
1285  * (0,0,B,0)    0               min(1,(1-a)/b)  0               max(1-a/b,0)
1286  * (0,0,B,A)    max(1-(1-b)/a,0) min(1,(1-a)/b)  min(1,b/a)     max(1-a/b,0)
1287  * (0,A,0,B)    min(1,(1-b)/a)  max(1-(1-a)/b,0) max(1-b/a,0)   min(1,a/b)
1288  * (0,A,B,0)    min(1,(1-b)/a)  min(1,(1-a)/b)  max(1-b/a,0)    max(1-a/b,0)
1289  *
1290  * See  http://marc.info/?l=xfree-render&m=99792000027857&w=2  for more
1291  * information about these operators.
1292  */
1293
1294 #define COMBINE_A_OUT 1
1295 #define COMBINE_A_IN  2
1296 #define COMBINE_B_OUT 4
1297 #define COMBINE_B_IN  8
1298
1299 #define COMBINE_CLEAR   0
1300 #define COMBINE_A       (COMBINE_A_OUT | COMBINE_A_IN)
1301 #define COMBINE_B       (COMBINE_B_OUT | COMBINE_B_IN)
1302 #define COMBINE_A_OVER  (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN)
1303 #define COMBINE_B_OVER  (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN)
1304 #define COMBINE_A_ATOP  (COMBINE_B_OUT | COMBINE_A_IN)
1305 #define COMBINE_B_ATOP  (COMBINE_A_OUT | COMBINE_B_IN)
1306 #define COMBINE_XOR     (COMBINE_A_OUT | COMBINE_B_OUT)
1307
1308 /* portion covered by a but not b */
1309 static uint8_t
1310 combine_disjoint_out_part (uint8_t a, uint8_t b)
1311 {
1312     /* min (1, (1-b) / a) */
1313
1314     b = ~b;                 /* 1 - b */
1315     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
1316         return MASK;        /* 1 */
1317     return DIV_UN8 (b, a);     /* (1-b) / a */
1318 }
1319
1320 /* portion covered by both a and b */
1321 static uint8_t
1322 combine_disjoint_in_part (uint8_t a, uint8_t b)
1323 {
1324     /* max (1-(1-b)/a,0) */
1325     /*  = - min ((1-b)/a - 1, 0) */
1326     /*  = 1 - min (1, (1-b)/a) */
1327
1328     b = ~b;                 /* 1 - b */
1329     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
1330         return 0;           /* 1 - 1 */
1331     return ~DIV_UN8(b, a);    /* 1 - (1-b) / a */
1332 }
1333
1334 /* portion covered by a but not b */
1335 static uint8_t
1336 combine_conjoint_out_part (uint8_t a, uint8_t b)
1337 {
1338     /* max (1-b/a,0) */
1339     /* = 1-min(b/a,1) */
1340
1341     /* min (1, (1-b) / a) */
1342
1343     if (b >= a)             /* b >= a -> b/a >= 1 */
1344         return 0x00;        /* 0 */
1345     return ~DIV_UN8(b, a);    /* 1 - b/a */
1346 }
1347
1348 /* portion covered by both a and b */
1349 static uint8_t
1350 combine_conjoint_in_part (uint8_t a, uint8_t b)
1351 {
1352     /* min (1,b/a) */
1353
1354     if (b >= a)             /* b >= a -> b/a >= 1 */
1355         return MASK;        /* 1 */
1356     return DIV_UN8 (b, a);     /* b/a */
1357 }
1358
1359 #define GET_COMP(v, i)   ((uint16_t) (uint8_t) ((v) >> i))
1360
1361 #define ADD(x, y, i, t)                                                 \
1362     ((t) = GET_COMP (x, i) + GET_COMP (y, i),                           \
1363      (uint32_t) ((uint8_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i))
1364
1365 #define GENERIC(x, y, i, ax, ay, t, u, v)                               \
1366     ((t) = (MUL_UN8 (GET_COMP (y, i), ay, (u)) +                        \
1367             MUL_UN8 (GET_COMP (x, i), ax, (v))),                        \
1368      (uint32_t) ((uint8_t) ((t) |                                       \
1369                            (0 - ((t) >> G_SHIFT)))) << (i))
1370
1371 static void
1372 combine_disjoint_general_u (uint32_t *      dest,
1373                             const uint32_t *src,
1374                             const uint32_t *mask,
1375                             int            width,
1376                             uint8_t        combine)
1377 {
1378     int i;
1379
1380     for (i = 0; i < width; ++i)
1381     {
1382         uint32_t s = combine_mask (src, mask, i);
1383         uint32_t d = *(dest + i);
1384         uint32_t m, n, o, p;
1385         uint16_t Fa, Fb, t, u, v;
1386         uint8_t sa = s >> A_SHIFT;
1387         uint8_t da = d >> A_SHIFT;
1388
1389         switch (combine & COMBINE_A)
1390         {
1391         default:
1392             Fa = 0;
1393             break;
1394
1395         case COMBINE_A_OUT:
1396             Fa = combine_disjoint_out_part (sa, da);
1397             break;
1398
1399         case COMBINE_A_IN:
1400             Fa = combine_disjoint_in_part (sa, da);
1401             break;
1402
1403         case COMBINE_A:
1404             Fa = MASK;
1405             break;
1406         }
1407
1408         switch (combine & COMBINE_B)
1409         {
1410         default:
1411             Fb = 0;
1412             break;
1413
1414         case COMBINE_B_OUT:
1415             Fb = combine_disjoint_out_part (da, sa);
1416             break;
1417
1418         case COMBINE_B_IN:
1419             Fb = combine_disjoint_in_part (da, sa);
1420             break;
1421
1422         case COMBINE_B:
1423             Fb = MASK;
1424             break;
1425         }
1426         m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
1427         n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
1428         o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
1429         p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
1430         s = m | n | o | p;
1431         *(dest + i) = s;
1432     }
1433 }
1434
1435 static void
1436 combine_disjoint_over_u (pixman_implementation_t *imp,
1437                          pixman_op_t              op,
1438                          uint32_t *                dest,
1439                          const uint32_t *          src,
1440                          const uint32_t *          mask,
1441                          int                      width)
1442 {
1443     int i;
1444
1445     for (i = 0; i < width; ++i)
1446     {
1447         uint32_t s = combine_mask (src, mask, i);
1448         uint16_t a = s >> A_SHIFT;
1449
1450         if (s != 0x00)
1451         {
1452             uint32_t d = *(dest + i);
1453             a = combine_disjoint_out_part (d >> A_SHIFT, a);
1454             UN8x4_MUL_UN8_ADD_UN8x4 (d, a, s);
1455
1456             *(dest + i) = d;
1457         }
1458     }
1459 }
1460
1461 static void
1462 combine_disjoint_in_u (pixman_implementation_t *imp,
1463                        pixman_op_t              op,
1464                        uint32_t *                dest,
1465                        const uint32_t *          src,
1466                        const uint32_t *          mask,
1467                        int                      width)
1468 {
1469     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1470 }
1471
1472 static void
1473 combine_disjoint_in_reverse_u (pixman_implementation_t *imp,
1474                                pixman_op_t              op,
1475                                uint32_t *                dest,
1476                                const uint32_t *          src,
1477                                const uint32_t *          mask,
1478                                int                      width)
1479 {
1480     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1481 }
1482
1483 static void
1484 combine_disjoint_out_u (pixman_implementation_t *imp,
1485                         pixman_op_t              op,
1486                         uint32_t *                dest,
1487                         const uint32_t *          src,
1488                         const uint32_t *          mask,
1489                         int                      width)
1490 {
1491     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1492 }
1493
1494 static void
1495 combine_disjoint_out_reverse_u (pixman_implementation_t *imp,
1496                                 pixman_op_t              op,
1497                                 uint32_t *                dest,
1498                                 const uint32_t *          src,
1499                                 const uint32_t *          mask,
1500                                 int                      width)
1501 {
1502     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1503 }
1504
1505 static void
1506 combine_disjoint_atop_u (pixman_implementation_t *imp,
1507                          pixman_op_t              op,
1508                          uint32_t *                dest,
1509                          const uint32_t *          src,
1510                          const uint32_t *          mask,
1511                          int                      width)
1512 {
1513     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1514 }
1515
1516 static void
1517 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp,
1518                                  pixman_op_t              op,
1519                                  uint32_t *                dest,
1520                                  const uint32_t *          src,
1521                                  const uint32_t *          mask,
1522                                  int                      width)
1523 {
1524     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1525 }
1526
1527 static void
1528 combine_disjoint_xor_u (pixman_implementation_t *imp,
1529                         pixman_op_t              op,
1530                         uint32_t *                dest,
1531                         const uint32_t *          src,
1532                         const uint32_t *          mask,
1533                         int                      width)
1534 {
1535     combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1536 }
1537
1538 static void
1539 combine_conjoint_general_u (uint32_t *      dest,
1540                             const uint32_t *src,
1541                             const uint32_t *mask,
1542                             int            width,
1543                             uint8_t        combine)
1544 {
1545     int i;
1546
1547     for (i = 0; i < width; ++i)
1548     {
1549         uint32_t s = combine_mask (src, mask, i);
1550         uint32_t d = *(dest + i);
1551         uint32_t m, n, o, p;
1552         uint16_t Fa, Fb, t, u, v;
1553         uint8_t sa = s >> A_SHIFT;
1554         uint8_t da = d >> A_SHIFT;
1555
1556         switch (combine & COMBINE_A)
1557         {
1558         default:
1559             Fa = 0;
1560             break;
1561
1562         case COMBINE_A_OUT:
1563             Fa = combine_conjoint_out_part (sa, da);
1564             break;
1565
1566         case COMBINE_A_IN:
1567             Fa = combine_conjoint_in_part (sa, da);
1568             break;
1569
1570         case COMBINE_A:
1571             Fa = MASK;
1572             break;
1573         }
1574
1575         switch (combine & COMBINE_B)
1576         {
1577         default:
1578             Fb = 0;
1579             break;
1580
1581         case COMBINE_B_OUT:
1582             Fb = combine_conjoint_out_part (da, sa);
1583             break;
1584
1585         case COMBINE_B_IN:
1586             Fb = combine_conjoint_in_part (da, sa);
1587             break;
1588
1589         case COMBINE_B:
1590             Fb = MASK;
1591             break;
1592         }
1593
1594         m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
1595         n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
1596         o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
1597         p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
1598
1599         s = m | n | o | p;
1600
1601         *(dest + i) = s;
1602     }
1603 }
1604
1605 static void
1606 combine_conjoint_over_u (pixman_implementation_t *imp,
1607                          pixman_op_t              op,
1608                          uint32_t *                dest,
1609                          const uint32_t *          src,
1610                          const uint32_t *          mask,
1611                          int                      width)
1612 {
1613     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
1614 }
1615
1616 static void
1617 combine_conjoint_over_reverse_u (pixman_implementation_t *imp,
1618                                  pixman_op_t              op,
1619                                  uint32_t *                dest,
1620                                  const uint32_t *          src,
1621                                  const uint32_t *          mask,
1622                                  int                      width)
1623 {
1624     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
1625 }
1626
1627 static void
1628 combine_conjoint_in_u (pixman_implementation_t *imp,
1629                        pixman_op_t              op,
1630                        uint32_t *                dest,
1631                        const uint32_t *          src,
1632                        const uint32_t *          mask,
1633                        int                      width)
1634 {
1635     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1636 }
1637
1638 static void
1639 combine_conjoint_in_reverse_u (pixman_implementation_t *imp,
1640                                pixman_op_t              op,
1641                                uint32_t *                dest,
1642                                const uint32_t *          src,
1643                                const uint32_t *          mask,
1644                                int                      width)
1645 {
1646     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1647 }
1648
1649 static void
1650 combine_conjoint_out_u (pixman_implementation_t *imp,
1651                         pixman_op_t              op,
1652                         uint32_t *                dest,
1653                         const uint32_t *          src,
1654                         const uint32_t *          mask,
1655                         int                      width)
1656 {
1657     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1658 }
1659
1660 static void
1661 combine_conjoint_out_reverse_u (pixman_implementation_t *imp,
1662                                 pixman_op_t              op,
1663                                 uint32_t *                dest,
1664                                 const uint32_t *          src,
1665                                 const uint32_t *          mask,
1666                                 int                      width)
1667 {
1668     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1669 }
1670
1671 static void
1672 combine_conjoint_atop_u (pixman_implementation_t *imp,
1673                          pixman_op_t              op,
1674                          uint32_t *                dest,
1675                          const uint32_t *          src,
1676                          const uint32_t *          mask,
1677                          int                      width)
1678 {
1679     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1680 }
1681
1682 static void
1683 combine_conjoint_atop_reverse_u (pixman_implementation_t *imp,
1684                                  pixman_op_t              op,
1685                                  uint32_t *                dest,
1686                                  const uint32_t *          src,
1687                                  const uint32_t *          mask,
1688                                  int                      width)
1689 {
1690     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1691 }
1692
1693 static void
1694 combine_conjoint_xor_u (pixman_implementation_t *imp,
1695                         pixman_op_t              op,
1696                         uint32_t *                dest,
1697                         const uint32_t *          src,
1698                         const uint32_t *          mask,
1699                         int                      width)
1700 {
1701     combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1702 }
1703
1704
1705 /* Component alpha combiners */
1706
1707 static void
1708 combine_clear_ca (pixman_implementation_t *imp,
1709                   pixman_op_t              op,
1710                   uint32_t *                dest,
1711                   const uint32_t *          src,
1712                   const uint32_t *          mask,
1713                   int                      width)
1714 {
1715     memset (dest, 0, width * sizeof(uint32_t));
1716 }
1717
1718 static void
1719 combine_src_ca (pixman_implementation_t *imp,
1720                 pixman_op_t              op,
1721                 uint32_t *                dest,
1722                 const uint32_t *          src,
1723                 const uint32_t *          mask,
1724                 int                      width)
1725 {
1726     int i;
1727
1728     for (i = 0; i < width; ++i)
1729     {
1730         uint32_t s = *(src + i);
1731         uint32_t m = *(mask + i);
1732
1733         combine_mask_value_ca (&s, &m);
1734
1735         *(dest + i) = s;
1736     }
1737 }
1738
1739 static void
1740 combine_over_ca (pixman_implementation_t *imp,
1741                  pixman_op_t              op,
1742                  uint32_t *                dest,
1743                  const uint32_t *          src,
1744                  const uint32_t *          mask,
1745                  int                      width)
1746 {
1747     int i;
1748
1749     for (i = 0; i < width; ++i)
1750     {
1751         uint32_t s = *(src + i);
1752         uint32_t m = *(mask + i);
1753         uint32_t a;
1754
1755         combine_mask_ca (&s, &m);
1756
1757         a = ~m;
1758         if (a)
1759         {
1760             uint32_t d = *(dest + i);
1761             UN8x4_MUL_UN8x4_ADD_UN8x4 (d, a, s);
1762             s = d;
1763         }
1764
1765         *(dest + i) = s;
1766     }
1767 }
1768
1769 static void
1770 combine_over_reverse_ca (pixman_implementation_t *imp,
1771                          pixman_op_t              op,
1772                          uint32_t *                dest,
1773                          const uint32_t *          src,
1774                          const uint32_t *          mask,
1775                          int                      width)
1776 {
1777     int i;
1778
1779     for (i = 0; i < width; ++i)
1780     {
1781         uint32_t d = *(dest + i);
1782         uint32_t a = ~d >> A_SHIFT;
1783
1784         if (a)
1785         {
1786             uint32_t s = *(src + i);
1787             uint32_t m = *(mask + i);
1788
1789             UN8x4_MUL_UN8x4 (s, m);
1790             UN8x4_MUL_UN8_ADD_UN8x4 (s, a, d);
1791
1792             *(dest + i) = s;
1793         }
1794     }
1795 }
1796
1797 static void
1798 combine_in_ca (pixman_implementation_t *imp,
1799                pixman_op_t              op,
1800                uint32_t *                dest,
1801                const uint32_t *          src,
1802                const uint32_t *          mask,
1803                int                      width)
1804 {
1805     int i;
1806
1807     for (i = 0; i < width; ++i)
1808     {
1809         uint32_t d = *(dest + i);
1810         uint16_t a = d >> A_SHIFT;
1811         uint32_t s = 0;
1812
1813         if (a)
1814         {
1815             uint32_t m = *(mask + i);
1816
1817             s = *(src + i);
1818             combine_mask_value_ca (&s, &m);
1819
1820             if (a != MASK)
1821                 UN8x4_MUL_UN8 (s, a);
1822         }
1823
1824         *(dest + i) = s;
1825     }
1826 }
1827
1828 static void
1829 combine_in_reverse_ca (pixman_implementation_t *imp,
1830                        pixman_op_t              op,
1831                        uint32_t *                dest,
1832                        const uint32_t *          src,
1833                        const uint32_t *          mask,
1834                        int                      width)
1835 {
1836     int i;
1837
1838     for (i = 0; i < width; ++i)
1839     {
1840         uint32_t s = *(src + i);
1841         uint32_t m = *(mask + i);
1842         uint32_t a;
1843
1844         combine_mask_alpha_ca (&s, &m);
1845
1846         a = m;
1847         if (a != ~0)
1848         {
1849             uint32_t d = 0;
1850
1851             if (a)
1852             {
1853                 d = *(dest + i);
1854                 UN8x4_MUL_UN8x4 (d, a);
1855             }
1856
1857             *(dest + i) = d;
1858         }
1859     }
1860 }
1861
1862 static void
1863 combine_out_ca (pixman_implementation_t *imp,
1864                 pixman_op_t              op,
1865                 uint32_t *                dest,
1866                 const uint32_t *          src,
1867                 const uint32_t *          mask,
1868                 int                      width)
1869 {
1870     int i;
1871
1872     for (i = 0; i < width; ++i)
1873     {
1874         uint32_t d = *(dest + i);
1875         uint16_t a = ~d >> A_SHIFT;
1876         uint32_t s = 0;
1877
1878         if (a)
1879         {
1880             uint32_t m = *(mask + i);
1881
1882             s = *(src + i);
1883             combine_mask_value_ca (&s, &m);
1884
1885             if (a != MASK)
1886                 UN8x4_MUL_UN8 (s, a);
1887         }
1888
1889         *(dest + i) = s;
1890     }
1891 }
1892
1893 static void
1894 combine_out_reverse_ca (pixman_implementation_t *imp,
1895                         pixman_op_t              op,
1896                         uint32_t *                dest,
1897                         const uint32_t *          src,
1898                         const uint32_t *          mask,
1899                         int                      width)
1900 {
1901     int i;
1902
1903     for (i = 0; i < width; ++i)
1904     {
1905         uint32_t s = *(src + i);
1906         uint32_t m = *(mask + i);
1907         uint32_t a;
1908
1909         combine_mask_alpha_ca (&s, &m);
1910
1911         a = ~m;
1912         if (a != ~0)
1913         {
1914             uint32_t d = 0;
1915
1916             if (a)
1917             {
1918                 d = *(dest + i);
1919                 UN8x4_MUL_UN8x4 (d, a);
1920             }
1921
1922             *(dest + i) = d;
1923         }
1924     }
1925 }
1926
1927 static void
1928 combine_atop_ca (pixman_implementation_t *imp,
1929                  pixman_op_t              op,
1930                  uint32_t *                dest,
1931                  const uint32_t *          src,
1932                  const uint32_t *          mask,
1933                  int                      width)
1934 {
1935     int i;
1936
1937     for (i = 0; i < width; ++i)
1938     {
1939         uint32_t d = *(dest + i);
1940         uint32_t s = *(src + i);
1941         uint32_t m = *(mask + i);
1942         uint32_t ad;
1943         uint16_t as = d >> A_SHIFT;
1944
1945         combine_mask_ca (&s, &m);
1946
1947         ad = ~m;
1948
1949         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
1950
1951         *(dest + i) = d;
1952     }
1953 }
1954
1955 static void
1956 combine_atop_reverse_ca (pixman_implementation_t *imp,
1957                          pixman_op_t              op,
1958                          uint32_t *                dest,
1959                          const uint32_t *          src,
1960                          const uint32_t *          mask,
1961                          int                      width)
1962 {
1963     int i;
1964
1965     for (i = 0; i < width; ++i)
1966     {
1967         uint32_t d = *(dest + i);
1968         uint32_t s = *(src + i);
1969         uint32_t m = *(mask + i);
1970         uint32_t ad;
1971         uint16_t as = ~d >> A_SHIFT;
1972
1973         combine_mask_ca (&s, &m);
1974
1975         ad = m;
1976
1977         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
1978
1979         *(dest + i) = d;
1980     }
1981 }
1982
1983 static void
1984 combine_xor_ca (pixman_implementation_t *imp,
1985                 pixman_op_t              op,
1986                 uint32_t *                dest,
1987                 const uint32_t *          src,
1988                 const uint32_t *          mask,
1989                 int                      width)
1990 {
1991     int i;
1992
1993     for (i = 0; i < width; ++i)
1994     {
1995         uint32_t d = *(dest + i);
1996         uint32_t s = *(src + i);
1997         uint32_t m = *(mask + i);
1998         uint32_t ad;
1999         uint16_t as = ~d >> A_SHIFT;
2000
2001         combine_mask_ca (&s, &m);
2002
2003         ad = ~m;
2004
2005         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
2006
2007         *(dest + i) = d;
2008     }
2009 }
2010
2011 static void
2012 combine_add_ca (pixman_implementation_t *imp,
2013                 pixman_op_t              op,
2014                 uint32_t *                dest,
2015                 const uint32_t *          src,
2016                 const uint32_t *          mask,
2017                 int                      width)
2018 {
2019     int i;
2020
2021     for (i = 0; i < width; ++i)
2022     {
2023         uint32_t s = *(src + i);
2024         uint32_t m = *(mask + i);
2025         uint32_t d = *(dest + i);
2026
2027         combine_mask_value_ca (&s, &m);
2028
2029         UN8x4_ADD_UN8x4 (d, s);
2030
2031         *(dest + i) = d;
2032     }
2033 }
2034
2035 static void
2036 combine_saturate_ca (pixman_implementation_t *imp,
2037                      pixman_op_t              op,
2038                      uint32_t *                dest,
2039                      const uint32_t *          src,
2040                      const uint32_t *          mask,
2041                      int                      width)
2042 {
2043     int i;
2044
2045     for (i = 0; i < width; ++i)
2046     {
2047         uint32_t s, d;
2048         uint16_t sa, sr, sg, sb, da;
2049         uint16_t t, u, v;
2050         uint32_t m, n, o, p;
2051
2052         d = *(dest + i);
2053         s = *(src + i);
2054         m = *(mask + i);
2055
2056         combine_mask_ca (&s, &m);
2057
2058         sa = (m >> A_SHIFT);
2059         sr = (m >> R_SHIFT) & MASK;
2060         sg = (m >> G_SHIFT) & MASK;
2061         sb =  m             & MASK;
2062         da = ~d >> A_SHIFT;
2063
2064         if (sb <= da)
2065             m = ADD (s, d, 0, t);
2066         else
2067             m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
2068
2069         if (sg <= da)
2070             n = ADD (s, d, G_SHIFT, t);
2071         else
2072             n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
2073
2074         if (sr <= da)
2075             o = ADD (s, d, R_SHIFT, t);
2076         else
2077             o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
2078
2079         if (sa <= da)
2080             p = ADD (s, d, A_SHIFT, t);
2081         else
2082             p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
2083
2084         *(dest + i) = m | n | o | p;
2085     }
2086 }
2087
2088 static void
2089 combine_disjoint_general_ca (uint32_t *      dest,
2090                              const uint32_t *src,
2091                              const uint32_t *mask,
2092                              int            width,
2093                              uint8_t        combine)
2094 {
2095     int i;
2096
2097     for (i = 0; i < width; ++i)
2098     {
2099         uint32_t s, d;
2100         uint32_t m, n, o, p;
2101         uint32_t Fa, Fb;
2102         uint16_t t, u, v;
2103         uint32_t sa;
2104         uint8_t da;
2105
2106         s = *(src + i);
2107         m = *(mask + i);
2108         d = *(dest + i);
2109         da = d >> A_SHIFT;
2110
2111         combine_mask_ca (&s, &m);
2112
2113         sa = m;
2114
2115         switch (combine & COMBINE_A)
2116         {
2117         default:
2118             Fa = 0;
2119             break;
2120
2121         case COMBINE_A_OUT:
2122             m = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> 0), da);
2123             n = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
2124             o = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
2125             p = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
2126             Fa = m | n | o | p;
2127             break;
2128
2129         case COMBINE_A_IN:
2130             m = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> 0), da);
2131             n = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
2132             o = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
2133             p = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
2134             Fa = m | n | o | p;
2135             break;
2136
2137         case COMBINE_A:
2138             Fa = ~0;
2139             break;
2140         }
2141
2142         switch (combine & COMBINE_B)
2143         {
2144         default:
2145             Fb = 0;
2146             break;
2147
2148         case COMBINE_B_OUT:
2149             m = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> 0));
2150             n = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
2151             o = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
2152             p = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
2153             Fb = m | n | o | p;
2154             break;
2155
2156         case COMBINE_B_IN:
2157             m = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> 0));
2158             n = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
2159             o = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
2160             p = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
2161             Fb = m | n | o | p;
2162             break;
2163
2164         case COMBINE_B:
2165             Fb = ~0;
2166             break;
2167         }
2168         m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
2169         n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
2170         o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
2171         p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
2172
2173         s = m | n | o | p;
2174
2175         *(dest + i) = s;
2176     }
2177 }
2178
2179 static void
2180 combine_disjoint_over_ca (pixman_implementation_t *imp,
2181                           pixman_op_t              op,
2182                           uint32_t *                dest,
2183                           const uint32_t *          src,
2184                           const uint32_t *          mask,
2185                           int                      width)
2186 {
2187     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2188 }
2189
2190 static void
2191 combine_disjoint_in_ca (pixman_implementation_t *imp,
2192                         pixman_op_t              op,
2193                         uint32_t *                dest,
2194                         const uint32_t *          src,
2195                         const uint32_t *          mask,
2196                         int                      width)
2197 {
2198     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2199 }
2200
2201 static void
2202 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp,
2203                                 pixman_op_t              op,
2204                                 uint32_t *                dest,
2205                                 const uint32_t *          src,
2206                                 const uint32_t *          mask,
2207                                 int                      width)
2208 {
2209     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2210 }
2211
2212 static void
2213 combine_disjoint_out_ca (pixman_implementation_t *imp,
2214                          pixman_op_t              op,
2215                          uint32_t *                dest,
2216                          const uint32_t *          src,
2217                          const uint32_t *          mask,
2218                          int                      width)
2219 {
2220     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2221 }
2222
2223 static void
2224 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp,
2225                                  pixman_op_t              op,
2226                                  uint32_t *                dest,
2227                                  const uint32_t *          src,
2228                                  const uint32_t *          mask,
2229                                  int                      width)
2230 {
2231     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2232 }
2233
2234 static void
2235 combine_disjoint_atop_ca (pixman_implementation_t *imp,
2236                           pixman_op_t              op,
2237                           uint32_t *                dest,
2238                           const uint32_t *          src,
2239                           const uint32_t *          mask,
2240                           int                      width)
2241 {
2242     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2243 }
2244
2245 static void
2246 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp,
2247                                   pixman_op_t              op,
2248                                   uint32_t *                dest,
2249                                   const uint32_t *          src,
2250                                   const uint32_t *          mask,
2251                                   int                      width)
2252 {
2253     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2254 }
2255
2256 static void
2257 combine_disjoint_xor_ca (pixman_implementation_t *imp,
2258                          pixman_op_t              op,
2259                          uint32_t *                dest,
2260                          const uint32_t *          src,
2261                          const uint32_t *          mask,
2262                          int                      width)
2263 {
2264     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2265 }
2266
2267 static void
2268 combine_conjoint_general_ca (uint32_t *      dest,
2269                              const uint32_t *src,
2270                              const uint32_t *mask,
2271                              int            width,
2272                              uint8_t        combine)
2273 {
2274     int i;
2275
2276     for (i = 0; i < width; ++i)
2277     {
2278         uint32_t s, d;
2279         uint32_t m, n, o, p;
2280         uint32_t Fa, Fb;
2281         uint16_t t, u, v;
2282         uint32_t sa;
2283         uint8_t da;
2284
2285         s = *(src + i);
2286         m = *(mask + i);
2287         d = *(dest + i);
2288         da = d >> A_SHIFT;
2289
2290         combine_mask_ca (&s, &m);
2291
2292         sa = m;
2293
2294         switch (combine & COMBINE_A)
2295         {
2296         default:
2297             Fa = 0;
2298             break;
2299
2300         case COMBINE_A_OUT:
2301             m = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> 0), da);
2302             n = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
2303             o = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
2304             p = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
2305             Fa = m | n | o | p;
2306             break;
2307
2308         case COMBINE_A_IN:
2309             m = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> 0), da);
2310             n = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
2311             o = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
2312             p = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
2313             Fa = m | n | o | p;
2314             break;
2315
2316         case COMBINE_A:
2317             Fa = ~0;
2318             break;
2319         }
2320
2321         switch (combine & COMBINE_B)
2322         {
2323         default:
2324             Fb = 0;
2325             break;
2326
2327         case COMBINE_B_OUT:
2328             m = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> 0));
2329             n = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
2330             o = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
2331             p = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
2332             Fb = m | n | o | p;
2333             break;
2334
2335         case COMBINE_B_IN:
2336             m = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> 0));
2337             n = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
2338             o = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
2339             p = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
2340             Fb = m | n | o | p;
2341             break;
2342
2343         case COMBINE_B:
2344             Fb = ~0;
2345             break;
2346         }
2347         m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
2348         n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
2349         o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
2350         p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
2351
2352         s = m | n | o | p;
2353
2354         *(dest + i) = s;
2355     }
2356 }
2357
2358 static void
2359 combine_conjoint_over_ca (pixman_implementation_t *imp,
2360                           pixman_op_t              op,
2361                           uint32_t *                dest,
2362                           const uint32_t *          src,
2363                           const uint32_t *          mask,
2364                           int                      width)
2365 {
2366     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2367 }
2368
2369 static void
2370 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp,
2371                                   pixman_op_t              op,
2372                                   uint32_t *                dest,
2373                                   const uint32_t *          src,
2374                                   const uint32_t *          mask,
2375                                   int                      width)
2376 {
2377     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
2378 }
2379
2380 static void
2381 combine_conjoint_in_ca (pixman_implementation_t *imp,
2382                         pixman_op_t              op,
2383                         uint32_t *                dest,
2384                         const uint32_t *          src,
2385                         const uint32_t *          mask,
2386                         int                      width)
2387 {
2388     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2389 }
2390
2391 static void
2392 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp,
2393                                 pixman_op_t              op,
2394                                 uint32_t *                dest,
2395                                 const uint32_t *          src,
2396                                 const uint32_t *          mask,
2397                                 int                      width)
2398 {
2399     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2400 }
2401
2402 static void
2403 combine_conjoint_out_ca (pixman_implementation_t *imp,
2404                          pixman_op_t              op,
2405                          uint32_t *                dest,
2406                          const uint32_t *          src,
2407                          const uint32_t *          mask,
2408                          int                      width)
2409 {
2410     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2411 }
2412
2413 static void
2414 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp,
2415                                  pixman_op_t              op,
2416                                  uint32_t *                dest,
2417                                  const uint32_t *          src,
2418                                  const uint32_t *          mask,
2419                                  int                      width)
2420 {
2421     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2422 }
2423
2424 static void
2425 combine_conjoint_atop_ca (pixman_implementation_t *imp,
2426                           pixman_op_t              op,
2427                           uint32_t *                dest,
2428                           const uint32_t *          src,
2429                           const uint32_t *          mask,
2430                           int                      width)
2431 {
2432     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2433 }
2434
2435 static void
2436 combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp,
2437                                   pixman_op_t              op,
2438                                   uint32_t *                dest,
2439                                   const uint32_t *          src,
2440                                   const uint32_t *          mask,
2441                                   int                      width)
2442 {
2443     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2444 }
2445
2446 static void
2447 combine_conjoint_xor_ca (pixman_implementation_t *imp,
2448                          pixman_op_t              op,
2449                          uint32_t *                dest,
2450                          const uint32_t *          src,
2451                          const uint32_t *          mask,
2452                          int                      width)
2453 {
2454     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2455 }
2456
2457 void
2458 _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp)
2459 {
2460     /* Unified alpha */
2461     imp->combine_32[PIXMAN_OP_CLEAR] = combine_clear;
2462     imp->combine_32[PIXMAN_OP_SRC] = combine_src_u;
2463     imp->combine_32[PIXMAN_OP_DST] = combine_dst;
2464     imp->combine_32[PIXMAN_OP_OVER] = combine_over_u;
2465     imp->combine_32[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u;
2466     imp->combine_32[PIXMAN_OP_IN] = combine_in_u;
2467     imp->combine_32[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u;
2468     imp->combine_32[PIXMAN_OP_OUT] = combine_out_u;
2469     imp->combine_32[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u;
2470     imp->combine_32[PIXMAN_OP_ATOP] = combine_atop_u;
2471     imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u;
2472     imp->combine_32[PIXMAN_OP_XOR] = combine_xor_u;
2473     imp->combine_32[PIXMAN_OP_ADD] = combine_add_u;
2474     imp->combine_32[PIXMAN_OP_SATURATE] = combine_saturate_u;
2475
2476     /* Disjoint, unified */
2477     imp->combine_32[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear;
2478     imp->combine_32[PIXMAN_OP_DISJOINT_SRC] = combine_src_u;
2479     imp->combine_32[PIXMAN_OP_DISJOINT_DST] = combine_dst;
2480     imp->combine_32[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u;
2481     imp->combine_32[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u;
2482     imp->combine_32[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u;
2483     imp->combine_32[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u;
2484     imp->combine_32[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u;
2485     imp->combine_32[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u;
2486     imp->combine_32[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u;
2487     imp->combine_32[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u;
2488     imp->combine_32[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u;
2489
2490     /* Conjoint, unified */
2491     imp->combine_32[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear;
2492     imp->combine_32[PIXMAN_OP_CONJOINT_SRC] = combine_src_u;
2493     imp->combine_32[PIXMAN_OP_CONJOINT_DST] = combine_dst;
2494     imp->combine_32[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u;
2495     imp->combine_32[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u;
2496     imp->combine_32[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u;
2497     imp->combine_32[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u;
2498     imp->combine_32[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u;
2499     imp->combine_32[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u;
2500     imp->combine_32[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u;
2501     imp->combine_32[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u;
2502     imp->combine_32[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u;
2503
2504     imp->combine_32[PIXMAN_OP_MULTIPLY] = combine_multiply_u;
2505     imp->combine_32[PIXMAN_OP_SCREEN] = combine_screen_u;
2506     imp->combine_32[PIXMAN_OP_OVERLAY] = combine_overlay_u;
2507     imp->combine_32[PIXMAN_OP_DARKEN] = combine_darken_u;
2508     imp->combine_32[PIXMAN_OP_LIGHTEN] = combine_lighten_u;
2509     imp->combine_32[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u;
2510     imp->combine_32[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u;
2511     imp->combine_32[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u;
2512     imp->combine_32[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u;
2513     imp->combine_32[PIXMAN_OP_DIFFERENCE] = combine_difference_u;
2514     imp->combine_32[PIXMAN_OP_EXCLUSION] = combine_exclusion_u;
2515     imp->combine_32[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u;
2516     imp->combine_32[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u;
2517     imp->combine_32[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u;
2518     imp->combine_32[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u;
2519
2520     /* Component alpha combiners */
2521     imp->combine_32_ca[PIXMAN_OP_CLEAR] = combine_clear_ca;
2522     imp->combine_32_ca[PIXMAN_OP_SRC] = combine_src_ca;
2523     /* dest */
2524     imp->combine_32_ca[PIXMAN_OP_OVER] = combine_over_ca;
2525     imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca;
2526     imp->combine_32_ca[PIXMAN_OP_IN] = combine_in_ca;
2527     imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca;
2528     imp->combine_32_ca[PIXMAN_OP_OUT] = combine_out_ca;
2529     imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca;
2530     imp->combine_32_ca[PIXMAN_OP_ATOP] = combine_atop_ca;
2531     imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca;
2532     imp->combine_32_ca[PIXMAN_OP_XOR] = combine_xor_ca;
2533     imp->combine_32_ca[PIXMAN_OP_ADD] = combine_add_ca;
2534     imp->combine_32_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca;
2535
2536     /* Disjoint CA */
2537     imp->combine_32_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca;
2538     imp->combine_32_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca;
2539     imp->combine_32_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst;
2540     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca;
2541     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca;
2542     imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca;
2543     imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca;
2544     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca;
2545     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca;
2546     imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca;
2547     imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca;
2548     imp->combine_32_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca;
2549
2550     /* Conjoint CA */
2551     imp->combine_32_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca;
2552     imp->combine_32_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca;
2553     imp->combine_32_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst;
2554     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca;
2555     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca;
2556     imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca;
2557     imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca;
2558     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca;
2559     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca;
2560     imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca;
2561     imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca;
2562     imp->combine_32_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca;
2563
2564     imp->combine_32_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca;
2565     imp->combine_32_ca[PIXMAN_OP_SCREEN] = combine_screen_ca;
2566     imp->combine_32_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca;
2567     imp->combine_32_ca[PIXMAN_OP_DARKEN] = combine_darken_ca;
2568     imp->combine_32_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca;
2569     imp->combine_32_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca;
2570     imp->combine_32_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca;
2571     imp->combine_32_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca;
2572     imp->combine_32_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca;
2573     imp->combine_32_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca;
2574     imp->combine_32_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca;
2575
2576     /* It is not clear that these make sense, so make them noops for now */
2577     imp->combine_32_ca[PIXMAN_OP_HSL_HUE] = combine_dst;
2578     imp->combine_32_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst;
2579     imp->combine_32_ca[PIXMAN_OP_HSL_COLOR] = combine_dst;
2580     imp->combine_32_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst;
2581 }