Exemple #1
0
    static inline void process_channel(const fix15_t Cs, fix15_t &Cb)
    {
        const fix15_t two_Cs = fix15_double(Cs);
        fix15_t B = 0;
        if (two_Cs <= fix15_one) {
            B = fix15_one - fix15_mul(fix15_one - two_Cs,
                                      fix15_one - Cb);
            B = fix15_mul(B, Cb);
        }
        else {
            fix15_t D = 0;
            const fix15_t four_Cb = Cb << 2;
            if (four_Cb <= fix15_one) {
                const fix15_t Cb_squared = fix15_mul(Cb, Cb);
                D = four_Cb; /* which is always greater than... */
                D += 16 * fix15_mul(Cb_squared, Cb);
                D -= 12 * Cb_squared;
                /* ... in the range 0 <= C_b <= 0.25 */
            }
            else {
                D = fix15_sqrt(Cb);
            }
#ifdef HEAVY_DEBUG
            /* Guard against underflows */
            assert(two_Cs > fix15_one);
            assert(D >= Cb);
#endif
            B = Cb + fix15_mul(2*Cs - fix15_one /* 2*Cs > 1 */,
                               D - Cb           /* D >= Cb */  );
        }
        Cb = B;
    }
Exemple #2
0
 inline void operator()
     (const fix15_t src_r, const fix15_t src_g, const fix15_t src_b,
      fix15_t &dst_r, fix15_t &dst_g, fix15_t &dst_b) const
 {
     dst_r = dst_r + src_r - fix15_mul(dst_r, src_r);
     dst_g = dst_g + src_g - fix15_mul(dst_g, src_g);
     dst_b = dst_b + src_b - fix15_mul(dst_b, src_b);
 }
Exemple #3
0
 inline void operator()
     (const fix15_t src_r, const fix15_t src_g, const fix15_t src_b,
      fix15_t &dst_r, fix15_t &dst_g, fix15_t &dst_b) const
 {
     dst_r = fix15_mul(src_r, dst_r);
     dst_g = fix15_mul(src_g, dst_g);
     dst_b = fix15_mul(src_b, dst_b);
 }
Exemple #4
0
 inline void operator() (const fix15_t Rs, const fix15_t Gs,
                         const fix15_t Bs, const fix15_t as,
                         fix15_short_t &rb, fix15_short_t &gb,
                         fix15_short_t &bb, fix15_short_t &ab) const
 {
     rb = fix15_short_clamp(fix15_mul(Rs, as) + rb);
     gb = fix15_short_clamp(fix15_mul(Gs, as) + gb);
     bb = fix15_short_clamp(fix15_mul(Bs, as) + bb);
     ab = fix15_short_clamp(ab + as);
 }
Exemple #5
0
 inline void operator() (const fix15_t Rs, const fix15_t Gs,
                         const fix15_t Bs, const fix15_t as,
                         fix15_short_t &rb, fix15_short_t &gb,
                         fix15_short_t &bb, fix15_short_t &ab) const
 {
     rb = fix15_short_clamp(fix15_mul(rb, as));
     gb = fix15_short_clamp(fix15_mul(gb, as));
     bb = fix15_short_clamp(fix15_mul(bb, as));
     ab = fix15_short_clamp(fix15_mul(ab, as));
 }
Exemple #6
0
 static inline void process_channel(const fix15_t Cs, fix15_t &Cb)
 {
     const fix15_t two_Cs = fix15_double(Cs);
     if (two_Cs <= fix15_one) {
         Cb = fix15_mul(Cb, two_Cs);
     }
     else {
         const fix15_t tmp = two_Cs - fix15_one;
         Cb = Cb + tmp - fix15_mul(Cb, tmp);
     }
 }
Exemple #7
0
 inline void operator() (const fix15_short_t * const src,
                         fix15_short_t * const dst,
                         const fix15_short_t opac) const
 {
     for (unsigned int i=0; i<BUFSIZE; i+=4) {
         const fix15_t one_minus_Sa = fix15_one-fix15_mul(src[i+3], opac);
         dst[i+0] = fix15_mul(dst[i+0], one_minus_Sa);
         dst[i+1] = fix15_mul(dst[i+1], one_minus_Sa);
         dst[i+2] = fix15_mul(dst[i+2], one_minus_Sa);
         if (DSTALPHA) {
             dst[i+3] = fix15_mul(one_minus_Sa, dst[i+3]);
         }
     }
 }
