2 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
3 * 2005 Lars Knoll & Zack Rusin, Trolltech
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.
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
31 #include "pixman-private.h"
32 #include "pixman-combine32.h"
34 /* component alpha helper functions */
37 combine_mask_ca (uint32_t *src, uint32_t *mask)
61 UN8x4_MUL_UN8x4 (x, a);
64 UN8x4_MUL_UN8 (a, xa);
69 combine_mask_value_ca (uint32_t *src, const uint32_t *mask)
84 UN8x4_MUL_UN8x4 (x, a);
89 combine_mask_alpha_ca (const uint32_t *src, uint32_t *mask)
97 x = *(src) >> A_SHIFT;
109 UN8x4_MUL_UN8 (a, x);
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.
121 static force_inline uint32_t
122 combine_mask (const uint32_t *src, const uint32_t *mask, int i)
128 m = *(mask + i) >> A_SHIFT;
137 UN8x4_MUL_UN8 (s, m);
143 combine_clear (pixman_implementation_t *imp,
146 const uint32_t * src,
147 const uint32_t * mask,
150 memset (dest, 0, width * sizeof (uint32_t));
154 combine_dst (pixman_implementation_t *imp,
157 const uint32_t * src,
158 const uint32_t * mask,
165 combine_src_u (pixman_implementation_t *imp,
168 const uint32_t * src,
169 const uint32_t * mask,
176 memcpy (dest, src, width * sizeof (uint32_t));
180 for (i = 0; i < width; ++i)
182 uint32_t s = combine_mask (src, mask, i);
190 combine_over_u (pixman_implementation_t *imp,
193 const uint32_t * src,
194 const uint32_t * mask,
201 for (i = 0; i < width; ++i)
203 uint32_t s = *(src + i);
204 uint32_t a = ALPHA_8 (s);
211 uint32_t d = *(dest + i);
212 uint32_t ia = a ^ 0xFF;
213 UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
220 for (i = 0; i < width; ++i)
222 uint32_t m = ALPHA_8 (*(mask + i));
225 uint32_t s = *(src + i);
226 uint32_t a = ALPHA_8 (s);
233 uint32_t d = *(dest + i);
234 uint32_t ia = a ^ 0xFF;
235 UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
241 uint32_t s = *(src + i);
244 uint32_t d = *(dest + i);
245 UN8x4_MUL_UN8 (s, m);
246 UN8x4_MUL_UN8_ADD_UN8x4 (d, ALPHA_8 (~s), s);
255 combine_over_reverse_u (pixman_implementation_t *imp,
258 const uint32_t * src,
259 const uint32_t * mask,
264 for (i = 0; i < width; ++i)
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);
275 combine_in_u (pixman_implementation_t *imp,
278 const uint32_t * src,
279 const uint32_t * mask,
284 for (i = 0; i < width; ++i)
286 uint32_t s = combine_mask (src, mask, i);
287 uint32_t a = ALPHA_8 (*(dest + i));
288 UN8x4_MUL_UN8 (s, a);
294 combine_in_reverse_u (pixman_implementation_t *imp,
297 const uint32_t * src,
298 const uint32_t * mask,
303 for (i = 0; i < width; ++i)
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);
314 combine_out_u (pixman_implementation_t *imp,
317 const uint32_t * src,
318 const uint32_t * mask,
323 for (i = 0; i < width; ++i)
325 uint32_t s = combine_mask (src, mask, i);
326 uint32_t a = ALPHA_8 (~*(dest + i));
327 UN8x4_MUL_UN8 (s, a);
333 combine_out_reverse_u (pixman_implementation_t *imp,
336 const uint32_t * src,
337 const uint32_t * mask,
342 for (i = 0; i < width; ++i)
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);
353 combine_atop_u (pixman_implementation_t *imp,
356 const uint32_t * src,
357 const uint32_t * mask,
362 for (i = 0; i < width; ++i)
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);
369 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia);
375 combine_atop_reverse_u (pixman_implementation_t *imp,
378 const uint32_t * src,
379 const uint32_t * mask,
384 for (i = 0; i < width; ++i)
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);
391 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a);
397 combine_xor_u (pixman_implementation_t *imp,
400 const uint32_t * src,
401 const uint32_t * mask,
406 for (i = 0; i < width; ++i)
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);
413 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia);
419 combine_add_u (pixman_implementation_t *imp,
422 const uint32_t * src,
423 const uint32_t * mask,
428 for (i = 0; i < width; ++i)
430 uint32_t s = combine_mask (src, mask, i);
431 uint32_t d = *(dest + i);
432 UN8x4_ADD_UN8x4 (d, s);
438 combine_saturate_u (pixman_implementation_t *imp,
441 const uint32_t * src,
442 const uint32_t * mask,
447 for (i = 0; i < width; ++i)
449 uint32_t s = combine_mask (src, mask, i);
450 uint32_t d = *(dest + i);
457 sa = DIV_UN8 (da, sa);
458 UN8x4_MUL_UN8 (s, sa);
461 UN8x4_ADD_UN8x4 (d, s);
470 * The following blend modes have been taken from the PDF ISO 32000
471 * specification, which at this point in time is available from
473 * http://www.adobe.com/devnet/pdf/pdf_reference.html
475 * The specific documents of interest are the PDF spec itself:
477 * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf
479 * chapters 11.3.5 and 11.3.6 and a later supplement for Adobe Acrobat
480 * 9.1 and Reader 9.1:
482 * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf
484 * that clarifies the specifications for blend modes ColorDodge and
487 * The formula for computing the final pixel color given in 11.3.6 is:
489 * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs)
491 * with B() is the blend function. When B(Cb, Cs) = Cs, this formula
492 * reduces to the regular OVER operator.
494 * Cs and Cb are not premultiplied, so in our implementation we instead
497 * cr = (1 – αs) × cb + (1 – αb) × cs + αb × αs × B (cb/αb, cs/αs)
499 * where cr, cs, and cb are premultiplied colors, and where the
501 * αb × αs × B(cb/αb, cs/αs)
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
507 * For all the blend mode operators, the alpha channel is given by
509 * αr = αs + αb + αb × αs
515 * ad * as * B(d / ad, s / as)
516 * = ad * as * d/ad * s/as
521 combine_multiply_u (pixman_implementation_t *imp,
524 const uint32_t * src,
525 const uint32_t * mask,
530 for (i = 0; i < width; ++i)
532 uint32_t s = combine_mask (src, mask, i);
533 uint32_t d = *(dest + i);
535 uint32_t src_ia = ALPHA_8 (~s);
536 uint32_t dest_ia = ALPHA_8 (~d);
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);
547 combine_multiply_ca (pixman_implementation_t *imp,
550 const uint32_t * src,
551 const uint32_t * mask,
556 for (i = 0; i < width; ++i)
558 uint32_t m = *(mask + i);
559 uint32_t s = *(src + i);
560 uint32_t d = *(dest + i);
562 uint32_t dest_ia = ALPHA_8 (~d);
564 combine_mask_ca (&s, &m);
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);
574 #define PDF_SEPARABLE_BLEND_MODE(name) \
576 combine_ ## name ## _u (pixman_implementation_t *imp, \
579 const uint32_t * src, \
580 const uint32_t * mask, \
584 for (i = 0; i < width; ++i) \
586 uint32_t s = combine_mask (src, mask, i); \
587 uint32_t d = *(dest + i); \
588 uint8_t sa = ALPHA_8 (s); \
590 uint8_t da = ALPHA_8 (d); \
595 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \
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)); \
606 combine_ ## name ## _ca (pixman_implementation_t *imp, \
609 const uint32_t * src, \
610 const uint32_t * mask, \
614 for (i = 0; i < width; ++i) \
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); \
623 combine_mask_ca (&s, &m); \
626 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (result, ~m, s, ida); \
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))); \
634 *(dest + i) = result; \
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
645 static inline uint32_t
646 blend_screen (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
648 return DIV_ONE_UN8 (s * ad + d * as - s * d);
651 PDF_SEPARABLE_BLEND_MODE (screen)
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)
661 * as * ad * Screen (s/as, 2 * d / ad - 1)
662 * = if (d < 0.5 * ad)
663 * as * ad * s/as * 2 * d /ad
665 * as * ad * (s/as + 2 * d / ad - 1 - s / as * (2 * d / ad - 1))
669 * ad * s + 2 * as * d - as * ad - ad * s * (2 * d / ad - 1)
673 * as * ad - 2 * (ad - d) * (as - s)
675 static inline uint32_t
676 blend_overlay (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
683 r = as * ad - 2 * (ad - d) * (as - s);
685 return DIV_ONE_UN8 (r);
688 PDF_SEPARABLE_BLEND_MODE (overlay)
693 * ad * as * B(d/ad, s/as)
694 * = ad * as * MIN(d/ad, s/as)
695 * = MIN (as * d, ad * s)
697 static inline uint32_t
698 blend_darken (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
703 return DIV_ONE_UN8 (s > d ? d : s);
706 PDF_SEPARABLE_BLEND_MODE (darken)
711 * ad * as * B(d/ad, s/as)
712 * = ad * as * MAX(d/ad, s/as)
713 * = MAX (as * d, ad * s)
715 static inline uint32_t
716 blend_lighten (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
721 return DIV_ONE_UN8 (s > d ? s : d);
724 PDF_SEPARABLE_BLEND_MODE (lighten)
729 * ad * as * B(d/ad, s/as)
732 * else if (d/ad >= (1 - s/as)
735 * ad * as * ((d/ad) / (1 - s/as))
738 * elif as * d >= ad * (as - s)
741 * as * (as * d / (as - s))
744 static inline uint32_t
745 blend_color_dodge (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
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);
754 return DIV_ONE_UN8 (as * ((d * as) / ((as - s))));
757 PDF_SEPARABLE_BLEND_MODE (color_dodge)
762 * We modify the first clause "if d = 1" to "if d >= 1" since with
763 * premultiplied colors d > 1 can actually happen.
765 * ad * as * B(d/ad, s/as)
768 * elif (1 - d/ad) >= s/as
771 * ad * as * (1 - ((1 - d/ad) / (s/as)))
774 * elif as * ad - as * d >= ad * s
777 * ad * as - as * as * (ad - d) / s
779 static inline uint32_t
780 blend_color_burn (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
783 return DIV_ONE_UN8 (ad * as);
784 else if (as * ad - as * d >= ad * s)
789 return DIV_ONE_UN8 (ad * as - (as * as * (ad - d)) / s);
792 PDF_SEPARABLE_BLEND_MODE (color_burn)
797 * ad * as * B(d/ad, s/as)
799 * ad * as * Multiply (d/ad, 2 * s/as)
801 * ad * as * Screen (d/ad, 2 * s/as - 1)
803 * ad * as * d/ad * 2 * s / as
805 * ad * as * (d/ad + (2 * s/as - 1) + d/ad * (2 * s/as - 1))
809 * as * ad - 2 * (ad - d) * (as - s)
811 static inline uint32_t
812 blend_hard_light (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
815 return DIV_ONE_UN8 (2 * s * d);
817 return DIV_ONE_UN8 (as * ad - 2 * (ad - d) * (as - s));
820 PDF_SEPARABLE_BLEND_MODE (hard_light)
825 * ad * as * B(d/ad, s/as)
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))
831 * ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad))
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);
837 * d * as + (sqrt (d * ad) - d) * (2 * s - as);
839 static inline uint32_t
840 blend_soft_light (uint32_t d_org,
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);
856 r = d * as - d * (ad - d) * (as - 2 * s) / ad;
862 else if (4 * d <= ad)
865 (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3);
869 r = d * as + (sqrt (d * ad) - d) * (2 * s - as);
871 return r * MASK + 0.5;
874 PDF_SEPARABLE_BLEND_MODE (soft_light)
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)
884 * ad * as * (s/as - d/ad)
885 * = if (ad * s <= as * d)
890 static inline uint32_t
891 blend_difference (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
893 uint32_t das = d * as;
894 uint32_t sad = s * ad;
897 return DIV_ONE_UN8 (das - sad);
899 return DIV_ONE_UN8 (sad - das);
902 PDF_SEPARABLE_BLEND_MODE (difference)
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
912 /* This can be made faster by writing it directly and not using
913 * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
915 static inline uint32_t
916 blend_exclusion (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
918 return DIV_ONE_UN8 (s * ad + d * as - 2 * d * s);
921 PDF_SEPARABLE_BLEND_MODE (exclusion)
923 #undef PDF_SEPARABLE_BLEND_MODE
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.
930 * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
937 * C = l + (((C – l) × l) ⁄ (l – min))
939 * C = l + (((C – l) × (1 – l) ) ⁄ (max – l))
945 * return clip_color (C)
947 * SAT (C) = CH_MAX (C) - CH_MIN (C)
951 * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
959 /* For premultiplied colors, we need to know what happens when C is
960 * multiplied by a real number. LUM and SAT are linear:
962 * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C)
964 * If we extend clip_color with an extra argument a and change
972 * then clip_color is also linear:
974 * r * clip_color (C, a) = clip_color (r * C, r * a);
978 * Similarly, we can extend set_lum with an extra argument that is just passed
981 * r * set_lum (C, l, a)
983 * = r × clip_color (C + l - LUM (C), a)
985 * = clip_color (r * C + r × l - r * LUM (C), r * a)
987 * = set_lum (r * C, r * l, r * a)
991 * r * set_sat (C, s) = set_sat (x * C, r * s)
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:
996 * r * set_sat (C, s) = set_sat (r * C, r * s)
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))
1005 #define PDF_NON_SEPARABLE_BLEND_MODE(name) \
1007 combine_ ## name ## _u (pixman_implementation_t *imp, \
1010 const uint32_t * src, \
1011 const uint32_t * mask, \
1015 for (i = 0; i < width; ++i) \
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; \
1024 uint32_t sc[3], dc[3], c[3]; \
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); \
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])); \
1045 set_lum (uint32_t dest[3], uint32_t src[3], uint32_t sa, uint32_t lum)
1047 double a, l, min, max;
1050 a = sa * (1.0 / MASK);
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);
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);
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);
1098 dest[0] = tmp[0] * MASK + 0.5;
1099 dest[1] = tmp[1] * MASK + 0.5;
1100 dest[2] = tmp[2] * MASK + 0.5;
1104 set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat)
1109 if (src[0] > src[1])
1111 if (src[0] > src[2])
1114 if (src[1] > src[2])
1134 if (src[0] > src[2])
1143 if (src[1] > src[2])
1160 dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
1166 dest[0] = dest[1] = dest[2] = 0;
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)
1178 blend_hsl_hue (uint32_t r[3],
1187 set_sat (r, r, SAT (d) * as);
1188 set_lum (r, r, as * ad, LUM (d) * as);
1191 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
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))
1203 blend_hsl_saturation (uint32_t r[3],
1212 set_sat (r, r, SAT (s) * ad);
1213 set_lum (r, r, as * ad, LUM (d) * as);
1216 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
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)
1226 blend_hsl_color (uint32_t r[3],
1235 set_lum (r, r, as * ad, LUM (d) * as);
1238 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
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)
1248 blend_hsl_luminosity (uint32_t r[3],
1257 set_lum (r, r, as * ad, LUM (s) * ad);
1260 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
1266 #undef PDF_NON_SEPARABLE_BLEND_MODE
1268 /* All of the disjoint/conjoint composing functions
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.
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)
1290 * See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more
1291 * information about these operators.
1294 #define COMBINE_A_OUT 1
1295 #define COMBINE_A_IN 2
1296 #define COMBINE_B_OUT 4
1297 #define COMBINE_B_IN 8
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)
1308 /* portion covered by a but not b */
1310 combine_disjoint_out_part (uint8_t a, uint8_t b)
1312 /* min (1, (1-b) / a) */
1315 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
1316 return MASK; /* 1 */
1317 return DIV_UN8 (b, a); /* (1-b) / a */
1320 /* portion covered by both a and b */
1322 combine_disjoint_in_part (uint8_t a, uint8_t b)
1324 /* max (1-(1-b)/a,0) */
1325 /* = - min ((1-b)/a - 1, 0) */
1326 /* = 1 - min (1, (1-b)/a) */
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 */
1334 /* portion covered by a but not b */
1336 combine_conjoint_out_part (uint8_t a, uint8_t b)
1339 /* = 1-min(b/a,1) */
1341 /* min (1, (1-b) / a) */
1343 if (b >= a) /* b >= a -> b/a >= 1 */
1344 return 0x00; /* 0 */
1345 return ~DIV_UN8(b, a); /* 1 - b/a */
1348 /* portion covered by both a and b */
1350 combine_conjoint_in_part (uint8_t a, uint8_t b)
1354 if (b >= a) /* b >= a -> b/a >= 1 */
1355 return MASK; /* 1 */
1356 return DIV_UN8 (b, a); /* b/a */
1359 #define GET_COMP(v, i) ((uint16_t) (uint8_t) ((v) >> i))
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))
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))
1372 combine_disjoint_general_u (uint32_t * dest,
1373 const uint32_t *src,
1374 const uint32_t *mask,
1380 for (i = 0; i < width; ++i)
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;
1389 switch (combine & COMBINE_A)
1396 Fa = combine_disjoint_out_part (sa, da);
1400 Fa = combine_disjoint_in_part (sa, da);
1408 switch (combine & COMBINE_B)
1415 Fb = combine_disjoint_out_part (da, sa);
1419 Fb = combine_disjoint_in_part (da, sa);
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);
1436 combine_disjoint_over_u (pixman_implementation_t *imp,
1439 const uint32_t * src,
1440 const uint32_t * mask,
1445 for (i = 0; i < width; ++i)
1447 uint32_t s = combine_mask (src, mask, i);
1448 uint16_t a = s >> A_SHIFT;
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);
1462 combine_disjoint_in_u (pixman_implementation_t *imp,
1465 const uint32_t * src,
1466 const uint32_t * mask,
1469 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1473 combine_disjoint_in_reverse_u (pixman_implementation_t *imp,
1476 const uint32_t * src,
1477 const uint32_t * mask,
1480 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1484 combine_disjoint_out_u (pixman_implementation_t *imp,
1487 const uint32_t * src,
1488 const uint32_t * mask,
1491 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1495 combine_disjoint_out_reverse_u (pixman_implementation_t *imp,
1498 const uint32_t * src,
1499 const uint32_t * mask,
1502 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1506 combine_disjoint_atop_u (pixman_implementation_t *imp,
1509 const uint32_t * src,
1510 const uint32_t * mask,
1513 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1517 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp,
1520 const uint32_t * src,
1521 const uint32_t * mask,
1524 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1528 combine_disjoint_xor_u (pixman_implementation_t *imp,
1531 const uint32_t * src,
1532 const uint32_t * mask,
1535 combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1539 combine_conjoint_general_u (uint32_t * dest,
1540 const uint32_t *src,
1541 const uint32_t *mask,
1547 for (i = 0; i < width; ++i)
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;
1556 switch (combine & COMBINE_A)
1563 Fa = combine_conjoint_out_part (sa, da);
1567 Fa = combine_conjoint_in_part (sa, da);
1575 switch (combine & COMBINE_B)
1582 Fb = combine_conjoint_out_part (da, sa);
1586 Fb = combine_conjoint_in_part (da, sa);
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);
1606 combine_conjoint_over_u (pixman_implementation_t *imp,
1609 const uint32_t * src,
1610 const uint32_t * mask,
1613 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
1617 combine_conjoint_over_reverse_u (pixman_implementation_t *imp,
1620 const uint32_t * src,
1621 const uint32_t * mask,
1624 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
1628 combine_conjoint_in_u (pixman_implementation_t *imp,
1631 const uint32_t * src,
1632 const uint32_t * mask,
1635 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1639 combine_conjoint_in_reverse_u (pixman_implementation_t *imp,
1642 const uint32_t * src,
1643 const uint32_t * mask,
1646 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1650 combine_conjoint_out_u (pixman_implementation_t *imp,
1653 const uint32_t * src,
1654 const uint32_t * mask,
1657 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1661 combine_conjoint_out_reverse_u (pixman_implementation_t *imp,
1664 const uint32_t * src,
1665 const uint32_t * mask,
1668 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1672 combine_conjoint_atop_u (pixman_implementation_t *imp,
1675 const uint32_t * src,
1676 const uint32_t * mask,
1679 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1683 combine_conjoint_atop_reverse_u (pixman_implementation_t *imp,
1686 const uint32_t * src,
1687 const uint32_t * mask,
1690 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1694 combine_conjoint_xor_u (pixman_implementation_t *imp,
1697 const uint32_t * src,
1698 const uint32_t * mask,
1701 combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1705 /* Component alpha combiners */
1708 combine_clear_ca (pixman_implementation_t *imp,
1711 const uint32_t * src,
1712 const uint32_t * mask,
1715 memset (dest, 0, width * sizeof(uint32_t));
1719 combine_src_ca (pixman_implementation_t *imp,
1722 const uint32_t * src,
1723 const uint32_t * mask,
1728 for (i = 0; i < width; ++i)
1730 uint32_t s = *(src + i);
1731 uint32_t m = *(mask + i);
1733 combine_mask_value_ca (&s, &m);
1740 combine_over_ca (pixman_implementation_t *imp,
1743 const uint32_t * src,
1744 const uint32_t * mask,
1749 for (i = 0; i < width; ++i)
1751 uint32_t s = *(src + i);
1752 uint32_t m = *(mask + i);
1755 combine_mask_ca (&s, &m);
1760 uint32_t d = *(dest + i);
1761 UN8x4_MUL_UN8x4_ADD_UN8x4 (d, a, s);
1770 combine_over_reverse_ca (pixman_implementation_t *imp,
1773 const uint32_t * src,
1774 const uint32_t * mask,
1779 for (i = 0; i < width; ++i)
1781 uint32_t d = *(dest + i);
1782 uint32_t a = ~d >> A_SHIFT;
1786 uint32_t s = *(src + i);
1787 uint32_t m = *(mask + i);
1789 UN8x4_MUL_UN8x4 (s, m);
1790 UN8x4_MUL_UN8_ADD_UN8x4 (s, a, d);
1798 combine_in_ca (pixman_implementation_t *imp,
1801 const uint32_t * src,
1802 const uint32_t * mask,
1807 for (i = 0; i < width; ++i)
1809 uint32_t d = *(dest + i);
1810 uint16_t a = d >> A_SHIFT;
1815 uint32_t m = *(mask + i);
1818 combine_mask_value_ca (&s, &m);
1821 UN8x4_MUL_UN8 (s, a);
1829 combine_in_reverse_ca (pixman_implementation_t *imp,
1832 const uint32_t * src,
1833 const uint32_t * mask,
1838 for (i = 0; i < width; ++i)
1840 uint32_t s = *(src + i);
1841 uint32_t m = *(mask + i);
1844 combine_mask_alpha_ca (&s, &m);
1854 UN8x4_MUL_UN8x4 (d, a);
1863 combine_out_ca (pixman_implementation_t *imp,
1866 const uint32_t * src,
1867 const uint32_t * mask,
1872 for (i = 0; i < width; ++i)
1874 uint32_t d = *(dest + i);
1875 uint16_t a = ~d >> A_SHIFT;
1880 uint32_t m = *(mask + i);
1883 combine_mask_value_ca (&s, &m);
1886 UN8x4_MUL_UN8 (s, a);
1894 combine_out_reverse_ca (pixman_implementation_t *imp,
1897 const uint32_t * src,
1898 const uint32_t * mask,
1903 for (i = 0; i < width; ++i)
1905 uint32_t s = *(src + i);
1906 uint32_t m = *(mask + i);
1909 combine_mask_alpha_ca (&s, &m);
1919 UN8x4_MUL_UN8x4 (d, a);
1928 combine_atop_ca (pixman_implementation_t *imp,
1931 const uint32_t * src,
1932 const uint32_t * mask,
1937 for (i = 0; i < width; ++i)
1939 uint32_t d = *(dest + i);
1940 uint32_t s = *(src + i);
1941 uint32_t m = *(mask + i);
1943 uint16_t as = d >> A_SHIFT;
1945 combine_mask_ca (&s, &m);
1949 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
1956 combine_atop_reverse_ca (pixman_implementation_t *imp,
1959 const uint32_t * src,
1960 const uint32_t * mask,
1965 for (i = 0; i < width; ++i)
1967 uint32_t d = *(dest + i);
1968 uint32_t s = *(src + i);
1969 uint32_t m = *(mask + i);
1971 uint16_t as = ~d >> A_SHIFT;
1973 combine_mask_ca (&s, &m);
1977 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
1984 combine_xor_ca (pixman_implementation_t *imp,
1987 const uint32_t * src,
1988 const uint32_t * mask,
1993 for (i = 0; i < width; ++i)
1995 uint32_t d = *(dest + i);
1996 uint32_t s = *(src + i);
1997 uint32_t m = *(mask + i);
1999 uint16_t as = ~d >> A_SHIFT;
2001 combine_mask_ca (&s, &m);
2005 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
2012 combine_add_ca (pixman_implementation_t *imp,
2015 const uint32_t * src,
2016 const uint32_t * mask,
2021 for (i = 0; i < width; ++i)
2023 uint32_t s = *(src + i);
2024 uint32_t m = *(mask + i);
2025 uint32_t d = *(dest + i);
2027 combine_mask_value_ca (&s, &m);
2029 UN8x4_ADD_UN8x4 (d, s);
2036 combine_saturate_ca (pixman_implementation_t *imp,
2039 const uint32_t * src,
2040 const uint32_t * mask,
2045 for (i = 0; i < width; ++i)
2048 uint16_t sa, sr, sg, sb, da;
2050 uint32_t m, n, o, p;
2056 combine_mask_ca (&s, &m);
2058 sa = (m >> A_SHIFT);
2059 sr = (m >> R_SHIFT) & MASK;
2060 sg = (m >> G_SHIFT) & MASK;
2065 m = ADD (s, d, 0, t);
2067 m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
2070 n = ADD (s, d, G_SHIFT, t);
2072 n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
2075 o = ADD (s, d, R_SHIFT, t);
2077 o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
2080 p = ADD (s, d, A_SHIFT, t);
2082 p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
2084 *(dest + i) = m | n | o | p;
2089 combine_disjoint_general_ca (uint32_t * dest,
2090 const uint32_t *src,
2091 const uint32_t *mask,
2097 for (i = 0; i < width; ++i)
2100 uint32_t m, n, o, p;
2111 combine_mask_ca (&s, &m);
2115 switch (combine & COMBINE_A)
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;
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;
2142 switch (combine & COMBINE_B)
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;
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;
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);
2180 combine_disjoint_over_ca (pixman_implementation_t *imp,
2183 const uint32_t * src,
2184 const uint32_t * mask,
2187 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2191 combine_disjoint_in_ca (pixman_implementation_t *imp,
2194 const uint32_t * src,
2195 const uint32_t * mask,
2198 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2202 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp,
2205 const uint32_t * src,
2206 const uint32_t * mask,
2209 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2213 combine_disjoint_out_ca (pixman_implementation_t *imp,
2216 const uint32_t * src,
2217 const uint32_t * mask,
2220 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2224 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp,
2227 const uint32_t * src,
2228 const uint32_t * mask,
2231 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2235 combine_disjoint_atop_ca (pixman_implementation_t *imp,
2238 const uint32_t * src,
2239 const uint32_t * mask,
2242 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2246 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp,
2249 const uint32_t * src,
2250 const uint32_t * mask,
2253 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2257 combine_disjoint_xor_ca (pixman_implementation_t *imp,
2260 const uint32_t * src,
2261 const uint32_t * mask,
2264 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2268 combine_conjoint_general_ca (uint32_t * dest,
2269 const uint32_t *src,
2270 const uint32_t *mask,
2276 for (i = 0; i < width; ++i)
2279 uint32_t m, n, o, p;
2290 combine_mask_ca (&s, &m);
2294 switch (combine & COMBINE_A)
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;
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;
2321 switch (combine & COMBINE_B)
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;
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;
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);
2359 combine_conjoint_over_ca (pixman_implementation_t *imp,
2362 const uint32_t * src,
2363 const uint32_t * mask,
2366 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2370 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp,
2373 const uint32_t * src,
2374 const uint32_t * mask,
2377 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
2381 combine_conjoint_in_ca (pixman_implementation_t *imp,
2384 const uint32_t * src,
2385 const uint32_t * mask,
2388 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2392 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp,
2395 const uint32_t * src,
2396 const uint32_t * mask,
2399 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2403 combine_conjoint_out_ca (pixman_implementation_t *imp,
2406 const uint32_t * src,
2407 const uint32_t * mask,
2410 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2414 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp,
2417 const uint32_t * src,
2418 const uint32_t * mask,
2421 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2425 combine_conjoint_atop_ca (pixman_implementation_t *imp,
2428 const uint32_t * src,
2429 const uint32_t * mask,
2432 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2436 combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp,
2439 const uint32_t * src,
2440 const uint32_t * mask,
2443 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2447 combine_conjoint_xor_ca (pixman_implementation_t *imp,
2450 const uint32_t * src,
2451 const uint32_t * mask,
2454 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2458 _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp)
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;