gfx/cairo/libpixman/src/pixman-combine32.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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
    28 #include <math.h>
    29 #include <string.h>
    31 #include "pixman-private.h"
    32 #include "pixman-combine32.h"
    34 /* component alpha helper functions */
    36 static void
    37 combine_mask_ca (uint32_t *src, uint32_t *mask)
    38 {
    39     uint32_t a = *mask;
    41     uint32_t x;
    42     uint16_t xa;
    44     if (!a)
    45     {
    46 	*(src) = 0;
    47 	return;
    48     }
    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     }
    60     xa = x >> A_SHIFT;
    61     UN8x4_MUL_UN8x4 (x, a);
    62     *(src) = x;
    64     UN8x4_MUL_UN8 (a, xa);
    65     *(mask) = a;
    66 }
    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;
    74     if (!a)
    75     {
    76 	*(src) = 0;
    77 	return;
    78     }
    80     if (a == ~0)
    81 	return;
    83     x = *(src);
    84     UN8x4_MUL_UN8x4 (x, a);
    85     *(src) = x;
    86 }
    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;
    94     if (!a)
    95 	return;
    97     x = *(src) >> A_SHIFT;
    98     if (x == MASK)
    99 	return;
   101     if (a == ~0)
   102     {
   103 	x |= x << G_SHIFT;
   104 	x |= x << R_SHIFT;
   105 	*(mask) = x;
   106 	return;
   107     }
   109     UN8x4_MUL_UN8 (a, x);
   110     *(mask) = a;
   111 }
   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  */
   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;
   126     if (mask)
   127     {
   128 	m = *(mask + i) >> A_SHIFT;
   130 	if (!m)
   131 	    return 0;
   132     }
   134     s = *(src + i);
   136     if (mask)
   137 	UN8x4_MUL_UN8 (s, m);
   139     return s;
   140 }
   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 }
   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 }
   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;
   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);
   184 	    *(dest + i) = s;
   185 	}
   186     }
   187 }
   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;
   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 }
   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;
   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 }
   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;
   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 }
   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;
   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 }
   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;
   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 }
   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;
   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 }
   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;
   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);
   369 	UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia);
   370 	*(dest + i) = s;
   371     }
   372 }
   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;
   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);
   391 	UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a);
   392 	*(dest + i) = s;
   393     }
   394 }
   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;
   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);
   413 	UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia);
   414 	*(dest + i) = s;
   415     }
   416 }
   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;
   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 }
   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;
   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;
   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 }
   466 /*
   467  * PDF blend modes:
   468  * The following blend modes have been taken from the PDF ISO 32000
   469  * specification, which at this point in time is available from
   470  * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
   471  * The relevant chapters are 11.3.5 and 11.3.6.
   472  * The formula for computing the final pixel color given in 11.3.6 is:
   473  * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs)
   474  * with B() being the blend function.
   475  * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs
   476  *
   477  * These blend modes should match the SVG filter draft specification, as
   478  * it has been designed to mirror ISO 32000. Note that at the current point
   479  * no released draft exists that shows this, as the formulas have not been
   480  * updated yet after the release of ISO 32000.
   481  *
   482  * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and
   483  * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
   484  * argument. Note that this implementation operates on premultiplied colors,
   485  * while the PDF specification does not. Therefore the code uses the formula
   486  * Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
   487  */
   489 /*
   490  * Multiply
   491  * B(Dca, ad, Sca, as) = Dca.Sca
   492  */
   493 static void
   494 combine_multiply_u (pixman_implementation_t *imp,
   495                     pixman_op_t              op,
   496                     uint32_t *                dest,
   497                     const uint32_t *          src,
   498                     const uint32_t *          mask,
   499                     int                      width)
   500 {
   501     int i;
   503     for (i = 0; i < width; ++i)
   504     {
   505 	uint32_t s = combine_mask (src, mask, i);
   506 	uint32_t d = *(dest + i);
   507 	uint32_t ss = s;
   508 	uint32_t src_ia = ALPHA_8 (~s);
   509 	uint32_t dest_ia = ALPHA_8 (~d);
   511 	UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (ss, dest_ia, d, src_ia);
   512 	UN8x4_MUL_UN8x4 (d, s);
   513 	UN8x4_ADD_UN8x4 (d, ss);
   515 	*(dest + i) = d;
   516     }
   517 }
   519 static void
   520 combine_multiply_ca (pixman_implementation_t *imp,
   521                      pixman_op_t              op,
   522                      uint32_t *                dest,
   523                      const uint32_t *          src,
   524                      const uint32_t *          mask,
   525                      int                      width)
   526 {
   527     int i;
   529     for (i = 0; i < width; ++i)
   530     {
   531 	uint32_t m = *(mask + i);
   532 	uint32_t s = *(src + i);
   533 	uint32_t d = *(dest + i);
   534 	uint32_t r = d;
   535 	uint32_t dest_ia = ALPHA_8 (~d);
   537 	combine_mask_ca (&s, &m);
   539 	UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (r, ~m, s, dest_ia);
   540 	UN8x4_MUL_UN8x4 (d, s);
   541 	UN8x4_ADD_UN8x4 (r, d);
   543 	*(dest + i) = r;
   544     }
   545 }
   547 #define PDF_SEPARABLE_BLEND_MODE(name)					\
   548     static void								\
   549     combine_ ## name ## _u (pixman_implementation_t *imp,		\
   550 			    pixman_op_t              op,		\
   551                             uint32_t *                dest,		\
   552 			    const uint32_t *          src,		\
   553 			    const uint32_t *          mask,		\
   554 			    int                      width)		\
   555     {									\
   556 	int i;								\
   557 	for (i = 0; i < width; ++i) {					\
   558 	    uint32_t s = combine_mask (src, mask, i);			\
   559 	    uint32_t d = *(dest + i);					\
   560 	    uint8_t sa = ALPHA_8 (s);					\
   561 	    uint8_t isa = ~sa;						\
   562 	    uint8_t da = ALPHA_8 (d);					\
   563 	    uint8_t ida = ~da;						\
   564 	    uint32_t result;						\
   565 									\
   566 	    result = d;							\
   567 	    UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida);	\
   568 	    								\
   569 	    *(dest + i) = result +					\
   570 		(DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) +		\
   571 		(blend_ ## name (RED_8 (d), da, RED_8 (s), sa) << R_SHIFT) + \
   572 		(blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa) << G_SHIFT) + \
   573 		(blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa));	\
   574 	}								\
   575     }									\
   576     									\
   577     static void								\
   578     combine_ ## name ## _ca (pixman_implementation_t *imp,		\
   579 			     pixman_op_t              op,		\
   580                              uint32_t *                dest,		\
   581 			     const uint32_t *          src,		\
   582 			     const uint32_t *          mask,		\
   583 			     int                     width)		\
   584     {									\
   585 	int i;								\
   586 	for (i = 0; i < width; ++i) {					\
   587 	    uint32_t m = *(mask + i);					\
   588 	    uint32_t s = *(src + i);					\
   589 	    uint32_t d = *(dest + i);					\
   590 	    uint8_t da = ALPHA_8 (d);					\
   591 	    uint8_t ida = ~da;						\
   592 	    uint32_t result;						\
   593             								\
   594 	    combine_mask_ca (&s, &m);					\
   595             								\
   596 	    result = d;							\
   597 	    UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (result, ~m, s, ida);     \
   598             								\
   599 	    result +=							\
   600 	        (DIV_ONE_UN8 (ALPHA_8 (m) * (uint32_t)da) << A_SHIFT) +	\
   601 	        (blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)) << R_SHIFT) + \
   602 	        (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)) << G_SHIFT) + \
   603 	        (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m))); \
   604 	    								\
   605 	    *(dest + i) = result;					\
   606 	}								\
   607     }
   609 /*
   610  * Screen
   611  * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca
   612  */
   613 static inline uint32_t
   614 blend_screen (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   615 {
   616     return DIV_ONE_UN8 (sca * da + dca * sa - sca * dca);
   617 }
   619 PDF_SEPARABLE_BLEND_MODE (screen)
   621 /*
   622  * Overlay
   623  * B(Dca, Da, Sca, Sa) =
   624  *   if 2.Dca < Da
   625  *     2.Sca.Dca
   626  *   otherwise
   627  *     Sa.Da - 2.(Da - Dca).(Sa - Sca)
   628  */
   629 static inline uint32_t
   630 blend_overlay (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   631 {
   632     uint32_t rca;
   634     if (2 * dca < da)
   635 	rca = 2 * sca * dca;
   636     else
   637 	rca = sa * da - 2 * (da - dca) * (sa - sca);
   638     return DIV_ONE_UN8 (rca);
   639 }
   641 PDF_SEPARABLE_BLEND_MODE (overlay)
   643 /*
   644  * Darken
   645  * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa)
   646  */
   647 static inline uint32_t
   648 blend_darken (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   649 {
   650     uint32_t s, d;
   652     s = sca * da;
   653     d = dca * sa;
   654     return DIV_ONE_UN8 (s > d ? d : s);
   655 }
   657 PDF_SEPARABLE_BLEND_MODE (darken)
   659 /*
   660  * Lighten
   661  * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa)
   662  */
   663 static inline uint32_t
   664 blend_lighten (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   665 {
   666     uint32_t s, d;
   668     s = sca * da;
   669     d = dca * sa;
   670     return DIV_ONE_UN8 (s > d ? s : d);
   671 }
   673 PDF_SEPARABLE_BLEND_MODE (lighten)
   675 /*
   676  * Color dodge
   677  * B(Dca, Da, Sca, Sa) =
   678  *   if Dca == 0
   679  *     0
   680  *   if Sca == Sa
   681  *     Sa.Da
   682  *   otherwise
   683  *     Sa.Da. min (1, Dca / Da / (1 - Sca/Sa))
   684  */
   685 static inline uint32_t
   686 blend_color_dodge (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   687 {
   688     if (sca >= sa)
   689     {
   690 	return dca == 0 ? 0 : DIV_ONE_UN8 (sa * da);
   691     }
   692     else
   693     {
   694 	uint32_t rca = dca * sa / (sa - sca);
   695 	return DIV_ONE_UN8 (sa * MIN (rca, da));
   696     }
   697 }
   699 PDF_SEPARABLE_BLEND_MODE (color_dodge)
   701 /*
   702  * Color burn
   703  * B(Dca, Da, Sca, Sa) =
   704  *   if Dca == Da
   705  *     Sa.Da
   706  *   if Sca == 0
   707  *     0
   708  *   otherwise
   709  *     Sa.Da.(1 - min (1, (1 - Dca/Da).Sa / Sca))
   710  */
   711 static inline uint32_t
   712 blend_color_burn (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   713 {
   714     if (sca == 0)
   715     {
   716 	return dca < da ? 0 : DIV_ONE_UN8 (sa * da);
   717     }
   718     else
   719     {
   720 	uint32_t rca = (da - dca) * sa / sca;
   721 	return DIV_ONE_UN8 (sa * (MAX (rca, da) - rca));
   722     }
   723 }
   725 PDF_SEPARABLE_BLEND_MODE (color_burn)
   727 /*
   728  * Hard light
   729  * B(Dca, Da, Sca, Sa) =
   730  *   if 2.Sca < Sa
   731  *     2.Sca.Dca
   732  *   otherwise
   733  *     Sa.Da - 2.(Da - Dca).(Sa - Sca)
   734  */
   735 static inline uint32_t
   736 blend_hard_light (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   737 {
   738     if (2 * sca < sa)
   739 	return DIV_ONE_UN8 (2 * sca * dca);
   740     else
   741 	return DIV_ONE_UN8 (sa * da - 2 * (da - dca) * (sa - sca));
   742 }
   744 PDF_SEPARABLE_BLEND_MODE (hard_light)
   746 /*
   747  * Soft light
   748  * B(Dca, Da, Sca, Sa) =
   749  *   if (2.Sca <= Sa)
   750  *     Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa))
   751  *   otherwise if Dca.4 <= Da
   752  *     Dca.(Sa + (2.Sca - Sa).((16.Dca/Da - 12).Dca/Da + 3)
   753  *   otherwise
   754  *     (Dca.Sa + (SQRT (Dca/Da).Da - Dca).(2.Sca - Sa))
   755  */
   756 static inline uint32_t
   757 blend_soft_light (uint32_t dca_org,
   758 		  uint32_t da_org,
   759 		  uint32_t sca_org,
   760 		  uint32_t sa_org)
   761 {
   762     double dca = dca_org * (1.0 / MASK);
   763     double da = da_org * (1.0 / MASK);
   764     double sca = sca_org * (1.0 / MASK);
   765     double sa = sa_org * (1.0 / MASK);
   766     double rca;
   768     if (2 * sca < sa)
   769     {
   770 	if (da == 0)
   771 	    rca = dca * sa;
   772 	else
   773 	    rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da;
   774     }
   775     else if (da == 0)
   776     {
   777 	rca = 0;
   778     }
   779     else if (4 * dca <= da)
   780     {
   781 	rca = dca * sa +
   782 	    (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3);
   783     }
   784     else
   785     {
   786 	rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa);
   787     }
   788     return rca * MASK + 0.5;
   789 }
   791 PDF_SEPARABLE_BLEND_MODE (soft_light)
   793 /*
   794  * Difference
   795  * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da)
   796  */
   797 static inline uint32_t
   798 blend_difference (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   799 {
   800     uint32_t dcasa = dca * sa;
   801     uint32_t scada = sca * da;
   803     if (scada < dcasa)
   804 	return DIV_ONE_UN8 (dcasa - scada);
   805     else
   806 	return DIV_ONE_UN8 (scada - dcasa);
   807 }
   809 PDF_SEPARABLE_BLEND_MODE (difference)
   811 /*
   812  * Exclusion
   813  * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca)
   814  */
   816 /* This can be made faster by writing it directly and not using
   817  * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
   819 static inline uint32_t
   820 blend_exclusion (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
   821 {
   822     return DIV_ONE_UN8 (sca * da + dca * sa - 2 * dca * sca);
   823 }
   825 PDF_SEPARABLE_BLEND_MODE (exclusion)
   827 #undef PDF_SEPARABLE_BLEND_MODE
   829 /*
   830  * PDF nonseperable blend modes are implemented using the following functions
   831  * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid
   832  * and min value of the red, green and blue components.
   833  *
   834  * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
   835  *
   836  * clip_color (C):
   837  *   l = LUM (C)
   838  *   min = Cmin
   839  *   max = Cmax
   840  *   if n < 0.0
   841  *     C = l + ( ( ( C – l ) × l ) ⁄ ( l – min ) )
   842  *   if x > 1.0
   843  *     C = l + ( ( ( C – l ) × ( 1 – l ) ) ⁄ ( max – l ) )
   844  *   return C
   845  *
   846  * set_lum (C, l):
   847  *   d = l – LUM (C)
   848  *   C += d
   849  *   return clip_color (C)
   850  *
   851  * SAT (C) = CH_MAX (C) - CH_MIN (C)
   852  *
   853  * set_sat (C, s):
   854  *  if Cmax > Cmin
   855  *    Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
   856  *    Cmax = s
   857  *  else
   858  *    Cmid = Cmax = 0.0
   859  *  Cmin = 0.0
   860  *  return C
   861  */
   863 /* For premultiplied colors, we need to know what happens when C is
   864  * multiplied by a real number. LUM and SAT are linear:
   865  *
   866  *    LUM (r × C) = r × LUM (C)		SAT (r * C) = r * SAT (C)
   867  *
   868  * If we extend clip_color with an extra argument a and change
   869  *
   870  *        if x >= 1.0
   871  *
   872  * into
   873  *
   874  *        if x >= a
   875  *
   876  * then clip_color is also linear:
   877  *
   878  *    r * clip_color (C, a) = clip_color (r_c, ra);
   879  *
   880  * for positive r.
   881  *
   882  * Similarly, we can extend set_lum with an extra argument that is just passed
   883  * on to clip_color:
   884  *
   885  *   r * set_lum ( C, l, a)
   886  *
   887  *   = r × clip_color ( C + l - LUM (C), a)
   888  *
   889  *   = clip_color ( r * C + r × l - r * LUM (C), r * a)
   890  *
   891  *   = set_lum ( r * C, r * l, r * a)
   892  *
   893  * Finally, set_sat:
   894  *
   895  *    r * set_sat (C, s) = set_sat (x * C, r * s)
   896  *
   897  * The above holds for all non-zero x, because the x'es in the fraction for
   898  * C_mid cancel out. Specifically, it holds for x = r:
   899  *
   900  *    r * set_sat (C, s) = set_sat (r_c, rs)
   901  *
   902  */
   904 /* So, for the non-separable PDF blend modes, we have (using s, d for
   905  * non-premultiplied colors, and S, D for premultiplied:
   906  *
   907  *   Color:
   908  *
   909  *     a_s * a_d * B(s, d)
   910  *   = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1)
   911  *   = set_lum (S * a_d, a_s * LUM (D), a_s * a_d)
   912  *
   913  *
   914  *   Luminosity:
   915  *
   916  *     a_s * a_d * B(s, d)
   917  *   = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1)
   918  *   = set_lum (a_s * D, a_d * LUM(S), a_s * a_d)
   919  *
   920  *
   921  *   Saturation:
   922  *
   923  *     a_s * a_d * B(s, d)
   924  *   = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1)
   925  *   = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)),
   926  *                                        a_s * LUM (D), a_s * a_d)
   927  *   = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d))
   928  *
   929  *   Hue:
   930  *
   931  *     a_s * a_d * B(s, d)
   932  *   = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
   933  *   = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d)
   934  *
   935  */
   937 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2]))
   938 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2]))
   939 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100)
   940 #define SAT(c) (CH_MAX (c) - CH_MIN (c))
   942 #define PDF_NON_SEPARABLE_BLEND_MODE(name)				\
   943     static void								\
   944     combine_ ## name ## _u (pixman_implementation_t *imp,		\
   945 			    pixman_op_t op,				\
   946                             uint32_t *dest,				\
   947 			    const uint32_t *src,				\
   948 			    const uint32_t *mask,			\
   949 			    int width)					\
   950     {									\
   951 	int i;								\
   952 	for (i = 0; i < width; ++i)					\
   953 	{								\
   954 	    uint32_t s = combine_mask (src, mask, i);			\
   955 	    uint32_t d = *(dest + i);					\
   956 	    uint8_t sa = ALPHA_8 (s);					\
   957 	    uint8_t isa = ~sa;						\
   958 	    uint8_t da = ALPHA_8 (d);					\
   959 	    uint8_t ida = ~da;						\
   960 	    uint32_t result;						\
   961 	    uint32_t sc[3], dc[3], c[3];					\
   962             								\
   963 	    result = d;							\
   964 	    UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida);	\
   965 	    dc[0] = RED_8 (d);						\
   966 	    sc[0] = RED_8 (s);						\
   967 	    dc[1] = GREEN_8 (d);					\
   968 	    sc[1] = GREEN_8 (s);					\
   969 	    dc[2] = BLUE_8 (d);						\
   970 	    sc[2] = BLUE_8 (s);						\
   971 	    blend_ ## name (c, dc, da, sc, sa);				\
   972             								\
   973 	    *(dest + i) = result +					\
   974 		(DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) +		\
   975 		(DIV_ONE_UN8 (c[0]) << R_SHIFT) +			\
   976 		(DIV_ONE_UN8 (c[1]) << G_SHIFT) +			\
   977 		(DIV_ONE_UN8 (c[2]));					\
   978 	}								\
   979     }
   981 static void
   982 set_lum (uint32_t dest[3], uint32_t src[3], uint32_t sa, uint32_t lum)
   983 {
   984     double a, l, min, max;
   985     double tmp[3];
   987     a = sa * (1.0 / MASK);
   989     l = lum * (1.0 / MASK);
   990     tmp[0] = src[0] * (1.0 / MASK);
   991     tmp[1] = src[1] * (1.0 / MASK);
   992     tmp[2] = src[2] * (1.0 / MASK);
   994     l = l - LUM (tmp);
   995     tmp[0] += l;
   996     tmp[1] += l;
   997     tmp[2] += l;
   999     /* clip_color */
  1000     l = LUM (tmp);
  1001     min = CH_MIN (tmp);
  1002     max = CH_MAX (tmp);
  1004     if (min < 0)
  1006 	if (l - min == 0.0)
  1008 	    tmp[0] = 0;
  1009 	    tmp[1] = 0;
  1010 	    tmp[2] = 0;
  1012 	else
  1014 	    tmp[0] = l + (tmp[0] - l) * l / (l - min);
  1015 	    tmp[1] = l + (tmp[1] - l) * l / (l - min);
  1016 	    tmp[2] = l + (tmp[2] - l) * l / (l - min);
  1019     if (max > a)
  1021 	if (max - l == 0.0)
  1023 	    tmp[0] = a;
  1024 	    tmp[1] = a;
  1025 	    tmp[2] = a;
  1027 	else
  1029 	    tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
  1030 	    tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
  1031 	    tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
  1035     dest[0] = tmp[0] * MASK + 0.5;
  1036     dest[1] = tmp[1] * MASK + 0.5;
  1037     dest[2] = tmp[2] * MASK + 0.5;
  1040 static void
  1041 set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat)
  1043     int id[3];
  1044     uint32_t min, max;
  1046     if (src[0] > src[1])
  1048 	if (src[0] > src[2])
  1050 	    id[0] = 0;
  1051 	    if (src[1] > src[2])
  1053 		id[1] = 1;
  1054 		id[2] = 2;
  1056 	    else
  1058 		id[1] = 2;
  1059 		id[2] = 1;
  1062 	else
  1064 	    id[0] = 2;
  1065 	    id[1] = 0;
  1066 	    id[2] = 1;
  1069     else
  1071 	if (src[0] > src[2])
  1073 	    id[0] = 1;
  1074 	    id[1] = 0;
  1075 	    id[2] = 2;
  1077 	else
  1079 	    id[2] = 0;
  1080 	    if (src[1] > src[2])
  1082 		id[0] = 1;
  1083 		id[1] = 2;
  1085 	    else
  1087 		id[0] = 2;
  1088 		id[1] = 1;
  1093     max = dest[id[0]];
  1094     min = dest[id[2]];
  1095     if (max > min)
  1097 	dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
  1098 	dest[id[0]] = sat;
  1099 	dest[id[2]] = 0;
  1101     else
  1103 	dest[0] = dest[1] = dest[2] = 0;
  1107 /*
  1108  * Hue:
  1109  * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb))
  1110  */
  1111 static inline void
  1112 blend_hsl_hue (uint32_t c[3],
  1113                uint32_t dc[3],
  1114                uint32_t da,
  1115                uint32_t sc[3],
  1116                uint32_t sa)
  1118     c[0] = sc[0] * da;
  1119     c[1] = sc[1] * da;
  1120     c[2] = sc[2] * da;
  1121     set_sat (c, c, SAT (dc) * sa);
  1122     set_lum (c, c, sa * da, LUM (dc) * sa);
  1125 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
  1127 /*
  1128  * Saturation:
  1129  * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb))
  1130  */
  1131 static inline void
  1132 blend_hsl_saturation (uint32_t c[3],
  1133                       uint32_t dc[3],
  1134                       uint32_t da,
  1135                       uint32_t sc[3],
  1136                       uint32_t sa)
  1138     c[0] = dc[0] * sa;
  1139     c[1] = dc[1] * sa;
  1140     c[2] = dc[2] * sa;
  1141     set_sat (c, c, SAT (sc) * da);
  1142     set_lum (c, c, sa * da, LUM (dc) * sa);
  1145 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
  1147 /*
  1148  * Color:
  1149  * B(Cb, Cs) = set_lum (Cs, LUM (Cb))
  1150  */
  1151 static inline void
  1152 blend_hsl_color (uint32_t c[3],
  1153                  uint32_t dc[3],
  1154                  uint32_t da,
  1155                  uint32_t sc[3],
  1156                  uint32_t sa)
  1158     c[0] = sc[0] * da;
  1159     c[1] = sc[1] * da;
  1160     c[2] = sc[2] * da;
  1161     set_lum (c, c, sa * da, LUM (dc) * sa);
  1164 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
  1166 /*
  1167  * Luminosity:
  1168  * B(Cb, Cs) = set_lum (Cb, LUM (Cs))
  1169  */
  1170 static inline void
  1171 blend_hsl_luminosity (uint32_t c[3],
  1172                       uint32_t dc[3],
  1173                       uint32_t da,
  1174                       uint32_t sc[3],
  1175                       uint32_t sa)
  1177     c[0] = dc[0] * sa;
  1178     c[1] = dc[1] * sa;
  1179     c[2] = dc[2] * sa;
  1180     set_lum (c, c, sa * da, LUM (sc) * da);
  1183 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
  1185 #undef SAT
  1186 #undef LUM
  1187 #undef CH_MAX
  1188 #undef CH_MIN
  1189 #undef PDF_NON_SEPARABLE_BLEND_MODE
  1191 /* All of the disjoint/conjoint composing functions
  1193  * The four entries in the first column indicate what source contributions
  1194  * come from each of the four areas of the picture -- areas covered by neither
  1195  * A nor B, areas covered only by A, areas covered only by B and finally
  1196  * areas covered by both A and B.
  1198  * Disjoint			Conjoint
  1199  * Fa		Fb		Fa		Fb
  1200  * (0,0,0,0)	0		0		0		0
  1201  * (0,A,0,A)	1		0		1		0
  1202  * (0,0,B,B)	0		1		0		1
  1203  * (0,A,B,A)	1		min((1-a)/b,1)	1		max(1-a/b,0)
  1204  * (0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1
  1205  * (0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
  1206  * (0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
  1207  * (0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
  1208  * (0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
  1209  * (0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
  1210  * (0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
  1211  * (0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
  1213  * See  http://marc.info/?l=xfree-render&m=99792000027857&w=2  for more
  1214  * information about these operators.
  1215  */
  1217 #define COMBINE_A_OUT 1
  1218 #define COMBINE_A_IN  2
  1219 #define COMBINE_B_OUT 4
  1220 #define COMBINE_B_IN  8
  1222 #define COMBINE_CLEAR   0
  1223 #define COMBINE_A       (COMBINE_A_OUT | COMBINE_A_IN)
  1224 #define COMBINE_B       (COMBINE_B_OUT | COMBINE_B_IN)
  1225 #define COMBINE_A_OVER  (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN)
  1226 #define COMBINE_B_OVER  (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN)
  1227 #define COMBINE_A_ATOP  (COMBINE_B_OUT | COMBINE_A_IN)
  1228 #define COMBINE_B_ATOP  (COMBINE_A_OUT | COMBINE_B_IN)
  1229 #define COMBINE_XOR     (COMBINE_A_OUT | COMBINE_B_OUT)
  1231 /* portion covered by a but not b */
  1232 static uint8_t
  1233 combine_disjoint_out_part (uint8_t a, uint8_t b)
  1235     /* min (1, (1-b) / a) */
  1237     b = ~b;                 /* 1 - b */
  1238     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
  1239 	return MASK;        /* 1 */
  1240     return DIV_UN8 (b, a);     /* (1-b) / a */
  1243 /* portion covered by both a and b */
  1244 static uint8_t
  1245 combine_disjoint_in_part (uint8_t a, uint8_t b)
  1247     /* max (1-(1-b)/a,0) */
  1248     /*  = - min ((1-b)/a - 1, 0) */
  1249     /*  = 1 - min (1, (1-b)/a) */
  1251     b = ~b;                 /* 1 - b */
  1252     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
  1253 	return 0;           /* 1 - 1 */
  1254     return ~DIV_UN8(b, a);    /* 1 - (1-b) / a */
  1257 /* portion covered by a but not b */
  1258 static uint8_t
  1259 combine_conjoint_out_part (uint8_t a, uint8_t b)
  1261     /* max (1-b/a,0) */
  1262     /* = 1-min(b/a,1) */
  1264     /* min (1, (1-b) / a) */
  1266     if (b >= a)             /* b >= a -> b/a >= 1 */
  1267 	return 0x00;        /* 0 */
  1268     return ~DIV_UN8(b, a);    /* 1 - b/a */
  1271 /* portion covered by both a and b */
  1272 static uint8_t
  1273 combine_conjoint_in_part (uint8_t a, uint8_t b)
  1275     /* min (1,b/a) */
  1277     if (b >= a)             /* b >= a -> b/a >= 1 */
  1278 	return MASK;        /* 1 */
  1279     return DIV_UN8 (b, a);     /* b/a */
  1282 #define GET_COMP(v, i)   ((uint16_t) (uint8_t) ((v) >> i))
  1284 #define ADD(x, y, i, t)							\
  1285     ((t) = GET_COMP (x, i) + GET_COMP (y, i),				\
  1286      (uint32_t) ((uint8_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i))
  1288 #define GENERIC(x, y, i, ax, ay, t, u, v)				\
  1289     ((t) = (MUL_UN8 (GET_COMP (y, i), ay, (u)) +			\
  1290             MUL_UN8 (GET_COMP (x, i), ax, (v))),			\
  1291      (uint32_t) ((uint8_t) ((t) |					\
  1292                            (0 - ((t) >> G_SHIFT)))) << (i))
  1294 static void
  1295 combine_disjoint_general_u (uint32_t *      dest,
  1296                             const uint32_t *src,
  1297                             const uint32_t *mask,
  1298                             int            width,
  1299                             uint8_t        combine)
  1301     int i;
  1303     for (i = 0; i < width; ++i)
  1305 	uint32_t s = combine_mask (src, mask, i);
  1306 	uint32_t d = *(dest + i);
  1307 	uint32_t m, n, o, p;
  1308 	uint16_t Fa, Fb, t, u, v;
  1309 	uint8_t sa = s >> A_SHIFT;
  1310 	uint8_t da = d >> A_SHIFT;
  1312 	switch (combine & COMBINE_A)
  1314 	default:
  1315 	    Fa = 0;
  1316 	    break;
  1318 	case COMBINE_A_OUT:
  1319 	    Fa = combine_disjoint_out_part (sa, da);
  1320 	    break;
  1322 	case COMBINE_A_IN:
  1323 	    Fa = combine_disjoint_in_part (sa, da);
  1324 	    break;
  1326 	case COMBINE_A:
  1327 	    Fa = MASK;
  1328 	    break;
  1331 	switch (combine & COMBINE_B)
  1333 	default:
  1334 	    Fb = 0;
  1335 	    break;
  1337 	case COMBINE_B_OUT:
  1338 	    Fb = combine_disjoint_out_part (da, sa);
  1339 	    break;
  1341 	case COMBINE_B_IN:
  1342 	    Fb = combine_disjoint_in_part (da, sa);
  1343 	    break;
  1345 	case COMBINE_B:
  1346 	    Fb = MASK;
  1347 	    break;
  1349 	m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
  1350 	n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
  1351 	o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
  1352 	p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
  1353 	s = m | n | o | p;
  1354 	*(dest + i) = s;
  1358 static void
  1359 combine_disjoint_over_u (pixman_implementation_t *imp,
  1360                          pixman_op_t              op,
  1361                          uint32_t *                dest,
  1362                          const uint32_t *          src,
  1363                          const uint32_t *          mask,
  1364                          int                      width)
  1366     int i;
  1368     for (i = 0; i < width; ++i)
  1370 	uint32_t s = combine_mask (src, mask, i);
  1371 	uint16_t a = s >> A_SHIFT;
  1373 	if (s != 0x00)
  1375 	    uint32_t d = *(dest + i);
  1376 	    a = combine_disjoint_out_part (d >> A_SHIFT, a);
  1377 	    UN8x4_MUL_UN8_ADD_UN8x4 (d, a, s);
  1379 	    *(dest + i) = d;
  1384 static void
  1385 combine_disjoint_in_u (pixman_implementation_t *imp,
  1386                        pixman_op_t              op,
  1387                        uint32_t *                dest,
  1388                        const uint32_t *          src,
  1389                        const uint32_t *          mask,
  1390                        int                      width)
  1392     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
  1395 static void
  1396 combine_disjoint_in_reverse_u (pixman_implementation_t *imp,
  1397                                pixman_op_t              op,
  1398                                uint32_t *                dest,
  1399                                const uint32_t *          src,
  1400                                const uint32_t *          mask,
  1401                                int                      width)
  1403     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
  1406 static void
  1407 combine_disjoint_out_u (pixman_implementation_t *imp,
  1408                         pixman_op_t              op,
  1409                         uint32_t *                dest,
  1410                         const uint32_t *          src,
  1411                         const uint32_t *          mask,
  1412                         int                      width)
  1414     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
  1417 static void
  1418 combine_disjoint_out_reverse_u (pixman_implementation_t *imp,
  1419                                 pixman_op_t              op,
  1420                                 uint32_t *                dest,
  1421                                 const uint32_t *          src,
  1422                                 const uint32_t *          mask,
  1423                                 int                      width)
  1425     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
  1428 static void
  1429 combine_disjoint_atop_u (pixman_implementation_t *imp,
  1430                          pixman_op_t              op,
  1431                          uint32_t *                dest,
  1432                          const uint32_t *          src,
  1433                          const uint32_t *          mask,
  1434                          int                      width)
  1436     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
  1439 static void
  1440 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp,
  1441                                  pixman_op_t              op,
  1442                                  uint32_t *                dest,
  1443                                  const uint32_t *          src,
  1444                                  const uint32_t *          mask,
  1445                                  int                      width)
  1447     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
  1450 static void
  1451 combine_disjoint_xor_u (pixman_implementation_t *imp,
  1452                         pixman_op_t              op,
  1453                         uint32_t *                dest,
  1454                         const uint32_t *          src,
  1455                         const uint32_t *          mask,
  1456                         int                      width)
  1458     combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
  1461 static void
  1462 combine_conjoint_general_u (uint32_t *      dest,
  1463                             const uint32_t *src,
  1464                             const uint32_t *mask,
  1465                             int            width,
  1466                             uint8_t        combine)
  1468     int i;
  1470     for (i = 0; i < width; ++i)
  1472 	uint32_t s = combine_mask (src, mask, i);
  1473 	uint32_t d = *(dest + i);
  1474 	uint32_t m, n, o, p;
  1475 	uint16_t Fa, Fb, t, u, v;
  1476 	uint8_t sa = s >> A_SHIFT;
  1477 	uint8_t da = d >> A_SHIFT;
  1479 	switch (combine & COMBINE_A)
  1481 	default:
  1482 	    Fa = 0;
  1483 	    break;
  1485 	case COMBINE_A_OUT:
  1486 	    Fa = combine_conjoint_out_part (sa, da);
  1487 	    break;
  1489 	case COMBINE_A_IN:
  1490 	    Fa = combine_conjoint_in_part (sa, da);
  1491 	    break;
  1493 	case COMBINE_A:
  1494 	    Fa = MASK;
  1495 	    break;
  1498 	switch (combine & COMBINE_B)
  1500 	default:
  1501 	    Fb = 0;
  1502 	    break;
  1504 	case COMBINE_B_OUT:
  1505 	    Fb = combine_conjoint_out_part (da, sa);
  1506 	    break;
  1508 	case COMBINE_B_IN:
  1509 	    Fb = combine_conjoint_in_part (da, sa);
  1510 	    break;
  1512 	case COMBINE_B:
  1513 	    Fb = MASK;
  1514 	    break;
  1517 	m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
  1518 	n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
  1519 	o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
  1520 	p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
  1522 	s = m | n | o | p;
  1524 	*(dest + i) = s;
  1528 static void
  1529 combine_conjoint_over_u (pixman_implementation_t *imp,
  1530                          pixman_op_t              op,
  1531                          uint32_t *                dest,
  1532                          const uint32_t *          src,
  1533                          const uint32_t *          mask,
  1534                          int                      width)
  1536     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
  1539 static void
  1540 combine_conjoint_over_reverse_u (pixman_implementation_t *imp,
  1541                                  pixman_op_t              op,
  1542                                  uint32_t *                dest,
  1543                                  const uint32_t *          src,
  1544                                  const uint32_t *          mask,
  1545                                  int                      width)
  1547     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
  1550 static void
  1551 combine_conjoint_in_u (pixman_implementation_t *imp,
  1552                        pixman_op_t              op,
  1553                        uint32_t *                dest,
  1554                        const uint32_t *          src,
  1555                        const uint32_t *          mask,
  1556                        int                      width)
  1558     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
  1561 static void
  1562 combine_conjoint_in_reverse_u (pixman_implementation_t *imp,
  1563                                pixman_op_t              op,
  1564                                uint32_t *                dest,
  1565                                const uint32_t *          src,
  1566                                const uint32_t *          mask,
  1567                                int                      width)
  1569     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
  1572 static void
  1573 combine_conjoint_out_u (pixman_implementation_t *imp,
  1574                         pixman_op_t              op,
  1575                         uint32_t *                dest,
  1576                         const uint32_t *          src,
  1577                         const uint32_t *          mask,
  1578                         int                      width)
  1580     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
  1583 static void
  1584 combine_conjoint_out_reverse_u (pixman_implementation_t *imp,
  1585                                 pixman_op_t              op,
  1586                                 uint32_t *                dest,
  1587                                 const uint32_t *          src,
  1588                                 const uint32_t *          mask,
  1589                                 int                      width)
  1591     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
  1594 static void
  1595 combine_conjoint_atop_u (pixman_implementation_t *imp,
  1596                          pixman_op_t              op,
  1597                          uint32_t *                dest,
  1598                          const uint32_t *          src,
  1599                          const uint32_t *          mask,
  1600                          int                      width)
  1602     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
  1605 static void
  1606 combine_conjoint_atop_reverse_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)
  1613     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
  1616 static void
  1617 combine_conjoint_xor_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)
  1624     combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
  1628 /* Component alpha combiners */
  1630 static void
  1631 combine_clear_ca (pixman_implementation_t *imp,
  1632                   pixman_op_t              op,
  1633                   uint32_t *                dest,
  1634                   const uint32_t *          src,
  1635                   const uint32_t *          mask,
  1636                   int                      width)
  1638     memset (dest, 0, width * sizeof(uint32_t));
  1641 static void
  1642 combine_src_ca (pixman_implementation_t *imp,
  1643                 pixman_op_t              op,
  1644                 uint32_t *                dest,
  1645                 const uint32_t *          src,
  1646                 const uint32_t *          mask,
  1647                 int                      width)
  1649     int i;
  1651     for (i = 0; i < width; ++i)
  1653 	uint32_t s = *(src + i);
  1654 	uint32_t m = *(mask + i);
  1656 	combine_mask_value_ca (&s, &m);
  1658 	*(dest + i) = s;
  1662 static void
  1663 combine_over_ca (pixman_implementation_t *imp,
  1664                  pixman_op_t              op,
  1665                  uint32_t *                dest,
  1666                  const uint32_t *          src,
  1667                  const uint32_t *          mask,
  1668                  int                      width)
  1670     int i;
  1672     for (i = 0; i < width; ++i)
  1674 	uint32_t s = *(src + i);
  1675 	uint32_t m = *(mask + i);
  1676 	uint32_t a;
  1678 	combine_mask_ca (&s, &m);
  1680 	a = ~m;
  1681 	if (a)
  1683 	    uint32_t d = *(dest + i);
  1684 	    UN8x4_MUL_UN8x4_ADD_UN8x4 (d, a, s);
  1685 	    s = d;
  1688 	*(dest + i) = s;
  1692 static void
  1693 combine_over_reverse_ca (pixman_implementation_t *imp,
  1694                          pixman_op_t              op,
  1695                          uint32_t *                dest,
  1696                          const uint32_t *          src,
  1697                          const uint32_t *          mask,
  1698                          int                      width)
  1700     int i;
  1702     for (i = 0; i < width; ++i)
  1704 	uint32_t d = *(dest + i);
  1705 	uint32_t a = ~d >> A_SHIFT;
  1707 	if (a)
  1709 	    uint32_t s = *(src + i);
  1710 	    uint32_t m = *(mask + i);
  1712 	    UN8x4_MUL_UN8x4 (s, m);
  1713 	    UN8x4_MUL_UN8_ADD_UN8x4 (s, a, d);
  1715 	    *(dest + i) = s;
  1720 static void
  1721 combine_in_ca (pixman_implementation_t *imp,
  1722                pixman_op_t              op,
  1723                uint32_t *                dest,
  1724                const uint32_t *          src,
  1725                const uint32_t *          mask,
  1726                int                      width)
  1728     int i;
  1730     for (i = 0; i < width; ++i)
  1732 	uint32_t d = *(dest + i);
  1733 	uint16_t a = d >> A_SHIFT;
  1734 	uint32_t s = 0;
  1736 	if (a)
  1738 	    uint32_t m = *(mask + i);
  1740 	    s = *(src + i);
  1741 	    combine_mask_value_ca (&s, &m);
  1743 	    if (a != MASK)
  1744 		UN8x4_MUL_UN8 (s, a);
  1747 	*(dest + i) = s;
  1751 static void
  1752 combine_in_reverse_ca (pixman_implementation_t *imp,
  1753                        pixman_op_t              op,
  1754                        uint32_t *                dest,
  1755                        const uint32_t *          src,
  1756                        const uint32_t *          mask,
  1757                        int                      width)
  1759     int i;
  1761     for (i = 0; i < width; ++i)
  1763 	uint32_t s = *(src + i);
  1764 	uint32_t m = *(mask + i);
  1765 	uint32_t a;
  1767 	combine_mask_alpha_ca (&s, &m);
  1769 	a = m;
  1770 	if (a != ~0)
  1772 	    uint32_t d = 0;
  1774 	    if (a)
  1776 		d = *(dest + i);
  1777 		UN8x4_MUL_UN8x4 (d, a);
  1780 	    *(dest + i) = d;
  1785 static void
  1786 combine_out_ca (pixman_implementation_t *imp,
  1787                 pixman_op_t              op,
  1788                 uint32_t *                dest,
  1789                 const uint32_t *          src,
  1790                 const uint32_t *          mask,
  1791                 int                      width)
  1793     int i;
  1795     for (i = 0; i < width; ++i)
  1797 	uint32_t d = *(dest + i);
  1798 	uint16_t a = ~d >> A_SHIFT;
  1799 	uint32_t s = 0;
  1801 	if (a)
  1803 	    uint32_t m = *(mask + i);
  1805 	    s = *(src + i);
  1806 	    combine_mask_value_ca (&s, &m);
  1808 	    if (a != MASK)
  1809 		UN8x4_MUL_UN8 (s, a);
  1812 	*(dest + i) = s;
  1816 static void
  1817 combine_out_reverse_ca (pixman_implementation_t *imp,
  1818                         pixman_op_t              op,
  1819                         uint32_t *                dest,
  1820                         const uint32_t *          src,
  1821                         const uint32_t *          mask,
  1822                         int                      width)
  1824     int i;
  1826     for (i = 0; i < width; ++i)
  1828 	uint32_t s = *(src + i);
  1829 	uint32_t m = *(mask + i);
  1830 	uint32_t a;
  1832 	combine_mask_alpha_ca (&s, &m);
  1834 	a = ~m;
  1835 	if (a != ~0)
  1837 	    uint32_t d = 0;
  1839 	    if (a)
  1841 		d = *(dest + i);
  1842 		UN8x4_MUL_UN8x4 (d, a);
  1845 	    *(dest + i) = d;
  1850 static void
  1851 combine_atop_ca (pixman_implementation_t *imp,
  1852                  pixman_op_t              op,
  1853                  uint32_t *                dest,
  1854                  const uint32_t *          src,
  1855                  const uint32_t *          mask,
  1856                  int                      width)
  1858     int i;
  1860     for (i = 0; i < width; ++i)
  1862 	uint32_t d = *(dest + i);
  1863 	uint32_t s = *(src + i);
  1864 	uint32_t m = *(mask + i);
  1865 	uint32_t ad;
  1866 	uint16_t as = d >> A_SHIFT;
  1868 	combine_mask_ca (&s, &m);
  1870 	ad = ~m;
  1872 	UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
  1874 	*(dest + i) = d;
  1878 static void
  1879 combine_atop_reverse_ca (pixman_implementation_t *imp,
  1880                          pixman_op_t              op,
  1881                          uint32_t *                dest,
  1882                          const uint32_t *          src,
  1883                          const uint32_t *          mask,
  1884                          int                      width)
  1886     int i;
  1888     for (i = 0; i < width; ++i)
  1890 	uint32_t d = *(dest + i);
  1891 	uint32_t s = *(src + i);
  1892 	uint32_t m = *(mask + i);
  1893 	uint32_t ad;
  1894 	uint16_t as = ~d >> A_SHIFT;
  1896 	combine_mask_ca (&s, &m);
  1898 	ad = m;
  1900 	UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
  1902 	*(dest + i) = d;
  1906 static void
  1907 combine_xor_ca (pixman_implementation_t *imp,
  1908                 pixman_op_t              op,
  1909                 uint32_t *                dest,
  1910                 const uint32_t *          src,
  1911                 const uint32_t *          mask,
  1912                 int                      width)
  1914     int i;
  1916     for (i = 0; i < width; ++i)
  1918 	uint32_t d = *(dest + i);
  1919 	uint32_t s = *(src + i);
  1920 	uint32_t m = *(mask + i);
  1921 	uint32_t ad;
  1922 	uint16_t as = ~d >> A_SHIFT;
  1924 	combine_mask_ca (&s, &m);
  1926 	ad = ~m;
  1928 	UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
  1930 	*(dest + i) = d;
  1934 static void
  1935 combine_add_ca (pixman_implementation_t *imp,
  1936                 pixman_op_t              op,
  1937                 uint32_t *                dest,
  1938                 const uint32_t *          src,
  1939                 const uint32_t *          mask,
  1940                 int                      width)
  1942     int i;
  1944     for (i = 0; i < width; ++i)
  1946 	uint32_t s = *(src + i);
  1947 	uint32_t m = *(mask + i);
  1948 	uint32_t d = *(dest + i);
  1950 	combine_mask_value_ca (&s, &m);
  1952 	UN8x4_ADD_UN8x4 (d, s);
  1954 	*(dest + i) = d;
  1958 static void
  1959 combine_saturate_ca (pixman_implementation_t *imp,
  1960                      pixman_op_t              op,
  1961                      uint32_t *                dest,
  1962                      const uint32_t *          src,
  1963                      const uint32_t *          mask,
  1964                      int                      width)
  1966     int i;
  1968     for (i = 0; i < width; ++i)
  1970 	uint32_t s, d;
  1971 	uint16_t sa, sr, sg, sb, da;
  1972 	uint16_t t, u, v;
  1973 	uint32_t m, n, o, p;
  1975 	d = *(dest + i);
  1976 	s = *(src + i);
  1977 	m = *(mask + i);
  1979 	combine_mask_ca (&s, &m);
  1981 	sa = (m >> A_SHIFT);
  1982 	sr = (m >> R_SHIFT) & MASK;
  1983 	sg = (m >> G_SHIFT) & MASK;
  1984 	sb =  m             & MASK;
  1985 	da = ~d >> A_SHIFT;
  1987 	if (sb <= da)
  1988 	    m = ADD (s, d, 0, t);
  1989 	else
  1990 	    m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
  1992 	if (sg <= da)
  1993 	    n = ADD (s, d, G_SHIFT, t);
  1994 	else
  1995 	    n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
  1997 	if (sr <= da)
  1998 	    o = ADD (s, d, R_SHIFT, t);
  1999 	else
  2000 	    o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
  2002 	if (sa <= da)
  2003 	    p = ADD (s, d, A_SHIFT, t);
  2004 	else
  2005 	    p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
  2007 	*(dest + i) = m | n | o | p;
  2011 static void
  2012 combine_disjoint_general_ca (uint32_t *      dest,
  2013                              const uint32_t *src,
  2014                              const uint32_t *mask,
  2015                              int            width,
  2016                              uint8_t        combine)
  2018     int i;
  2020     for (i = 0; i < width; ++i)
  2022 	uint32_t s, d;
  2023 	uint32_t m, n, o, p;
  2024 	uint32_t Fa, Fb;
  2025 	uint16_t t, u, v;
  2026 	uint32_t sa;
  2027 	uint8_t da;
  2029 	s = *(src + i);
  2030 	m = *(mask + i);
  2031 	d = *(dest + i);
  2032 	da = d >> A_SHIFT;
  2034 	combine_mask_ca (&s, &m);
  2036 	sa = m;
  2038 	switch (combine & COMBINE_A)
  2040 	default:
  2041 	    Fa = 0;
  2042 	    break;
  2044 	case COMBINE_A_OUT:
  2045 	    m = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> 0), da);
  2046 	    n = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2047 	    o = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2048 	    p = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2049 	    Fa = m | n | o | p;
  2050 	    break;
  2052 	case COMBINE_A_IN:
  2053 	    m = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> 0), da);
  2054 	    n = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2055 	    o = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2056 	    p = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2057 	    Fa = m | n | o | p;
  2058 	    break;
  2060 	case COMBINE_A:
  2061 	    Fa = ~0;
  2062 	    break;
  2065 	switch (combine & COMBINE_B)
  2067 	default:
  2068 	    Fb = 0;
  2069 	    break;
  2071 	case COMBINE_B_OUT:
  2072 	    m = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> 0));
  2073 	    n = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
  2074 	    o = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
  2075 	    p = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
  2076 	    Fb = m | n | o | p;
  2077 	    break;
  2079 	case COMBINE_B_IN:
  2080 	    m = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> 0));
  2081 	    n = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
  2082 	    o = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
  2083 	    p = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
  2084 	    Fb = m | n | o | p;
  2085 	    break;
  2087 	case COMBINE_B:
  2088 	    Fb = ~0;
  2089 	    break;
  2091 	m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
  2092 	n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
  2093 	o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
  2094 	p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
  2096 	s = m | n | o | p;
  2098 	*(dest + i) = s;
  2102 static void
  2103 combine_disjoint_over_ca (pixman_implementation_t *imp,
  2104                           pixman_op_t              op,
  2105                           uint32_t *                dest,
  2106                           const uint32_t *          src,
  2107                           const uint32_t *          mask,
  2108                           int                      width)
  2110     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
  2113 static void
  2114 combine_disjoint_in_ca (pixman_implementation_t *imp,
  2115                         pixman_op_t              op,
  2116                         uint32_t *                dest,
  2117                         const uint32_t *          src,
  2118                         const uint32_t *          mask,
  2119                         int                      width)
  2121     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
  2124 static void
  2125 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp,
  2126                                 pixman_op_t              op,
  2127                                 uint32_t *                dest,
  2128                                 const uint32_t *          src,
  2129                                 const uint32_t *          mask,
  2130                                 int                      width)
  2132     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
  2135 static void
  2136 combine_disjoint_out_ca (pixman_implementation_t *imp,
  2137                          pixman_op_t              op,
  2138                          uint32_t *                dest,
  2139                          const uint32_t *          src,
  2140                          const uint32_t *          mask,
  2141                          int                      width)
  2143     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
  2146 static void
  2147 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp,
  2148                                  pixman_op_t              op,
  2149                                  uint32_t *                dest,
  2150                                  const uint32_t *          src,
  2151                                  const uint32_t *          mask,
  2152                                  int                      width)
  2154     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
  2157 static void
  2158 combine_disjoint_atop_ca (pixman_implementation_t *imp,
  2159                           pixman_op_t              op,
  2160                           uint32_t *                dest,
  2161                           const uint32_t *          src,
  2162                           const uint32_t *          mask,
  2163                           int                      width)
  2165     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
  2168 static void
  2169 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp,
  2170                                   pixman_op_t              op,
  2171                                   uint32_t *                dest,
  2172                                   const uint32_t *          src,
  2173                                   const uint32_t *          mask,
  2174                                   int                      width)
  2176     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
  2179 static void
  2180 combine_disjoint_xor_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)
  2187     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
  2190 static void
  2191 combine_conjoint_general_ca (uint32_t *      dest,
  2192                              const uint32_t *src,
  2193                              const uint32_t *mask,
  2194                              int            width,
  2195                              uint8_t        combine)
  2197     int i;
  2199     for (i = 0; i < width; ++i)
  2201 	uint32_t s, d;
  2202 	uint32_t m, n, o, p;
  2203 	uint32_t Fa, Fb;
  2204 	uint16_t t, u, v;
  2205 	uint32_t sa;
  2206 	uint8_t da;
  2208 	s = *(src + i);
  2209 	m = *(mask + i);
  2210 	d = *(dest + i);
  2211 	da = d >> A_SHIFT;
  2213 	combine_mask_ca (&s, &m);
  2215 	sa = m;
  2217 	switch (combine & COMBINE_A)
  2219 	default:
  2220 	    Fa = 0;
  2221 	    break;
  2223 	case COMBINE_A_OUT:
  2224 	    m = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> 0), da);
  2225 	    n = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2226 	    o = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2227 	    p = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2228 	    Fa = m | n | o | p;
  2229 	    break;
  2231 	case COMBINE_A_IN:
  2232 	    m = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> 0), da);
  2233 	    n = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2234 	    o = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2235 	    p = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2236 	    Fa = m | n | o | p;
  2237 	    break;
  2239 	case COMBINE_A:
  2240 	    Fa = ~0;
  2241 	    break;
  2244 	switch (combine & COMBINE_B)
  2246 	default:
  2247 	    Fb = 0;
  2248 	    break;
  2250 	case COMBINE_B_OUT:
  2251 	    m = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> 0));
  2252 	    n = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
  2253 	    o = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
  2254 	    p = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
  2255 	    Fb = m | n | o | p;
  2256 	    break;
  2258 	case COMBINE_B_IN:
  2259 	    m = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> 0));
  2260 	    n = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
  2261 	    o = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
  2262 	    p = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
  2263 	    Fb = m | n | o | p;
  2264 	    break;
  2266 	case COMBINE_B:
  2267 	    Fb = ~0;
  2268 	    break;
  2270 	m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
  2271 	n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
  2272 	o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
  2273 	p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
  2275 	s = m | n | o | p;
  2277 	*(dest + i) = s;
  2281 static void
  2282 combine_conjoint_over_ca (pixman_implementation_t *imp,
  2283                           pixman_op_t              op,
  2284                           uint32_t *                dest,
  2285                           const uint32_t *          src,
  2286                           const uint32_t *          mask,
  2287                           int                      width)
  2289     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
  2292 static void
  2293 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp,
  2294                                   pixman_op_t              op,
  2295                                   uint32_t *                dest,
  2296                                   const uint32_t *          src,
  2297                                   const uint32_t *          mask,
  2298                                   int                      width)
  2300     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
  2303 static void
  2304 combine_conjoint_in_ca (pixman_implementation_t *imp,
  2305                         pixman_op_t              op,
  2306                         uint32_t *                dest,
  2307                         const uint32_t *          src,
  2308                         const uint32_t *          mask,
  2309                         int                      width)
  2311     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
  2314 static void
  2315 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp,
  2316                                 pixman_op_t              op,
  2317                                 uint32_t *                dest,
  2318                                 const uint32_t *          src,
  2319                                 const uint32_t *          mask,
  2320                                 int                      width)
  2322     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
  2325 static void
  2326 combine_conjoint_out_ca (pixman_implementation_t *imp,
  2327                          pixman_op_t              op,
  2328                          uint32_t *                dest,
  2329                          const uint32_t *          src,
  2330                          const uint32_t *          mask,
  2331                          int                      width)
  2333     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
  2336 static void
  2337 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp,
  2338                                  pixman_op_t              op,
  2339                                  uint32_t *                dest,
  2340                                  const uint32_t *          src,
  2341                                  const uint32_t *          mask,
  2342                                  int                      width)
  2344     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
  2347 static void
  2348 combine_conjoint_atop_ca (pixman_implementation_t *imp,
  2349                           pixman_op_t              op,
  2350                           uint32_t *                dest,
  2351                           const uint32_t *          src,
  2352                           const uint32_t *          mask,
  2353                           int                      width)
  2355     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
  2358 static void
  2359 combine_conjoint_atop_reverse_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)
  2366     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
  2369 static void
  2370 combine_conjoint_xor_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)
  2377     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
  2380 void
  2381 _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp)
  2383     /* Unified alpha */
  2384     imp->combine_32[PIXMAN_OP_CLEAR] = combine_clear;
  2385     imp->combine_32[PIXMAN_OP_SRC] = combine_src_u;
  2386     imp->combine_32[PIXMAN_OP_DST] = combine_dst;
  2387     imp->combine_32[PIXMAN_OP_OVER] = combine_over_u;
  2388     imp->combine_32[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u;
  2389     imp->combine_32[PIXMAN_OP_IN] = combine_in_u;
  2390     imp->combine_32[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u;
  2391     imp->combine_32[PIXMAN_OP_OUT] = combine_out_u;
  2392     imp->combine_32[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u;
  2393     imp->combine_32[PIXMAN_OP_ATOP] = combine_atop_u;
  2394     imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u;
  2395     imp->combine_32[PIXMAN_OP_XOR] = combine_xor_u;
  2396     imp->combine_32[PIXMAN_OP_ADD] = combine_add_u;
  2397     imp->combine_32[PIXMAN_OP_SATURATE] = combine_saturate_u;
  2399     /* Disjoint, unified */
  2400     imp->combine_32[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear;
  2401     imp->combine_32[PIXMAN_OP_DISJOINT_SRC] = combine_src_u;
  2402     imp->combine_32[PIXMAN_OP_DISJOINT_DST] = combine_dst;
  2403     imp->combine_32[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u;
  2404     imp->combine_32[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u;
  2405     imp->combine_32[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u;
  2406     imp->combine_32[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u;
  2407     imp->combine_32[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u;
  2408     imp->combine_32[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u;
  2409     imp->combine_32[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u;
  2410     imp->combine_32[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u;
  2411     imp->combine_32[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u;
  2413     /* Conjoint, unified */
  2414     imp->combine_32[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear;
  2415     imp->combine_32[PIXMAN_OP_CONJOINT_SRC] = combine_src_u;
  2416     imp->combine_32[PIXMAN_OP_CONJOINT_DST] = combine_dst;
  2417     imp->combine_32[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u;
  2418     imp->combine_32[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u;
  2419     imp->combine_32[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u;
  2420     imp->combine_32[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u;
  2421     imp->combine_32[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u;
  2422     imp->combine_32[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u;
  2423     imp->combine_32[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u;
  2424     imp->combine_32[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u;
  2425     imp->combine_32[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u;
  2427     imp->combine_32[PIXMAN_OP_MULTIPLY] = combine_multiply_u;
  2428     imp->combine_32[PIXMAN_OP_SCREEN] = combine_screen_u;
  2429     imp->combine_32[PIXMAN_OP_OVERLAY] = combine_overlay_u;
  2430     imp->combine_32[PIXMAN_OP_DARKEN] = combine_darken_u;
  2431     imp->combine_32[PIXMAN_OP_LIGHTEN] = combine_lighten_u;
  2432     imp->combine_32[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u;
  2433     imp->combine_32[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u;
  2434     imp->combine_32[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u;
  2435     imp->combine_32[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u;
  2436     imp->combine_32[PIXMAN_OP_DIFFERENCE] = combine_difference_u;
  2437     imp->combine_32[PIXMAN_OP_EXCLUSION] = combine_exclusion_u;
  2438     imp->combine_32[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u;
  2439     imp->combine_32[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u;
  2440     imp->combine_32[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u;
  2441     imp->combine_32[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u;
  2443     /* Component alpha combiners */
  2444     imp->combine_32_ca[PIXMAN_OP_CLEAR] = combine_clear_ca;
  2445     imp->combine_32_ca[PIXMAN_OP_SRC] = combine_src_ca;
  2446     /* dest */
  2447     imp->combine_32_ca[PIXMAN_OP_OVER] = combine_over_ca;
  2448     imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca;
  2449     imp->combine_32_ca[PIXMAN_OP_IN] = combine_in_ca;
  2450     imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca;
  2451     imp->combine_32_ca[PIXMAN_OP_OUT] = combine_out_ca;
  2452     imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca;
  2453     imp->combine_32_ca[PIXMAN_OP_ATOP] = combine_atop_ca;
  2454     imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca;
  2455     imp->combine_32_ca[PIXMAN_OP_XOR] = combine_xor_ca;
  2456     imp->combine_32_ca[PIXMAN_OP_ADD] = combine_add_ca;
  2457     imp->combine_32_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca;
  2459     /* Disjoint CA */
  2460     imp->combine_32_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca;
  2461     imp->combine_32_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca;
  2462     imp->combine_32_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst;
  2463     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca;
  2464     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca;
  2465     imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca;
  2466     imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca;
  2467     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca;
  2468     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca;
  2469     imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca;
  2470     imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca;
  2471     imp->combine_32_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca;
  2473     /* Conjoint CA */
  2474     imp->combine_32_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca;
  2475     imp->combine_32_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca;
  2476     imp->combine_32_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst;
  2477     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca;
  2478     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca;
  2479     imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca;
  2480     imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca;
  2481     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca;
  2482     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca;
  2483     imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca;
  2484     imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca;
  2485     imp->combine_32_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca;
  2487     imp->combine_32_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca;
  2488     imp->combine_32_ca[PIXMAN_OP_SCREEN] = combine_screen_ca;
  2489     imp->combine_32_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca;
  2490     imp->combine_32_ca[PIXMAN_OP_DARKEN] = combine_darken_ca;
  2491     imp->combine_32_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca;
  2492     imp->combine_32_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca;
  2493     imp->combine_32_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca;
  2494     imp->combine_32_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca;
  2495     imp->combine_32_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca;
  2496     imp->combine_32_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca;
  2497     imp->combine_32_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca;
  2499     /* It is not clear that these make sense, so make them noops for now */
  2500     imp->combine_32_ca[PIXMAN_OP_HSL_HUE] = combine_dst;
  2501     imp->combine_32_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst;
  2502     imp->combine_32_ca[PIXMAN_OP_HSL_COLOR] = combine_dst;
  2503     imp->combine_32_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst;

mercurial