Exemple #8
0
 inline void operator() (const fix15_short_t * const src,
                         fix15_short_t * const dst,
                         const fix15_short_t opac) const
 {
     for (unsigned int i=0; i<BUFSIZE; i+=4) {
         const fix15_t Sa = fix15_mul(src[i+3], opac);
         const fix15_t one_minus_Sa = fix15_one - Sa;
         dst[i+0] = fix15_sumprods(src[i], opac, one_minus_Sa, dst[i]);
         dst[i+1] = fix15_sumprods(src[i+1], opac, one_minus_Sa, dst[i+1]);
         dst[i+2] = fix15_sumprods(src[i+2], opac, one_minus_Sa, dst[i+2]);
         if (DSTALPHA) {
             fix15_t tmp = Sa + dst[i+3];
             tmp -= fix15_mul(Sa, dst[i+3]);
             dst[i+3] = fix15_short_clamp(tmp);
         }
     }
 }
Exemple #9
0
    inline void operator() (const fix15_t Rs, const fix15_t Gs,
                            const fix15_t Bs, const fix15_t as,
                            fix15_short_t &rb, fix15_short_t &gb,
                            fix15_short_t &bb, fix15_short_t &ab) const
    {
        const fix15_t j = fix15_one - as;
        const fix15_t k = fix15_mul(ab, j);

        rb = fix15_short_clamp(fix15_sumprods(as, Rs, j, rb));
        gb = fix15_short_clamp(fix15_sumprods(as, Gs, j, gb));
        bb = fix15_short_clamp(fix15_sumprods(as, Bs, j, bb));
        ab = fix15_short_clamp(as + k);
    }
Exemple #10
0
 inline void operator() (const fix15_t Rs, const fix15_t Gs,
                         const fix15_t Bs, const fix15_t as,
                         fix15_short_t &rb, fix15_short_t &gb,
                         fix15_short_t &bb, fix15_short_t &ab) const
 {
     // W3C spec:
     //   co = as*Cs*(1-ab) + ab*Cb*as
     // where
     //   Cs ∈ {Rs, Gs, Bs}         -- input is non-premultiplied
     //   cb ∈ {rb gb, bb} = ab*Cb  -- output is premultiplied by alpha
     const fix15_t one_minus_ab = fix15_one - ab;
     const fix15_t as_mul_one_minus_ab = fix15_mul(as, one_minus_ab);
     rb = fix15_short_clamp(fix15_sumprods(as_mul_one_minus_ab, Rs, as, rb));
     gb = fix15_short_clamp(fix15_sumprods(as_mul_one_minus_ab, Gs, as, gb));
     bb = fix15_short_clamp(fix15_sumprods(as_mul_one_minus_ab, Bs, as, bb));
     // W3C spec:
     //   ao = as*(1-ab) + ab*as
     //   ao = as
     ab = as;
 }
Exemple #11
0
 inline void operator() (const fix15_t Rs, const fix15_t Gs,
                         const fix15_t Bs, const fix15_t as,
                         fix15_short_t &rb, fix15_short_t &gb,
                         fix15_short_t &bb, fix15_short_t &ab) const
 {
     // W3C spec:
     //   co = as*Cs*ab + ab*Cb*(1-as)
     // where
     //   Cs ∈ {Rs, Gs, Bs}         -- input is non-premultiplied
     //   cb ∈ {rb gb, bb} = ab*Cb  -- output is premultiplied by alpha
     const fix15_t one_minus_as = fix15_one - as;
     const fix15_t ab_mul_as = fix15_mul(as, ab);
     rb = fix15_short_clamp(fix15_sumprods(ab_mul_as, Rs, one_minus_as, rb));
     gb = fix15_short_clamp(fix15_sumprods(ab_mul_as, Gs, one_minus_as, gb));
     bb = fix15_short_clamp(fix15_sumprods(ab_mul_as, Bs, one_minus_as, bb));
     // W3C spec:
     //   ao = as*ab + ab*(1-as)
     //   ao = ab
     // (leave output alpha unchanged)
 }
