LCOV - code coverage report
Current view: top level - gfx/cairo/libpixman/src - pixman-combine32.c (source / functions) Hit Total Coverage
Test: output.info Lines: 107 904 11.8 %
Date: 2017-07-14 16:53:18 Functions: 1 115 0.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
       3             :  *             2005 Lars Knoll & Zack Rusin, Trolltech
       4             :  *
       5             :  * Permission to use, copy, modify, distribute, and sell this software and its
       6             :  * documentation for any purpose is hereby granted without fee, provided that
       7             :  * the above copyright notice appear in all copies and that both that
       8             :  * copyright notice and this permission notice appear in supporting
       9             :  * documentation, and that the name of Keith Packard not be used in
      10             :  * advertising or publicity pertaining to distribution of the software without
      11             :  * specific, written prior permission.  Keith Packard makes no
      12             :  * representations about the suitability of this software for any purpose.  It
      13             :  * is provided "as is" without express or implied warranty.
      14             :  *
      15             :  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
      16             :  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
      17             :  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      19             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      20             :  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
      21             :  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
      22             :  * SOFTWARE.
      23             :  */
      24             : #ifdef HAVE_CONFIG_H
      25             : #include <config.h>
      26             : #endif
      27             : 
      28             : #include <math.h>
      29             : #include <string.h>
      30             : 
      31             : #include "pixman-private.h"
      32             : #include "pixman-combine32.h"
      33             : 
      34             : /* component alpha helper functions */
      35             : 
      36             : static void
      37           0 : combine_mask_ca (uint32_t *src, uint32_t *mask)
      38             : {
      39           0 :     uint32_t a = *mask;
      40             : 
      41             :     uint32_t x;
      42             :     uint16_t xa;
      43             : 
      44           0 :     if (!a)
      45             :     {
      46           0 :         *(src) = 0;
      47           0 :         return;
      48             :     }
      49             : 
      50           0 :     x = *(src);
      51           0 :     if (a == ~0)
      52             :     {
      53           0 :         x = x >> A_SHIFT;
      54           0 :         x |= x << G_SHIFT;
      55           0 :         x |= x << R_SHIFT;
      56           0 :         *(mask) = x;
      57           0 :         return;
      58             :     }
      59             : 
      60           0 :     xa = x >> A_SHIFT;
      61           0 :     UN8x4_MUL_UN8x4 (x, a);
      62           0 :     *(src) = x;
      63             :     
      64           0 :     UN8x4_MUL_UN8 (a, xa);
      65           0 :     *(mask) = a;
      66             : }
      67             : 
      68             : static void
      69           0 : combine_mask_value_ca (uint32_t *src, const uint32_t *mask)
      70             : {
      71           0 :     uint32_t a = *mask;
      72             :     uint32_t x;
      73             : 
      74           0 :     if (!a)
      75             :     {
      76           0 :         *(src) = 0;
      77           0 :         return;
      78             :     }
      79             : 
      80           0 :     if (a == ~0)
      81           0 :         return;
      82             : 
      83           0 :     x = *(src);
      84           0 :     UN8x4_MUL_UN8x4 (x, a);
      85           0 :     *(src) = x;
      86             : }
      87             : 
      88             : static void
      89           0 : combine_mask_alpha_ca (const uint32_t *src, uint32_t *mask)
      90             : {
      91           0 :     uint32_t a = *(mask);
      92             :     uint32_t x;
      93             : 
      94           0 :     if (!a)
      95           0 :         return;
      96             : 
      97           0 :     x = *(src) >> A_SHIFT;
      98           0 :     if (x == MASK)
      99           0 :         return;
     100             : 
     101           0 :     if (a == ~0)
     102             :     {
     103           0 :         x |= x << G_SHIFT;
     104           0 :         x |= x << R_SHIFT;
     105           0 :         *(mask) = x;
     106           0 :         return;
     107             :     }
     108             : 
     109           0 :     UN8x4_MUL_UN8 (a, x);
     110           0 :     *(mask) = a;
     111             : }
     112             : 
     113             : /*
     114             :  * There are two ways of handling alpha -- either as a single unified value or
     115             :  * a separate value for each component, hence each macro must have two
     116             :  * versions.  The unified alpha version has a 'u' at the end of the name,
     117             :  * the component version has a 'ca'.  Similarly, functions which deal with
     118             :  * this difference will have two versions using the same convention.
     119             :  */
     120             : 
     121             : static force_inline uint32_t
     122             : combine_mask (const uint32_t *src, const uint32_t *mask, int i)
     123             : {
     124             :     uint32_t s, m;
     125             : 
     126           0 :     if (mask)
     127             :     {
     128           0 :         m = *(mask + i) >> A_SHIFT;
     129             : 
     130           0 :         if (!m)
     131           0 :             return 0;
     132             :     }
     133             : 
     134           0 :     s = *(src + i);
     135             : 
     136           0 :     if (mask)
     137           0 :         UN8x4_MUL_UN8 (s, m);
     138             : 
     139           0 :     return s;
     140             : }
     141             : 
     142             : static void
     143           0 : 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           0 :     memset (dest, 0, width * sizeof(uint32_t));
     151           0 : }
     152             : 
     153             : static void
     154           0 : 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           0 :     return;
     162             : }
     163             : 
     164             : static void
     165           0 : combine_src_u (pixman_implementation_t *imp,
     166             :                pixman_op_t              op,
     167             :                uint32_t *                dest,
     168             :                const uint32_t *          src,
     169             :                const uint32_t *          mask,
     170             :                int                      width)
     171             : {
     172             :     int i;
     173             : 
     174           0 :     if (!mask)
     175             :     {
     176           0 :         memcpy (dest, src, width * sizeof (uint32_t));
     177             :     }
     178             :     else
     179             :     {
     180           0 :         for (i = 0; i < width; ++i)
     181             :         {
     182           0 :             uint32_t s = combine_mask (src, mask, i);
     183             : 
     184           0 :             *(dest + i) = s;
     185             :         }
     186             :     }
     187           0 : }
     188             : 
     189             : static void
     190           0 : combine_over_u (pixman_implementation_t *imp,
     191             :                 pixman_op_t              op,
     192             :                 uint32_t *                dest,
     193             :                 const uint32_t *          src,
     194             :                 const uint32_t *          mask,
     195             :                 int                      width)
     196             : {
     197             :     int i;
     198             : 
     199           0 :     if (!mask)
     200             :     {
     201           0 :         for (i = 0; i < width; ++i)
     202             :         {
     203           0 :             uint32_t s = *(src + i);
     204           0 :             uint32_t a = ALPHA_8 (s);
     205           0 :             if (a == 0xFF)
     206             :             {
     207           0 :                 *(dest + i) = s;
     208             :             }
     209           0 :             else if (s)
     210             :             {
     211           0 :                 uint32_t d = *(dest + i);
     212           0 :                 uint32_t ia = a ^ 0xFF;
     213           0 :                 UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
     214           0 :                 *(dest + i) = d;
     215             :             }
     216             :         }
     217             :     }
     218             :     else
     219             :     {
     220           0 :         for (i = 0; i < width; ++i)
     221             :         {
     222           0 :             uint32_t m = ALPHA_8 (*(mask + i));
     223           0 :             if (m == 0xFF)
     224             :             {
     225           0 :                 uint32_t s = *(src + i);
     226           0 :                 uint32_t a = ALPHA_8 (s);
     227           0 :                 if (a == 0xFF)
     228             :                 {
     229           0 :                     *(dest + i) = s;
     230             :                 }
     231           0 :                 else if (s)
     232             :                 {
     233           0 :                     uint32_t d = *(dest + i);
     234           0 :                     uint32_t ia = a ^ 0xFF;
     235           0 :                     UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s);
     236           0 :                     *(dest + i) = d;
     237             :                 }
     238             :             }
     239           0 :             else if (m)
     240             :             {
     241           0 :                 uint32_t s = *(src + i);
     242           0 :                 if (s)
     243             :                 {
     244           0 :                     uint32_t d = *(dest + i);
     245           0 :                     UN8x4_MUL_UN8 (s, m);
     246           0 :                     UN8x4_MUL_UN8_ADD_UN8x4 (d, ALPHA_8 (~s), s);
     247           0 :                     *(dest + i) = d;
     248             :                 }
     249             :             }
     250             :         }
     251             :     }
     252           0 : }
     253             : 
     254             : static void
     255           0 : combine_over_reverse_u (pixman_implementation_t *imp,
     256             :                         pixman_op_t              op,
     257             :                         uint32_t *                dest,
     258             :                         const uint32_t *          src,
     259             :                         const uint32_t *          mask,
     260             :                         int                      width)
     261             : {
     262             :     int i;
     263             : 
     264           0 :     for (i = 0; i < width; ++i)
     265             :     {
     266           0 :         uint32_t s = combine_mask (src, mask, i);
     267           0 :         uint32_t d = *(dest + i);
     268           0 :         uint32_t ia = ALPHA_8 (~*(dest + i));
     269           0 :         UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d);
     270           0 :         *(dest + i) = s;
     271             :     }
     272           0 : }
     273             : 
     274             : static void
     275           0 : combine_in_u (pixman_implementation_t *imp,
     276             :               pixman_op_t              op,
     277             :               uint32_t *                dest,
     278             :               const uint32_t *          src,
     279             :               const uint32_t *          mask,
     280             :               int                      width)
     281             : {
     282             :     int i;
     283             : 
     284           0 :     for (i = 0; i < width; ++i)
     285             :     {
     286           0 :         uint32_t s = combine_mask (src, mask, i);
     287           0 :         uint32_t a = ALPHA_8 (*(dest + i));
     288           0 :         UN8x4_MUL_UN8 (s, a);
     289           0 :         *(dest + i) = s;
     290             :     }
     291           0 : }
     292             : 
     293             : static void
     294           0 : combine_in_reverse_u (pixman_implementation_t *imp,
     295             :                       pixman_op_t              op,
     296             :                       uint32_t *                dest,
     297             :                       const uint32_t *          src,
     298             :                       const uint32_t *          mask,
     299             :                       int                      width)
     300             : {
     301             :     int i;
     302             : 
     303           0 :     for (i = 0; i < width; ++i)
     304             :     {
     305           0 :         uint32_t s = combine_mask (src, mask, i);
     306           0 :         uint32_t d = *(dest + i);
     307           0 :         uint32_t a = ALPHA_8 (s);
     308           0 :         UN8x4_MUL_UN8 (d, a);
     309           0 :         *(dest + i) = d;
     310             :     }
     311           0 : }
     312             : 
     313             : static void
     314           0 : combine_out_u (pixman_implementation_t *imp,
     315             :                pixman_op_t              op,
     316             :                uint32_t *                dest,
     317             :                const uint32_t *          src,
     318             :                const uint32_t *          mask,
     319             :                int                      width)
     320             : {
     321             :     int i;
     322             : 
     323           0 :     for (i = 0; i < width; ++i)
     324             :     {
     325           0 :         uint32_t s = combine_mask (src, mask, i);
     326           0 :         uint32_t a = ALPHA_8 (~*(dest + i));
     327           0 :         UN8x4_MUL_UN8 (s, a);
     328           0 :         *(dest + i) = s;
     329             :     }
     330           0 : }
     331             : 
     332             : static void
     333           0 : combine_out_reverse_u (pixman_implementation_t *imp,
     334             :                        pixman_op_t              op,
     335             :                        uint32_t *                dest,
     336             :                        const uint32_t *          src,
     337             :                        const uint32_t *          mask,
     338             :                        int                      width)
     339             : {
     340             :     int i;
     341             : 
     342           0 :     for (i = 0; i < width; ++i)
     343             :     {
     344           0 :         uint32_t s = combine_mask (src, mask, i);
     345           0 :         uint32_t d = *(dest + i);
     346           0 :         uint32_t a = ALPHA_8 (~s);
     347           0 :         UN8x4_MUL_UN8 (d, a);
     348           0 :         *(dest + i) = d;
     349             :     }
     350           0 : }
     351             : 
     352             : static void
     353           0 : combine_atop_u (pixman_implementation_t *imp,
     354             :                 pixman_op_t              op,
     355             :                 uint32_t *                dest,
     356             :                 const uint32_t *          src,
     357             :                 const uint32_t *          mask,
     358             :                 int                      width)
     359             : {
     360             :     int i;
     361             : 
     362           0 :     for (i = 0; i < width; ++i)
     363             :     {
     364           0 :         uint32_t s = combine_mask (src, mask, i);
     365           0 :         uint32_t d = *(dest + i);
     366           0 :         uint32_t dest_a = ALPHA_8 (d);
     367           0 :         uint32_t src_ia = ALPHA_8 (~s);
     368             : 
     369           0 :         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia);
     370           0 :         *(dest + i) = s;
     371             :     }
     372           0 : }
     373             : 
     374             : static void
     375           0 : combine_atop_reverse_u (pixman_implementation_t *imp,
     376             :                         pixman_op_t              op,
     377             :                         uint32_t *                dest,
     378             :                         const uint32_t *          src,
     379             :                         const uint32_t *          mask,
     380             :                         int                      width)
     381             : {
     382             :     int i;
     383             : 
     384           0 :     for (i = 0; i < width; ++i)
     385             :     {
     386           0 :         uint32_t s = combine_mask (src, mask, i);
     387           0 :         uint32_t d = *(dest + i);
     388           0 :         uint32_t src_a = ALPHA_8 (s);
     389           0 :         uint32_t dest_ia = ALPHA_8 (~d);
     390             : 
     391           0 :         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a);
     392           0 :         *(dest + i) = s;
     393             :     }
     394           0 : }
     395             : 
     396             : static void
     397           0 : combine_xor_u (pixman_implementation_t *imp,
     398             :                pixman_op_t              op,
     399             :                uint32_t *                dest,
     400             :                const uint32_t *          src,
     401             :                const uint32_t *          mask,
     402             :                int                      width)
     403             : {
     404             :     int i;
     405             : 
     406           0 :     for (i = 0; i < width; ++i)
     407             :     {
     408           0 :         uint32_t s = combine_mask (src, mask, i);
     409           0 :         uint32_t d = *(dest + i);
     410           0 :         uint32_t src_ia = ALPHA_8 (~s);
     411           0 :         uint32_t dest_ia = ALPHA_8 (~d);
     412             : 
     413           0 :         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia);
     414           0 :         *(dest + i) = s;
     415             :     }
     416           0 : }
     417             : 
     418             : static void
     419           0 : combine_add_u (pixman_implementation_t *imp,
     420             :                pixman_op_t              op,
     421             :                uint32_t *                dest,
     422             :                const uint32_t *          src,
     423             :                const uint32_t *          mask,
     424             :                int                      width)
     425             : {
     426             :     int i;
     427             : 
     428           0 :     for (i = 0; i < width; ++i)
     429             :     {
     430           0 :         uint32_t s = combine_mask (src, mask, i);
     431           0 :         uint32_t d = *(dest + i);
     432           0 :         UN8x4_ADD_UN8x4 (d, s);
     433           0 :         *(dest + i) = d;
     434             :     }
     435           0 : }
     436             : 
     437             : static void
     438           0 : combine_saturate_u (pixman_implementation_t *imp,
     439             :                     pixman_op_t              op,
     440             :                     uint32_t *                dest,
     441             :                     const uint32_t *          src,
     442             :                     const uint32_t *          mask,
     443             :                     int                      width)
     444             : {
     445             :     int i;
     446             : 
     447           0 :     for (i = 0; i < width; ++i)
     448             :     {
     449           0 :         uint32_t s = combine_mask (src, mask, i);
     450           0 :         uint32_t d = *(dest + i);
     451             :         uint16_t sa, da;
     452             : 
     453           0 :         sa = s >> A_SHIFT;
     454           0 :         da = ~d >> A_SHIFT;
     455           0 :         if (sa > da)
     456             :         {
     457           0 :             sa = DIV_UN8 (da, sa);
     458           0 :             UN8x4_MUL_UN8 (s, sa);
     459             :         }
     460             :         ;
     461           0 :         UN8x4_ADD_UN8x4 (d, s);
     462           0 :         *(dest + i) = d;
     463             :     }
     464           0 : }
     465             : 
     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             :  */
     488             : 
     489             : /*
     490             :  * Multiply
     491             :  * B(Dca, ad, Sca, as) = Dca.Sca
     492             :  */
     493             : static void
     494           0 : 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;
     502             : 
     503           0 :     for (i = 0; i < width; ++i)
     504             :     {
     505           0 :         uint32_t s = combine_mask (src, mask, i);
     506           0 :         uint32_t d = *(dest + i);
     507           0 :         uint32_t ss = s;
     508           0 :         uint32_t src_ia = ALPHA_8 (~s);
     509           0 :         uint32_t dest_ia = ALPHA_8 (~d);
     510             : 
     511           0 :         UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (ss, dest_ia, d, src_ia);
     512           0 :         UN8x4_MUL_UN8x4 (d, s);
     513           0 :         UN8x4_ADD_UN8x4 (d, ss);
     514             : 
     515           0 :         *(dest + i) = d;
     516             :     }
     517           0 : }
     518             : 
     519             : static void
     520           0 : 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;
     528             : 
     529           0 :     for (i = 0; i < width; ++i)
     530             :     {
     531           0 :         uint32_t m = *(mask + i);
     532           0 :         uint32_t s = *(src + i);
     533           0 :         uint32_t d = *(dest + i);
     534           0 :         uint32_t r = d;
     535           0 :         uint32_t dest_ia = ALPHA_8 (~d);
     536             : 
     537           0 :         combine_mask_ca (&s, &m);
     538             : 
     539           0 :         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (r, ~m, s, dest_ia);
     540           0 :         UN8x4_MUL_UN8x4 (d, s);
     541           0 :         UN8x4_ADD_UN8x4 (r, d);
     542             : 
     543           0 :         *(dest + i) = r;
     544             :     }
     545           0 : }
     546             : 
     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             :     }
     608             : 
     609             : /*
     610             :  * Screen
     611             :  * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca
     612             :  */
     613             : static inline uint32_t
     614           0 : blend_screen (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     615             : {
     616           0 :     return DIV_ONE_UN8 (sca * da + dca * sa - sca * dca);
     617             : }
     618             : 
     619           0 : PDF_SEPARABLE_BLEND_MODE (screen)
     620             : 
     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           0 : blend_overlay (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     631             : {
     632             :     uint32_t rca;
     633             : 
     634           0 :     if (2 * dca < da)
     635           0 :         rca = 2 * sca * dca;
     636             :     else
     637           0 :         rca = sa * da - 2 * (da - dca) * (sa - sca);
     638           0 :     return DIV_ONE_UN8 (rca);
     639             : }
     640             : 
     641           0 : PDF_SEPARABLE_BLEND_MODE (overlay)
     642             : 
     643             : /*
     644             :  * Darken
     645             :  * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa)
     646             :  */
     647             : static inline uint32_t
     648           0 : blend_darken (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     649             : {
     650             :     uint32_t s, d;
     651             : 
     652           0 :     s = sca * da;
     653           0 :     d = dca * sa;
     654           0 :     return DIV_ONE_UN8 (s > d ? d : s);
     655             : }
     656             : 
     657           0 : PDF_SEPARABLE_BLEND_MODE (darken)
     658             : 
     659             : /*
     660             :  * Lighten
     661             :  * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa)
     662             :  */
     663             : static inline uint32_t
     664           0 : blend_lighten (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     665             : {
     666             :     uint32_t s, d;
     667             : 
     668           0 :     s = sca * da;
     669           0 :     d = dca * sa;
     670           0 :     return DIV_ONE_UN8 (s > d ? s : d);
     671             : }
     672             : 
     673           0 : PDF_SEPARABLE_BLEND_MODE (lighten)
     674             : 
     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           0 : blend_color_dodge (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     687             : {
     688           0 :     if (sca >= sa)
     689             :     {
     690           0 :         return dca == 0 ? 0 : DIV_ONE_UN8 (sa * da);
     691             :     }
     692             :     else
     693             :     {
     694           0 :         uint32_t rca = dca * sa / (sa - sca);
     695           0 :         return DIV_ONE_UN8 (sa * MIN (rca, da));
     696             :     }
     697             : }
     698             : 
     699           0 : PDF_SEPARABLE_BLEND_MODE (color_dodge)
     700             : 
     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           0 : blend_color_burn (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     713             : {
     714           0 :     if (sca == 0)
     715             :     {
     716           0 :         return dca < da ? 0 : DIV_ONE_UN8 (sa * da);
     717             :     }
     718             :     else
     719             :     {
     720           0 :         uint32_t rca = (da - dca) * sa / sca;
     721           0 :         return DIV_ONE_UN8 (sa * (MAX (rca, da) - rca));
     722             :     }
     723             : }
     724             : 
     725           0 : PDF_SEPARABLE_BLEND_MODE (color_burn)
     726             : 
     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           0 : blend_hard_light (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     737             : {
     738           0 :     if (2 * sca < sa)
     739           0 :         return DIV_ONE_UN8 (2 * sca * dca);
     740             :     else
     741           0 :         return DIV_ONE_UN8 (sa * da - 2 * (da - dca) * (sa - sca));
     742             : }
     743             : 
     744           0 : PDF_SEPARABLE_BLEND_MODE (hard_light)
     745             : 
     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           0 : blend_soft_light (uint32_t dca_org,
     758             :                   uint32_t da_org,
     759             :                   uint32_t sca_org,
     760             :                   uint32_t sa_org)
     761             : {
     762           0 :     double dca = dca_org * (1.0 / MASK);
     763           0 :     double da = da_org * (1.0 / MASK);
     764           0 :     double sca = sca_org * (1.0 / MASK);
     765           0 :     double sa = sa_org * (1.0 / MASK);
     766             :     double rca;
     767             : 
     768           0 :     if (2 * sca < sa)
     769             :     {
     770           0 :         if (da == 0)
     771           0 :             rca = dca * sa;
     772             :         else
     773           0 :             rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da;
     774             :     }
     775           0 :     else if (da == 0)
     776             :     {
     777           0 :         rca = 0;
     778             :     }
     779           0 :     else if (4 * dca <= da)
     780             :     {
     781           0 :         rca = dca * sa +
     782           0 :             (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3);
     783             :     }
     784             :     else
     785             :     {
     786           0 :         rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa);
     787             :     }
     788           0 :     return rca * MASK + 0.5;
     789             : }
     790             : 
     791           0 : PDF_SEPARABLE_BLEND_MODE (soft_light)
     792             : 
     793             : /*
     794             :  * Difference
     795             :  * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da)
     796             :  */
     797             : static inline uint32_t
     798           0 : blend_difference (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     799             : {
     800           0 :     uint32_t dcasa = dca * sa;
     801           0 :     uint32_t scada = sca * da;
     802             : 
     803           0 :     if (scada < dcasa)
     804           0 :         return DIV_ONE_UN8 (dcasa - scada);
     805             :     else
     806           0 :         return DIV_ONE_UN8 (scada - dcasa);
     807             : }
     808             : 
     809           0 : PDF_SEPARABLE_BLEND_MODE (difference)
     810             : 
     811             : /*
     812             :  * Exclusion
     813             :  * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca)
     814             :  */
     815             : 
     816             : /* This can be made faster by writing it directly and not using
     817             :  * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
     818             : 
     819             : static inline uint32_t
     820           0 : blend_exclusion (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa)
     821             : {
     822           0 :     return DIV_ONE_UN8 (sca * da + dca * sa - 2 * dca * sca);
     823             : }
     824             : 
     825           0 : PDF_SEPARABLE_BLEND_MODE (exclusion)
     826             : 
     827             : #undef PDF_SEPARABLE_BLEND_MODE
     828             : 
     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             :  */
     862             : 
     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             :  */
     903             : 
     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             :  */
     936             : 
     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))
     941             : 
     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             :     }
     980             : 
     981             : static void
     982           0 : 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];
     986             : 
     987           0 :     a = sa * (1.0 / MASK);
     988             : 
     989           0 :     l = lum * (1.0 / MASK);
     990           0 :     tmp[0] = src[0] * (1.0 / MASK);
     991           0 :     tmp[1] = src[1] * (1.0 / MASK);
     992           0 :     tmp[2] = src[2] * (1.0 / MASK);
     993             : 
     994           0 :     l = l - LUM (tmp);
     995           0 :     tmp[0] += l;
     996           0 :     tmp[1] += l;
     997           0 :     tmp[2] += l;
     998             : 
     999             :     /* clip_color */
    1000           0 :     l = LUM (tmp);
    1001           0 :     min = CH_MIN (tmp);
    1002           0 :     max = CH_MAX (tmp);
    1003             : 
    1004           0 :     if (min < 0)
    1005             :     {
    1006           0 :         if (l - min == 0.0)
    1007             :         {
    1008           0 :             tmp[0] = 0;
    1009           0 :             tmp[1] = 0;
    1010           0 :             tmp[2] = 0;
    1011             :         }
    1012             :         else
    1013             :         {
    1014           0 :             tmp[0] = l + (tmp[0] - l) * l / (l - min);
    1015           0 :             tmp[1] = l + (tmp[1] - l) * l / (l - min);
    1016           0 :             tmp[2] = l + (tmp[2] - l) * l / (l - min);
    1017             :         }
    1018             :     }
    1019           0 :     if (max > a)
    1020             :     {
    1021           0 :         if (max - l == 0.0)
    1022             :         {
    1023           0 :             tmp[0] = a;
    1024           0 :             tmp[1] = a;
    1025           0 :             tmp[2] = a;
    1026             :         }
    1027             :         else
    1028             :         {
    1029           0 :             tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
    1030           0 :             tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
    1031           0 :             tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
    1032             :         }
    1033             :     }
    1034             : 
    1035           0 :     dest[0] = tmp[0] * MASK + 0.5;
    1036           0 :     dest[1] = tmp[1] * MASK + 0.5;
    1037           0 :     dest[2] = tmp[2] * MASK + 0.5;
    1038           0 : }
    1039             : 
    1040             : static void
    1041           0 : set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat)
    1042             : {
    1043             :     int id[3];
    1044             :     uint32_t min, max;
    1045             : 
    1046           0 :     if (src[0] > src[1])
    1047             :     {
    1048           0 :         if (src[0] > src[2])
    1049             :         {
    1050           0 :             id[0] = 0;
    1051           0 :             if (src[1] > src[2])
    1052             :             {
    1053           0 :                 id[1] = 1;
    1054           0 :                 id[2] = 2;
    1055             :             }
    1056             :             else
    1057             :             {
    1058           0 :                 id[1] = 2;
    1059           0 :                 id[2] = 1;
    1060             :             }
    1061             :         }
    1062             :         else
    1063             :         {
    1064           0 :             id[0] = 2;
    1065           0 :             id[1] = 0;
    1066           0 :             id[2] = 1;
    1067             :         }
    1068             :     }
    1069             :     else
    1070             :     {
    1071           0 :         if (src[0] > src[2])
    1072             :         {
    1073           0 :             id[0] = 1;
    1074           0 :             id[1] = 0;
    1075           0 :             id[2] = 2;
    1076             :         }
    1077             :         else
    1078             :         {
    1079           0 :             id[2] = 0;
    1080           0 :             if (src[1] > src[2])
    1081             :             {
    1082           0 :                 id[0] = 1;
    1083           0 :                 id[1] = 2;
    1084             :             }
    1085             :             else
    1086             :             {
    1087           0 :                 id[0] = 2;
    1088           0 :                 id[1] = 1;
    1089             :             }
    1090             :         }
    1091             :     }
    1092             : 
    1093           0 :     max = dest[id[0]];
    1094           0 :     min = dest[id[2]];
    1095           0 :     if (max > min)
    1096             :     {
    1097           0 :         dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
    1098           0 :         dest[id[0]] = sat;
    1099           0 :         dest[id[2]] = 0;
    1100             :     }
    1101             :     else
    1102             :     {
    1103           0 :         dest[0] = dest[1] = dest[2] = 0;
    1104             :     }
    1105           0 : }
    1106             : 
    1107             : /*
    1108             :  * Hue:
    1109             :  * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb))
    1110             :  */
    1111             : static inline void
    1112           0 : 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)
    1117             : {
    1118           0 :     c[0] = sc[0] * da;
    1119           0 :     c[1] = sc[1] * da;
    1120           0 :     c[2] = sc[2] * da;
    1121           0 :     set_sat (c, c, SAT (dc) * sa);
    1122           0 :     set_lum (c, c, sa * da, LUM (dc) * sa);
    1123           0 : }
    1124             : 
    1125           0 : PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
    1126             : 
    1127             : /*
    1128             :  * Saturation:
    1129             :  * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb))
    1130             :  */
    1131             : static inline void
    1132           0 : 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)
    1137             : {
    1138           0 :     c[0] = dc[0] * sa;
    1139           0 :     c[1] = dc[1] * sa;
    1140           0 :     c[2] = dc[2] * sa;
    1141           0 :     set_sat (c, c, SAT (sc) * da);
    1142           0 :     set_lum (c, c, sa * da, LUM (dc) * sa);
    1143           0 : }
    1144             : 
    1145           0 : PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
    1146             : 
    1147             : /*
    1148             :  * Color:
    1149             :  * B(Cb, Cs) = set_lum (Cs, LUM (Cb))
    1150             :  */
    1151             : static inline void
    1152           0 : 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)
    1157             : {
    1158           0 :     c[0] = sc[0] * da;
    1159           0 :     c[1] = sc[1] * da;
    1160           0 :     c[2] = sc[2] * da;
    1161           0 :     set_lum (c, c, sa * da, LUM (dc) * sa);
    1162           0 : }
    1163             : 
    1164           0 : PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
    1165             : 
    1166             : /*
    1167             :  * Luminosity:
    1168             :  * B(Cb, Cs) = set_lum (Cb, LUM (Cs))
    1169             :  */
    1170             : static inline void
    1171           0 : 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)
    1176             : {
    1177           0 :     c[0] = dc[0] * sa;
    1178           0 :     c[1] = dc[1] * sa;
    1179           0 :     c[2] = dc[2] * sa;
    1180           0 :     set_lum (c, c, sa * da, LUM (sc) * da);
    1181           0 : }
    1182             : 
    1183           0 : PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
    1184             : 
    1185             : #undef SAT
    1186             : #undef LUM
    1187             : #undef CH_MAX
    1188             : #undef CH_MIN
    1189             : #undef PDF_NON_SEPARABLE_BLEND_MODE
    1190             : 
    1191             : /* All of the disjoint/conjoint composing functions
    1192             :  *
    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.
    1197             :  * 
    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)
    1212             :  *
    1213             :  * See  http://marc.info/?l=xfree-render&m=99792000027857&w=2  for more
    1214             :  * information about these operators.
    1215             :  */
    1216             : 
    1217             : #define COMBINE_A_OUT 1
    1218             : #define COMBINE_A_IN  2
    1219             : #define COMBINE_B_OUT 4
    1220             : #define COMBINE_B_IN  8
    1221             : 
    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)
    1230             : 
    1231             : /* portion covered by a but not b */
    1232             : static uint8_t
    1233           0 : combine_disjoint_out_part (uint8_t a, uint8_t b)
    1234             : {
    1235             :     /* min (1, (1-b) / a) */
    1236             : 
    1237           0 :     b = ~b;                 /* 1 - b */
    1238           0 :     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
    1239           0 :         return MASK;        /* 1 */
    1240           0 :     return DIV_UN8 (b, a);     /* (1-b) / a */
    1241             : }
    1242             : 
    1243             : /* portion covered by both a and b */
    1244             : static uint8_t
    1245           0 : combine_disjoint_in_part (uint8_t a, uint8_t b)
    1246             : {
    1247             :     /* max (1-(1-b)/a,0) */
    1248             :     /*  = - min ((1-b)/a - 1, 0) */
    1249             :     /*  = 1 - min (1, (1-b)/a) */
    1250             : 
    1251           0 :     b = ~b;                 /* 1 - b */
    1252           0 :     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
    1253           0 :         return 0;           /* 1 - 1 */
    1254           0 :     return ~DIV_UN8(b, a);    /* 1 - (1-b) / a */
    1255             : }
    1256             : 
    1257             : /* portion covered by a but not b */
    1258             : static uint8_t
    1259           0 : combine_conjoint_out_part (uint8_t a, uint8_t b)
    1260             : {
    1261             :     /* max (1-b/a,0) */
    1262             :     /* = 1-min(b/a,1) */
    1263             : 
    1264             :     /* min (1, (1-b) / a) */
    1265             : 
    1266           0 :     if (b >= a)             /* b >= a -> b/a >= 1 */
    1267           0 :         return 0x00;        /* 0 */
    1268           0 :     return ~DIV_UN8(b, a);    /* 1 - b/a */
    1269             : }
    1270             : 
    1271             : /* portion covered by both a and b */
    1272             : static uint8_t
    1273           0 : combine_conjoint_in_part (uint8_t a, uint8_t b)
    1274             : {
    1275             :     /* min (1,b/a) */
    1276             : 
    1277           0 :     if (b >= a)             /* b >= a -> b/a >= 1 */
    1278           0 :         return MASK;        /* 1 */
    1279           0 :     return DIV_UN8 (b, a);     /* b/a */
    1280             : }
    1281             : 
    1282             : #define GET_COMP(v, i)   ((uint16_t) (uint8_t) ((v) >> i))
    1283             : 
    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))
    1287             : 
    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))
    1293             : 
    1294             : static void
    1295           0 : combine_disjoint_general_u (uint32_t *      dest,
    1296             :                             const uint32_t *src,
    1297             :                             const uint32_t *mask,
    1298             :                             int            width,
    1299             :                             uint8_t        combine)
    1300             : {
    1301             :     int i;
    1302             : 
    1303           0 :     for (i = 0; i < width; ++i)
    1304             :     {
    1305           0 :         uint32_t s = combine_mask (src, mask, i);
    1306           0 :         uint32_t d = *(dest + i);
    1307             :         uint32_t m, n, o, p;
    1308             :         uint16_t Fa, Fb, t, u, v;
    1309           0 :         uint8_t sa = s >> A_SHIFT;
    1310           0 :         uint8_t da = d >> A_SHIFT;
    1311             : 
    1312           0 :         switch (combine & COMBINE_A)
    1313             :         {
    1314             :         default:
    1315           0 :             Fa = 0;
    1316           0 :             break;
    1317             : 
    1318             :         case COMBINE_A_OUT:
    1319           0 :             Fa = combine_disjoint_out_part (sa, da);
    1320           0 :             break;
    1321             : 
    1322             :         case COMBINE_A_IN:
    1323           0 :             Fa = combine_disjoint_in_part (sa, da);
    1324           0 :             break;
    1325             : 
    1326             :         case COMBINE_A:
    1327           0 :             Fa = MASK;
    1328           0 :             break;
    1329             :         }
    1330             : 
    1331           0 :         switch (combine & COMBINE_B)
    1332             :         {
    1333             :         default:
    1334           0 :             Fb = 0;
    1335           0 :             break;
    1336             : 
    1337             :         case COMBINE_B_OUT:
    1338           0 :             Fb = combine_disjoint_out_part (da, sa);
    1339           0 :             break;
    1340             : 
    1341             :         case COMBINE_B_IN:
    1342           0 :             Fb = combine_disjoint_in_part (da, sa);
    1343           0 :             break;
    1344             : 
    1345             :         case COMBINE_B:
    1346           0 :             Fb = MASK;
    1347           0 :             break;
    1348             :         }
    1349           0 :         m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
    1350           0 :         n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
    1351           0 :         o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
    1352           0 :         p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
    1353           0 :         s = m | n | o | p;
    1354           0 :         *(dest + i) = s;
    1355             :     }
    1356           0 : }
    1357             : 
    1358             : static void
    1359           0 : 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)
    1365             : {
    1366             :     int i;
    1367             : 
    1368           0 :     for (i = 0; i < width; ++i)
    1369             :     {
    1370           0 :         uint32_t s = combine_mask (src, mask, i);
    1371           0 :         uint16_t a = s >> A_SHIFT;
    1372             : 
    1373           0 :         if (s != 0x00)
    1374             :         {
    1375           0 :             uint32_t d = *(dest + i);
    1376           0 :             a = combine_disjoint_out_part (d >> A_SHIFT, a);
    1377           0 :             UN8x4_MUL_UN8_ADD_UN8x4 (d, a, s);
    1378             : 
    1379           0 :             *(dest + i) = d;
    1380             :         }
    1381             :     }
    1382           0 : }
    1383             : 
    1384             : static void
    1385           0 : 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)
    1391             : {
    1392           0 :     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
    1393           0 : }
    1394             : 
    1395             : static void
    1396           0 : 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)
    1402             : {
    1403           0 :     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
    1404           0 : }
    1405             : 
    1406             : static void
    1407           0 : 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)
    1413             : {
    1414           0 :     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
    1415           0 : }
    1416             : 
    1417             : static void
    1418           0 : 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)
    1424             : {
    1425           0 :     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
    1426           0 : }
    1427             : 
    1428             : static void
    1429           0 : 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)
    1435             : {
    1436           0 :     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
    1437           0 : }
    1438             : 
    1439             : static void
    1440           0 : 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)
    1446             : {
    1447           0 :     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
    1448           0 : }
    1449             : 
    1450             : static void
    1451           0 : 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)
    1457             : {
    1458           0 :     combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
    1459           0 : }
    1460             : 
    1461             : static void
    1462           0 : combine_conjoint_general_u (uint32_t *      dest,
    1463             :                             const uint32_t *src,
    1464             :                             const uint32_t *mask,
    1465             :                             int            width,
    1466             :                             uint8_t        combine)
    1467             : {
    1468             :     int i;
    1469             : 
    1470           0 :     for (i = 0; i < width; ++i)
    1471             :     {
    1472           0 :         uint32_t s = combine_mask (src, mask, i);
    1473           0 :         uint32_t d = *(dest + i);
    1474             :         uint32_t m, n, o, p;
    1475             :         uint16_t Fa, Fb, t, u, v;
    1476           0 :         uint8_t sa = s >> A_SHIFT;
    1477           0 :         uint8_t da = d >> A_SHIFT;
    1478             : 
    1479           0 :         switch (combine & COMBINE_A)
    1480             :         {
    1481             :         default:
    1482           0 :             Fa = 0;
    1483           0 :             break;
    1484             : 
    1485             :         case COMBINE_A_OUT:
    1486           0 :             Fa = combine_conjoint_out_part (sa, da);
    1487           0 :             break;
    1488             : 
    1489             :         case COMBINE_A_IN:
    1490           0 :             Fa = combine_conjoint_in_part (sa, da);
    1491           0 :             break;
    1492             : 
    1493             :         case COMBINE_A:
    1494           0 :             Fa = MASK;
    1495           0 :             break;
    1496             :         }
    1497             : 
    1498           0 :         switch (combine & COMBINE_B)
    1499             :         {
    1500             :         default:
    1501           0 :             Fb = 0;
    1502           0 :             break;
    1503             : 
    1504             :         case COMBINE_B_OUT:
    1505           0 :             Fb = combine_conjoint_out_part (da, sa);
    1506           0 :             break;
    1507             : 
    1508             :         case COMBINE_B_IN:
    1509           0 :             Fb = combine_conjoint_in_part (da, sa);
    1510           0 :             break;
    1511             : 
    1512             :         case COMBINE_B:
    1513           0 :             Fb = MASK;
    1514           0 :             break;
    1515             :         }
    1516             : 
    1517           0 :         m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
    1518           0 :         n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
    1519           0 :         o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
    1520           0 :         p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
    1521             : 
    1522           0 :         s = m | n | o | p;
    1523             : 
    1524           0 :         *(dest + i) = s;
    1525             :     }
    1526           0 : }
    1527             : 
    1528             : static void
    1529           0 : 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)
    1535             : {
    1536           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
    1537           0 : }
    1538             : 
    1539             : static void
    1540           0 : 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)
    1546             : {
    1547           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
    1548           0 : }
    1549             : 
    1550             : static void
    1551           0 : 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)
    1557             : {
    1558           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
    1559           0 : }
    1560             : 
    1561             : static void
    1562           0 : 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)
    1568             : {
    1569           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
    1570           0 : }
    1571             : 
    1572             : static void
    1573           0 : 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)
    1579             : {
    1580           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
    1581           0 : }
    1582             : 
    1583             : static void
    1584           0 : 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)
    1590             : {
    1591           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
    1592           0 : }
    1593             : 
    1594             : static void
    1595           0 : 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)
    1601             : {
    1602           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
    1603           0 : }
    1604             : 
    1605             : static void
    1606           0 : 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)
    1612             : {
    1613           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
    1614           0 : }
    1615             : 
    1616             : static void
    1617           0 : 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)
    1623             : {
    1624           0 :     combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
    1625           0 : }
    1626             : 
    1627             : 
    1628             : /* Component alpha combiners */
    1629             : 
    1630             : static void
    1631           0 : 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)
    1637             : {
    1638           0 :     memset (dest, 0, width * sizeof(uint32_t));
    1639           0 : }
    1640             : 
    1641             : static void
    1642           0 : 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)
    1648             : {
    1649             :     int i;
    1650             : 
    1651           0 :     for (i = 0; i < width; ++i)
    1652             :     {
    1653           0 :         uint32_t s = *(src + i);
    1654           0 :         uint32_t m = *(mask + i);
    1655             : 
    1656           0 :         combine_mask_value_ca (&s, &m);
    1657             : 
    1658           0 :         *(dest + i) = s;
    1659             :     }
    1660           0 : }
    1661             : 
    1662             : static void
    1663           0 : 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)
    1669             : {
    1670             :     int i;
    1671             : 
    1672           0 :     for (i = 0; i < width; ++i)
    1673             :     {
    1674           0 :         uint32_t s = *(src + i);
    1675           0 :         uint32_t m = *(mask + i);
    1676             :         uint32_t a;
    1677             : 
    1678           0 :         combine_mask_ca (&s, &m);
    1679             : 
    1680           0 :         a = ~m;
    1681           0 :         if (a)
    1682             :         {
    1683           0 :             uint32_t d = *(dest + i);
    1684           0 :             UN8x4_MUL_UN8x4_ADD_UN8x4 (d, a, s);
    1685           0 :             s = d;
    1686             :         }
    1687             : 
    1688           0 :         *(dest + i) = s;
    1689             :     }
    1690           0 : }
    1691             : 
    1692             : static void
    1693           0 : 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)
    1699             : {
    1700             :     int i;
    1701             : 
    1702           0 :     for (i = 0; i < width; ++i)
    1703             :     {
    1704           0 :         uint32_t d = *(dest + i);
    1705           0 :         uint32_t a = ~d >> A_SHIFT;
    1706             : 
    1707           0 :         if (a)
    1708             :         {
    1709           0 :             uint32_t s = *(src + i);
    1710           0 :             uint32_t m = *(mask + i);
    1711             : 
    1712           0 :             UN8x4_MUL_UN8x4 (s, m);
    1713           0 :             UN8x4_MUL_UN8_ADD_UN8x4 (s, a, d);
    1714             : 
    1715           0 :             *(dest + i) = s;
    1716             :         }
    1717             :     }
    1718           0 : }
    1719             : 
    1720             : static void
    1721           0 : 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)
    1727             : {
    1728             :     int i;
    1729             : 
    1730           0 :     for (i = 0; i < width; ++i)
    1731             :     {
    1732           0 :         uint32_t d = *(dest + i);
    1733           0 :         uint16_t a = d >> A_SHIFT;
    1734           0 :         uint32_t s = 0;
    1735             : 
    1736           0 :         if (a)
    1737             :         {
    1738           0 :             uint32_t m = *(mask + i);
    1739             : 
    1740           0 :             s = *(src + i);
    1741           0 :             combine_mask_value_ca (&s, &m);
    1742             : 
    1743           0 :             if (a != MASK)
    1744           0 :                 UN8x4_MUL_UN8 (s, a);
    1745             :         }
    1746             : 
    1747           0 :         *(dest + i) = s;
    1748             :     }
    1749           0 : }
    1750             : 
    1751             : static void
    1752           0 : 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)
    1758             : {
    1759             :     int i;
    1760             : 
    1761           0 :     for (i = 0; i < width; ++i)
    1762             :     {
    1763           0 :         uint32_t s = *(src + i);
    1764           0 :         uint32_t m = *(mask + i);
    1765             :         uint32_t a;
    1766             : 
    1767           0 :         combine_mask_alpha_ca (&s, &m);
    1768             : 
    1769           0 :         a = m;
    1770           0 :         if (a != ~0)
    1771             :         {
    1772           0 :             uint32_t d = 0;
    1773             : 
    1774           0 :             if (a)
    1775             :             {
    1776           0 :                 d = *(dest + i);
    1777           0 :                 UN8x4_MUL_UN8x4 (d, a);
    1778             :             }
    1779             : 
    1780           0 :             *(dest + i) = d;
    1781             :         }
    1782             :     }
    1783           0 : }
    1784             : 
    1785             : static void
    1786           0 : 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)
    1792             : {
    1793             :     int i;
    1794             : 
    1795           0 :     for (i = 0; i < width; ++i)
    1796             :     {
    1797           0 :         uint32_t d = *(dest + i);
    1798           0 :         uint16_t a = ~d >> A_SHIFT;
    1799           0 :         uint32_t s = 0;
    1800             : 
    1801           0 :         if (a)
    1802             :         {
    1803           0 :             uint32_t m = *(mask + i);
    1804             : 
    1805           0 :             s = *(src + i);
    1806           0 :             combine_mask_value_ca (&s, &m);
    1807             : 
    1808           0 :             if (a != MASK)
    1809           0 :                 UN8x4_MUL_UN8 (s, a);
    1810             :         }
    1811             : 
    1812           0 :         *(dest + i) = s;
    1813             :     }
    1814           0 : }
    1815             : 
    1816             : static void
    1817           0 : 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)
    1823             : {
    1824             :     int i;
    1825             : 
    1826           0 :     for (i = 0; i < width; ++i)
    1827             :     {
    1828           0 :         uint32_t s = *(src + i);
    1829           0 :         uint32_t m = *(mask + i);
    1830             :         uint32_t a;
    1831             : 
    1832           0 :         combine_mask_alpha_ca (&s, &m);
    1833             : 
    1834           0 :         a = ~m;
    1835           0 :         if (a != ~0)
    1836             :         {
    1837           0 :             uint32_t d = 0;
    1838             : 
    1839           0 :             if (a)
    1840             :             {
    1841           0 :                 d = *(dest + i);
    1842           0 :                 UN8x4_MUL_UN8x4 (d, a);
    1843             :             }
    1844             : 
    1845           0 :             *(dest + i) = d;
    1846             :         }
    1847             :     }
    1848           0 : }
    1849             : 
    1850             : static void
    1851           0 : 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)
    1857             : {
    1858             :     int i;
    1859             : 
    1860           0 :     for (i = 0; i < width; ++i)
    1861             :     {
    1862           0 :         uint32_t d = *(dest + i);
    1863           0 :         uint32_t s = *(src + i);
    1864           0 :         uint32_t m = *(mask + i);
    1865             :         uint32_t ad;
    1866           0 :         uint16_t as = d >> A_SHIFT;
    1867             : 
    1868           0 :         combine_mask_ca (&s, &m);
    1869             : 
    1870           0 :         ad = ~m;
    1871             : 
    1872           0 :         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
    1873             : 
    1874           0 :         *(dest + i) = d;
    1875             :     }
    1876           0 : }
    1877             : 
    1878             : static void
    1879           0 : 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)
    1885             : {
    1886             :     int i;
    1887             : 
    1888           0 :     for (i = 0; i < width; ++i)
    1889             :     {
    1890           0 :         uint32_t d = *(dest + i);
    1891           0 :         uint32_t s = *(src + i);
    1892           0 :         uint32_t m = *(mask + i);
    1893             :         uint32_t ad;
    1894           0 :         uint16_t as = ~d >> A_SHIFT;
    1895             : 
    1896           0 :         combine_mask_ca (&s, &m);
    1897             : 
    1898           0 :         ad = m;
    1899             : 
    1900           0 :         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
    1901             : 
    1902           0 :         *(dest + i) = d;
    1903             :     }
    1904           0 : }
    1905             : 
    1906             : static void
    1907           0 : 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)
    1913             : {
    1914             :     int i;
    1915             : 
    1916           0 :     for (i = 0; i < width; ++i)
    1917             :     {
    1918           0 :         uint32_t d = *(dest + i);
    1919           0 :         uint32_t s = *(src + i);
    1920           0 :         uint32_t m = *(mask + i);
    1921             :         uint32_t ad;
    1922           0 :         uint16_t as = ~d >> A_SHIFT;
    1923             : 
    1924           0 :         combine_mask_ca (&s, &m);
    1925             : 
    1926           0 :         ad = ~m;
    1927             : 
    1928           0 :         UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as);
    1929             : 
    1930           0 :         *(dest + i) = d;
    1931             :     }
    1932           0 : }
    1933             : 
    1934             : static void
    1935           0 : 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)
    1941             : {
    1942             :     int i;
    1943             : 
    1944           0 :     for (i = 0; i < width; ++i)
    1945             :     {
    1946           0 :         uint32_t s = *(src + i);
    1947           0 :         uint32_t m = *(mask + i);
    1948           0 :         uint32_t d = *(dest + i);
    1949             : 
    1950           0 :         combine_mask_value_ca (&s, &m);
    1951             : 
    1952           0 :         UN8x4_ADD_UN8x4 (d, s);
    1953             : 
    1954           0 :         *(dest + i) = d;
    1955             :     }
    1956           0 : }
    1957             : 
    1958             : static void
    1959           0 : 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)
    1965             : {
    1966             :     int i;
    1967             : 
    1968           0 :     for (i = 0; i < width; ++i)
    1969             :     {
    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;
    1974             : 
    1975           0 :         d = *(dest + i);
    1976           0 :         s = *(src + i);
    1977           0 :         m = *(mask + i);
    1978             : 
    1979           0 :         combine_mask_ca (&s, &m);
    1980             : 
    1981           0 :         sa = (m >> A_SHIFT);
    1982           0 :         sr = (m >> R_SHIFT) & MASK;
    1983           0 :         sg = (m >> G_SHIFT) & MASK;
    1984           0 :         sb =  m             & MASK;
    1985           0 :         da = ~d >> A_SHIFT;
    1986             : 
    1987           0 :         if (sb <= da)
    1988           0 :             m = ADD (s, d, 0, t);
    1989             :         else
    1990           0 :             m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
    1991             : 
    1992           0 :         if (sg <= da)
    1993           0 :             n = ADD (s, d, G_SHIFT, t);
    1994             :         else
    1995           0 :             n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
    1996             : 
    1997           0 :         if (sr <= da)
    1998           0 :             o = ADD (s, d, R_SHIFT, t);
    1999             :         else
    2000           0 :             o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
    2001             : 
    2002           0 :         if (sa <= da)
    2003           0 :             p = ADD (s, d, A_SHIFT, t);
    2004             :         else
    2005           0 :             p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
    2006             : 
    2007           0 :         *(dest + i) = m | n | o | p;
    2008             :     }
    2009           0 : }
    2010             : 
    2011             : static void
    2012           0 : combine_disjoint_general_ca (uint32_t *      dest,
    2013             :                              const uint32_t *src,
    2014             :                              const uint32_t *mask,
    2015             :                              int            width,
    2016             :                              uint8_t        combine)
    2017             : {
    2018             :     int i;
    2019             : 
    2020           0 :     for (i = 0; i < width; ++i)
    2021             :     {
    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;
    2028             : 
    2029           0 :         s = *(src + i);
    2030           0 :         m = *(mask + i);
    2031           0 :         d = *(dest + i);
    2032           0 :         da = d >> A_SHIFT;
    2033             : 
    2034           0 :         combine_mask_ca (&s, &m);
    2035             : 
    2036           0 :         sa = m;
    2037             : 
    2038           0 :         switch (combine & COMBINE_A)
    2039             :         {
    2040             :         default:
    2041           0 :             Fa = 0;
    2042           0 :             break;
    2043             : 
    2044             :         case COMBINE_A_OUT:
    2045           0 :             m = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> 0), da);
    2046           0 :             n = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
    2047           0 :             o = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
    2048           0 :             p = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
    2049           0 :             Fa = m | n | o | p;
    2050           0 :             break;
    2051             : 
    2052             :         case COMBINE_A_IN:
    2053           0 :             m = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> 0), da);
    2054           0 :             n = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
    2055           0 :             o = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
    2056           0 :             p = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
    2057           0 :             Fa = m | n | o | p;
    2058           0 :             break;
    2059             : 
    2060             :         case COMBINE_A:
    2061           0 :             Fa = ~0;
    2062           0 :             break;
    2063             :         }
    2064             : 
    2065           0 :         switch (combine & COMBINE_B)
    2066             :         {
    2067             :         default:
    2068           0 :             Fb = 0;
    2069           0 :             break;
    2070             : 
    2071             :         case COMBINE_B_OUT:
    2072           0 :             m = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> 0));
    2073           0 :             n = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
    2074           0 :             o = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
    2075           0 :             p = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
    2076           0 :             Fb = m | n | o | p;
    2077           0 :             break;
    2078             : 
    2079             :         case COMBINE_B_IN:
    2080           0 :             m = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> 0));
    2081           0 :             n = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
    2082           0 :             o = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
    2083           0 :             p = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
    2084           0 :             Fb = m | n | o | p;
    2085           0 :             break;
    2086             : 
    2087             :         case COMBINE_B:
    2088           0 :             Fb = ~0;
    2089           0 :             break;
    2090             :         }
    2091           0 :         m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
    2092           0 :         n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
    2093           0 :         o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
    2094           0 :         p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
    2095             : 
    2096           0 :         s = m | n | o | p;
    2097             : 
    2098           0 :         *(dest + i) = s;
    2099             :     }
    2100           0 : }
    2101             : 
    2102             : static void
    2103           0 : 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)
    2109             : {
    2110           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
    2111           0 : }
    2112             : 
    2113             : static void
    2114           0 : 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)
    2120             : {
    2121           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
    2122           0 : }
    2123             : 
    2124             : static void
    2125           0 : 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)
    2131             : {
    2132           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
    2133           0 : }
    2134             : 
    2135             : static void
    2136           0 : 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)
    2142             : {
    2143           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
    2144           0 : }
    2145             : 
    2146             : static void
    2147           0 : 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)
    2153             : {
    2154           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
    2155           0 : }
    2156             : 
    2157             : static void
    2158           0 : 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)
    2164             : {
    2165           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
    2166           0 : }
    2167             : 
    2168             : static void
    2169           0 : 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)
    2175             : {
    2176           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
    2177           0 : }
    2178             : 
    2179             : static void
    2180           0 : 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)
    2186             : {
    2187           0 :     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
    2188           0 : }
    2189             : 
    2190             : static void
    2191           0 : combine_conjoint_general_ca (uint32_t *      dest,
    2192             :                              const uint32_t *src,
    2193             :                              const uint32_t *mask,
    2194             :                              int            width,
    2195             :                              uint8_t        combine)
    2196             : {
    2197             :     int i;
    2198             : 
    2199           0 :     for (i = 0; i < width; ++i)
    2200             :     {
    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;
    2207             : 
    2208           0 :         s = *(src + i);
    2209           0 :         m = *(mask + i);
    2210           0 :         d = *(dest + i);
    2211           0 :         da = d >> A_SHIFT;
    2212             : 
    2213           0 :         combine_mask_ca (&s, &m);
    2214             : 
    2215           0 :         sa = m;
    2216             : 
    2217           0 :         switch (combine & COMBINE_A)
    2218             :         {
    2219             :         default:
    2220           0 :             Fa = 0;
    2221           0 :             break;
    2222             : 
    2223             :         case COMBINE_A_OUT:
    2224           0 :             m = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> 0), da);
    2225           0 :             n = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
    2226           0 :             o = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
    2227           0 :             p = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
    2228           0 :             Fa = m | n | o | p;
    2229           0 :             break;
    2230             : 
    2231             :         case COMBINE_A_IN:
    2232           0 :             m = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> 0), da);
    2233           0 :             n = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT;
    2234           0 :             o = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT;
    2235           0 :             p = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT;
    2236           0 :             Fa = m | n | o | p;
    2237           0 :             break;
    2238             : 
    2239             :         case COMBINE_A:
    2240           0 :             Fa = ~0;
    2241           0 :             break;
    2242             :         }
    2243             : 
    2244           0 :         switch (combine & COMBINE_B)
    2245             :         {
    2246             :         default:
    2247           0 :             Fb = 0;
    2248           0 :             break;
    2249             : 
    2250             :         case COMBINE_B_OUT:
    2251           0 :             m = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> 0));
    2252           0 :             n = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
    2253           0 :             o = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
    2254           0 :             p = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
    2255           0 :             Fb = m | n | o | p;
    2256           0 :             break;
    2257             : 
    2258             :         case COMBINE_B_IN:
    2259           0 :             m = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> 0));
    2260           0 :             n = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT;
    2261           0 :             o = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT;
    2262           0 :             p = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT;
    2263           0 :             Fb = m | n | o | p;
    2264           0 :             break;
    2265             : 
    2266             :         case COMBINE_B:
    2267           0 :             Fb = ~0;
    2268           0 :             break;
    2269             :         }
    2270           0 :         m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
    2271           0 :         n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
    2272           0 :         o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
    2273           0 :         p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
    2274             : 
    2275           0 :         s = m | n | o | p;
    2276             : 
    2277           0 :         *(dest + i) = s;
    2278             :     }
    2279           0 : }
    2280             : 
    2281             : static void
    2282           0 : 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)
    2288             : {
    2289           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
    2290           0 : }
    2291             : 
    2292             : static void
    2293           0 : 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)
    2299             : {
    2300           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
    2301           0 : }
    2302             : 
    2303             : static void
    2304           0 : 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)
    2310             : {
    2311           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
    2312           0 : }
    2313             : 
    2314             : static void
    2315           0 : 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)
    2321             : {
    2322           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
    2323           0 : }
    2324             : 
    2325             : static void
    2326           0 : 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)
    2332             : {
    2333           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
    2334           0 : }
    2335             : 
    2336             : static void
    2337           0 : 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)
    2343             : {
    2344           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
    2345           0 : }
    2346             : 
    2347             : static void
    2348           0 : 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)
    2354             : {
    2355           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
    2356           0 : }
    2357             : 
    2358             : static void
    2359           0 : 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)
    2365             : {
    2366           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
    2367           0 : }
    2368             : 
    2369             : static void
    2370           0 : 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)
    2376             : {
    2377           0 :     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
    2378           0 : }
    2379             : 
    2380             : void
    2381           1 : _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp)
    2382             : {
    2383             :     /* Unified alpha */
    2384           1 :     imp->combine_32[PIXMAN_OP_CLEAR] = combine_clear;
    2385           1 :     imp->combine_32[PIXMAN_OP_SRC] = combine_src_u;
    2386           1 :     imp->combine_32[PIXMAN_OP_DST] = combine_dst;
    2387           1 :     imp->combine_32[PIXMAN_OP_OVER] = combine_over_u;
    2388           1 :     imp->combine_32[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u;
    2389           1 :     imp->combine_32[PIXMAN_OP_IN] = combine_in_u;
    2390           1 :     imp->combine_32[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u;
    2391           1 :     imp->combine_32[PIXMAN_OP_OUT] = combine_out_u;
    2392           1 :     imp->combine_32[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u;
    2393           1 :     imp->combine_32[PIXMAN_OP_ATOP] = combine_atop_u;
    2394           1 :     imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u;
    2395           1 :     imp->combine_32[PIXMAN_OP_XOR] = combine_xor_u;
    2396           1 :     imp->combine_32[PIXMAN_OP_ADD] = combine_add_u;
    2397           1 :     imp->combine_32[PIXMAN_OP_SATURATE] = combine_saturate_u;
    2398             : 
    2399             :     /* Disjoint, unified */
    2400           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear;
    2401           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_SRC] = combine_src_u;
    2402           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_DST] = combine_dst;
    2403           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u;
    2404           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u;
    2405           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u;
    2406           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u;
    2407           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u;
    2408           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u;
    2409           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u;
    2410           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u;
    2411           1 :     imp->combine_32[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u;
    2412             : 
    2413             :     /* Conjoint, unified */
    2414           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear;
    2415           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_SRC] = combine_src_u;
    2416           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_DST] = combine_dst;
    2417           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u;
    2418           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u;
    2419           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u;
    2420           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u;
    2421           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u;
    2422           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u;
    2423           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u;
    2424           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u;
    2425           1 :     imp->combine_32[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u;
    2426             : 
    2427           1 :     imp->combine_32[PIXMAN_OP_MULTIPLY] = combine_multiply_u;
    2428           1 :     imp->combine_32[PIXMAN_OP_SCREEN] = combine_screen_u;
    2429           1 :     imp->combine_32[PIXMAN_OP_OVERLAY] = combine_overlay_u;
    2430           1 :     imp->combine_32[PIXMAN_OP_DARKEN] = combine_darken_u;
    2431           1 :     imp->combine_32[PIXMAN_OP_LIGHTEN] = combine_lighten_u;
    2432           1 :     imp->combine_32[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u;
    2433           1 :     imp->combine_32[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u;
    2434           1 :     imp->combine_32[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u;
    2435           1 :     imp->combine_32[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u;
    2436           1 :     imp->combine_32[PIXMAN_OP_DIFFERENCE] = combine_difference_u;
    2437           1 :     imp->combine_32[PIXMAN_OP_EXCLUSION] = combine_exclusion_u;
    2438           1 :     imp->combine_32[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u;
    2439           1 :     imp->combine_32[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u;
    2440           1 :     imp->combine_32[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u;
    2441           1 :     imp->combine_32[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u;
    2442             : 
    2443             :     /* Component alpha combiners */
    2444           1 :     imp->combine_32_ca[PIXMAN_OP_CLEAR] = combine_clear_ca;
    2445           1 :     imp->combine_32_ca[PIXMAN_OP_SRC] = combine_src_ca;
    2446             :     /* dest */
    2447           1 :     imp->combine_32_ca[PIXMAN_OP_OVER] = combine_over_ca;
    2448           1 :     imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca;
    2449           1 :     imp->combine_32_ca[PIXMAN_OP_IN] = combine_in_ca;
    2450           1 :     imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca;
    2451           1 :     imp->combine_32_ca[PIXMAN_OP_OUT] = combine_out_ca;
    2452           1 :     imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca;
    2453           1 :     imp->combine_32_ca[PIXMAN_OP_ATOP] = combine_atop_ca;
    2454           1 :     imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca;
    2455           1 :     imp->combine_32_ca[PIXMAN_OP_XOR] = combine_xor_ca;
    2456           1 :     imp->combine_32_ca[PIXMAN_OP_ADD] = combine_add_ca;
    2457           1 :     imp->combine_32_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca;
    2458             : 
    2459             :     /* Disjoint CA */
    2460           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca;
    2461           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca;
    2462           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst;
    2463           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca;
    2464           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca;
    2465           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca;
    2466           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca;
    2467           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca;
    2468           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca;
    2469           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca;
    2470           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca;
    2471           1 :     imp->combine_32_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca;
    2472             : 
    2473             :     /* Conjoint CA */
    2474           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca;
    2475           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca;
    2476           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst;
    2477           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca;
    2478           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca;
    2479           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca;
    2480           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca;
    2481           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca;
    2482           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca;
    2483           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca;
    2484           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca;
    2485           1 :     imp->combine_32_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca;
    2486             : 
    2487           1 :     imp->combine_32_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca;
    2488           1 :     imp->combine_32_ca[PIXMAN_OP_SCREEN] = combine_screen_ca;
    2489           1 :     imp->combine_32_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca;
    2490           1 :     imp->combine_32_ca[PIXMAN_OP_DARKEN] = combine_darken_ca;
    2491           1 :     imp->combine_32_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca;
    2492           1 :     imp->combine_32_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca;
    2493           1 :     imp->combine_32_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca;
    2494           1 :     imp->combine_32_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca;
    2495           1 :     imp->combine_32_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca;
    2496           1 :     imp->combine_32_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca;
    2497           1 :     imp->combine_32_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca;
    2498             : 
    2499             :     /* It is not clear that these make sense, so make them noops for now */
    2500           1 :     imp->combine_32_ca[PIXMAN_OP_HSL_HUE] = combine_dst;
    2501           1 :     imp->combine_32_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst;
    2502           1 :     imp->combine_32_ca[PIXMAN_OP_HSL_COLOR] = combine_dst;
    2503           1 :     imp->combine_32_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst;
    2504           1 : }

Generated by: LCOV version 1.13