Exemplo n.º 1
0
 static inline void process_channel(const fix15_t Cs, fix15_t &Cb)
 {
     if (Cs > 0) {
         const fix15_t tmp = fix15_div(fix15_one - Cb, Cs);
         if (tmp < fix15_one) {
             Cb = fix15_one - tmp;
             return;
         }
     }
     Cb = 0;
 }
Exemplo n.º 2
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]);
        }
    }