Exemple #12
0
    inline void operator() (const fix15_short_t * const src,
                            fix15_short_t * const dst,
                            const fix15_short_t src_opacity) const
    {
#ifndef HEAVY_DEBUG
        // Skip tile if it can't affect the backdrop
        const bool skip_empty_src = ! compositefunc.zero_alpha_has_effect;
        if (skip_empty_src && src_opacity == 0) {
            return;
        }
#endif

        // Pixel loop
        fix15_t Rs,Gs,Bs,as, Rb,Gb,Bb,ab, one_minus_ab;
#pragma omp parallel for private(Rs,Gs,Bs,as, Rb,Gb,Bb,ab, one_minus_ab)
        for (unsigned int i = 0; i < BUFSIZE; i += 4)
        {
            // Calculate unpremultiplied source RGB values
            as = src[i+3];
            if (as == 0) {
#ifndef HEAVY_DEBUG
                // Skip pixel if it can't affect the backdrop pixel
                if (skip_empty_src) {
                    continue;
                }
#endif
                // Otherwise just avoid the divide-by-zero by assuming the
                // value before premultiplication was also zero.
                Rs = Gs = Bs = 0;
            }
            else {
                Rs = fix15_short_clamp(fix15_div(src[i+0], as));
                Gs = fix15_short_clamp(fix15_div(src[i+1], as));
                Bs = fix15_short_clamp(fix15_div(src[i+2], as));
            }
#ifdef HEAVY_DEBUG
            assert(Rs <= fix15_one); assert(Rs >= 0);
            assert(Gs <= fix15_one); assert(Gs >= 0);
            assert(Bs <= fix15_one); assert(Bs >= 0);
#endif

            // Calculate unpremultiplied backdrop RGB values
            if (DSTALPHA) {
                ab = dst[i+3];
                if (ab == 0) {
                    Rb = Gb = Bb = 0;
                }
                else {
                    Rb = fix15_short_clamp(fix15_div(dst[i+0], ab));
                    Gb = fix15_short_clamp(fix15_div(dst[i+1], ab));
                    Bb = fix15_short_clamp(fix15_div(dst[i+2], ab));
                }
            }
            else {
                ab = fix15_one;
                Rb = dst[i+0];
                Gb = dst[i+1];
                Bb = dst[i+2];
            }
#ifdef HEAVY_DEBUG
            assert(Rb <= fix15_one); assert(Rb >= 0);
            assert(Gb <= fix15_one); assert(Gb >= 0);
            assert(Bb <= fix15_one); assert(Bb >= 0);
#endif

            // Apply the colour blend functor
            blendfunc(Rs, Gs, Bs, Rb, Gb, Bb);

            // Apply results of the blend in place
            if (DSTALPHA) {
                one_minus_ab = fix15_one - ab;
                Rb = fix15_sumprods(one_minus_ab, Rs, ab, Rb);
                Gb = fix15_sumprods(one_minus_ab, Gs, ab, Gb);
                Bb = fix15_sumprods(one_minus_ab, Bs, ab, Bb);
            }
#ifdef HEAVY_DEBUG
            assert(Rb <= fix15_one); assert(Rb >= 0);
            assert(Gb <= fix15_one); assert(Gb >= 0);
            assert(Bb <= fix15_one); assert(Bb >= 0);
#endif
            // Use the blend result as a source, and composite directly into
            // the destination buffer as premultiplied RGB.
            compositefunc(Rb, Gb, Bb, fix15_mul(as, src_opacity),
                          dst[i+0], dst[i+1], dst[i+2], dst[i+3]);
        }
    }
Exemple #13
0
 static inline void process_channel(const fix15_t Cs, fix15_t &Cb)
 {
     Cb = Cb + Cs - fix15_double(fix15_mul(Cb, Cs));
 }