## enlightenment-devel

 [E-devel] Alpha Blending (from: Evas patches -- 2) From: Jose O Gonzalez - 2004-03-24 11:30:20 ```> > > 1) Replace the current formula for the new destination > > > alpha (when blending to rgba) by the formula > > > BLEND_COLOR(a, A_VAL(dst), 255, A_VAL(dst), tmp) > > > where "a" is the relevant alpha value. > > > > i tried this and tested it - it is, in fact, wrong :( sorry - the > > math doesn't > > work you as you want it to - i actually tested it and the results > > were - well > > catastrophically bad in terms of rendering display :( i can't put > > this in :( > > That's odd... I'll see if I can take a look at it in more detail > and figure out what's happenning... Well, it has taken some time to look into this as it took me further into things than I'd initially expected ... But I believe that I've found the problem -- it's actually still lurking there in the code recently committed to CVS. I found it very odd that you observed such "catastrophic" results because the difference in the computed alpha values from using the blend-macro vs using the current formula is at most 1, and both give 0 iff the input values are 0. Nevertheless, I thought perhaps an accuracy issue was involved and so took a look at the question of "dividing by 255". I will omit details here, but essentially I found the following: 1) Let's call the "c-ideal", or best approx for color-blending, the formula: DATA8 nc1 = 0.5 + c1 + (((c0 - c1) * a0) / 255.0); for given input DATA8 a0, c0, c1; It turns out that this can be evaluated using integer arithmetic by: DATA32 tmp = (255 * c1) + ((c0 - c1) * a0) + 0x80; DATA8 nc1 = (tmp + (tmp >> 8)) >> 8; If it's any faster, one can rewrite the first statement as: DATA32 tmp = ((c1 << 8) - c1) + ((c0 - c1) * a0) + 0x80; 2) Let's call the "a-ideal", or best approx for alpha-blending, the formula: DATA8 na1 = 0.5 + a1 + (((255 - a1) * a0) / 255.0); for given input DATA8 a0, a1; This too can be evaluated using integer arithmetic by: DATA32 tmp = ((255 - a1) * a0) + 0x80; DATA8 na1 = a1 + ((tmp + (tmp >> 8)) >> 8); ---------------------------------------------------------------- We may compare the currently used blend-macro formulas with the "c-ideal" for color-blending, and we find that it differs from it for 1,938 cases. For alpha-blending, using the blend-macro (as proposed in the patches) differs from the "a-ideal" for only 24 cases, whereas the formula a1 + (((255 - a1) * a0) / 255) that is currently used, differs from the "a-ideal" for 21,770 cases. Now, from the formulas for all of these, it is clear that for both the color and alpha components, the computed values from any of these differ by at most 1, ie. the absolute value of their difference is 0 or 1. Also, the computed alpha value na1, is 0 iff a1 = a0 = 0, for all of these. From these facts, one would expect that, visually, the difference between using any of these would be difficult to notice, with say one or two blendings, for most common types of images. ---------------------------------------------------------------- Now, to the heart of the matter: I wrote functions for doing rgba to rgba blending with the following five different methods: -------- A) For the color components: the int-arith formula in 1) for the "c-ideal". For the alpha component: the int-arith formula in 2) for the "a-ideal". This is the "ideal". -------- B) For the color components: the current blend-macro. For the alpha component: the int-arith formula in 2) for the "a-ideal". -------- C) For the color components: the current blend-macro. For the alpha component: the current blend-macro used to compute alpha (as in the patches). So this corresponds to what was in the Evas patches (and in the Imlib2 patches as well). -------- D) For the color components: the current blend-macro. For the alpha component: the formula a1 + (((255 - a1) * a0) / 255) ie. The current blending function in CVS. -------- E) For the color components: the formula c1 + (((c0 - c1) * a0) / 255) For the alpha component: the formula a1 + (((255 - a1) * a0) / 255) This one just for completeness. -------------------------------------------------------- I ran a variety of tests using each of the above, blending a variety of images (with alpha) together 2^n times, for n = 0 to 8, in various associative combinations, from one to 4 layers deep..., and I'll be dammed if I could see any significant difference in the results at all, much less anything that could be considered as radically different. This led me to believe that you had done something wrong in writing down the implementations of the functions, I checked the patches I sent and found them ok. I thus took a look at the code recently committed to CVS and I believe that I've found the culprit. It seems to be that when you tested this, you wrote BLEND_COLOR(A_VAL(src), A_VAL(dst), 255, A_VAL(dst), tmp) because, unfortunately, you are iterating over things called src_ptr and dst_ptr, NOT over the input src, dst pointers. You actually still have this in the "evas_blend_ pixel_cmod_pixel.c" file, but I also found it commented out of other files in an earlier commit, I guess when first trying to test this suggestion of mine. I'm enclosing *new* patches which hopefully will be ok. Please test against the patches and see if you still obtain odd results. If you do, then the problem is very, very odd indeed. jose. PS. If it does work, I'd consider increasing the accuracy further by using the "a-ideal" described in 2), to compute the alpha values; and if it's not much slower, perhaps also use the "c-ideal" of 1) to do the color blending -- but I've not pursued this in the patches. **************************************************************** Index: e17/libs/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_al pha_color_pixel.c,v retrieving revision 1.5 diff -u -r1.5 evas_blend_alpha_color_pixel.c --- e17/libs/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c 18 Mar 2004 09:06:11 -0000 1.5 +++ e17/libs/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c 24 Mar 2004 10:45:29 -0000 @@ -147,12 +147,10 @@ while (dst_ptr < dst_end_ptr) { DATA32 tmp; - DATA8 a; - DATA8 aa; + DATA8 a, aa; aa = (((*src_ptr) + 1) * A_VAL(&col)) >> 8; - a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; - switch (a) + switch (aa) { case 0: break; @@ -160,6 +158,10 @@ *dst_ptr = col; break; default: + a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; + BLEND_COLOR(aa, A_VAL(dst_ptr), + 255, A_VAL(dst_ptr), + tmp); BLEND_COLOR(a, R_VAL(dst_ptr), R_VAL(&col), R_VAL(dst_ptr), tmp); @@ -169,7 +171,6 @@ BLEND_COLOR(a, B_VAL(dst_ptr), B_VAL(&col), B_VAL(dst_ptr), tmp); - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((aa * (255 - A_VAL(dst_ptr))) / 255); break; } src_ptr++; ************************************************************************* ******************* Index: e17/libs/evas/src/lib/engines/common/evas_blend_color_pixel.c =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_co lor_pixel.c,v retrieving revision 1.5 diff -u -r1.5 evas_blend_color_pixel.c --- e17/libs/evas/src/lib/engines/common/evas_blend_color_pixel.c 18 Mar 2004 09:06:12 -0000 1.5 +++ e17/libs/evas/src/lib/engines/common/evas_blend_color_pixel.c 24 Mar 2004 10:46:47 -0000 @@ -96,6 +96,9 @@ a = _evas_pow_lut[A_VAL(&src)][A_VAL(dst_ptr)]; + BLEND_COLOR(A_VAL(&src), A_VAL(dst_ptr), + 255, A_VAL(dst_ptr), + tmp); BLEND_COLOR(a, R_VAL(dst_ptr), R_VAL(&src), R_VAL(dst_ptr), tmp); @@ -105,7 +108,6 @@ BLEND_COLOR(a, B_VAL(dst_ptr), B_VAL(&src), B_VAL(dst_ptr), tmp); - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((A_VAL(&src) * (255 - A_VAL(dst_ptr))) / 255); dst_ptr++; } ************************************************************************* ************************ Index: e17/libs/evas/src/lib/engines/common/evas_blend_pixel_pixel.c =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_pi xel_pixel.c,v retrieving revision 1.8 diff -u -r1.8 evas_blend_pixel_pixel.c --- e17/libs/evas/src/lib/engines/common/evas_blend_pixel_pixel.c 18 Mar 2004 09:06:12 -0000 1.8 +++ e17/libs/evas/src/lib/engines/common/evas_blend_pixel_pixel.c 24 Mar 2004 10:49:19 -0000 @@ -22,9 +22,12 @@ while (dst_ptr < dst_end_ptr) { DATA32 tmp; + DATA8 a; + + a = A_VAL(src_ptr); #ifdef CONDITIONAL_BLEND - switch (A_VAL(src_ptr)) + switch (a) { case 0: break; @@ -32,27 +35,27 @@ *dst_ptr = *src_ptr; break; default: - BLEND_COLOR(A_VAL(src_ptr), R_VAL(dst_ptr), + BLEND_COLOR(a, R_VAL(dst_ptr), R_VAL(src_ptr), R_VAL(dst_ptr), tmp); - BLEND_COLOR(A_VAL(src_ptr), G_VAL(dst_ptr), + BLEND_COLOR(a, G_VAL(dst_ptr), G_VAL(src_ptr), G_VAL(dst_ptr), tmp); - BLEND_COLOR(A_VAL(src_ptr), B_VAL(dst_ptr), + BLEND_COLOR(a, B_VAL(dst_ptr), B_VAL(src_ptr), B_VAL(dst_ptr), tmp); break; } #else - if (A_VAL(src_ptr)) + if (a) { - BLEND_COLOR(A_VAL(src_ptr), R_VAL(dst_ptr), + BLEND_COLOR(a, R_VAL(dst_ptr), R_VAL(src_ptr), R_VAL(dst_ptr), tmp); - BLEND_COLOR(A_VAL(src_ptr), G_VAL(dst_ptr), + BLEND_COLOR(a, G_VAL(dst_ptr), G_VAL(src_ptr), G_VAL(dst_ptr), tmp); - BLEND_COLOR(A_VAL(src_ptr), B_VAL(dst_ptr), + BLEND_COLOR(a, B_VAL(dst_ptr), B_VAL(src_ptr), B_VAL(dst_ptr), tmp); } @@ -128,9 +131,10 @@ while (dst_ptr < dst_end_ptr) { DATA32 tmp; - DATA8 a; + DATA8 a, aa; - switch (A_VAL(src_ptr)) + aa = A_VAL(src_ptr); + switch (aa) { case 0: break; @@ -138,8 +142,11 @@ *dst_ptr = *src_ptr; break; default: - a = _evas_pow_lut[A_VAL(src_ptr)][A_VAL(dst_ptr)]; + a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; + BLEND_COLOR(aa, A_VAL(dst_ptr), + 255, A_VAL(dst_ptr), + tmp); BLEND_COLOR(a, R_VAL(dst_ptr), R_VAL(src_ptr), R_VAL(dst_ptr), tmp); @@ -149,7 +156,6 @@ BLEND_COLOR(a, B_VAL(dst_ptr), B_VAL(src_ptr), B_VAL(dst_ptr), tmp); - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((A_VAL(src_ptr) * (255 - A_VAL(dst_ptr))) / 255); } src_ptr++; dst_ptr++; ************************************************************************* ******************************** Index: e17/libs/evas/src/lib/engines/common/evas_blend_pixel_cmod_pixel.c =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_pi xel_cmod_pixel.c,v retrieving revision 1.4 diff -u -r1.4 evas_blend_pixel_cmod_pixel.c --- e17/libs/evas/src/lib/engines/common/evas_blend_pixel_cmod_pixel.c 16 Mar 2004 08:03:00 -0000 1.4 +++ e17/libs/evas/src/lib/engines/common/evas_blend_pixel_cmod_pixel.c 24 Mar 2004 10:48:22 -0000 @@ -27,7 +27,10 @@ case 0: break; case 255: - *dst_ptr = *src_ptr; + A_VAL(dst_ptr) = 0xff; + R_VAL(dst_ptr) = rmod[R_VAL(src_ptr)]; + G_VAL(dst_ptr) = gmod[G_VAL(src_ptr)]; + B_VAL(dst_ptr) = bmod[B_VAL(src_ptr)]; break; default: BLEND_COLOR(a, R_VAL(dst_ptr), @@ -60,17 +63,23 @@ while (dst_ptr < dst_end_ptr) { DATA32 tmp; - DATA8 a; - - a = _evas_pow_lut[amod[A_VAL(src_ptr)]][A_VAL(dst_ptr)]; - switch (a) + DATA8 a, aa; + + aa = amod[A_VAL(src_ptr)]; + switch (aa) { case 0: break; case 255: - *dst_ptr = *src_ptr; + A_VAL(dst_ptr) = 0xff; + R_VAL(dst_ptr) = rmod[R_VAL(src_ptr)]; + G_VAL(dst_ptr) = gmod[G_VAL(src_ptr)]; + B_VAL(dst_ptr) = bmod[B_VAL(src_ptr)]; break; default: + a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; + BLEND_COLOR(aa,A_VAL(dst_ptr), + 255,A_VAL(dst_ptr),tmp); BLEND_COLOR(a, R_VAL(dst_ptr), rmod[R_VAL(src_ptr)], R_VAL(dst_ptr), tmp); @@ -80,8 +89,6 @@ BLEND_COLOR(a, B_VAL(dst_ptr), bmod[B_VAL(src_ptr)], B_VAL(dst_ptr), tmp); - BLEND_COLOR(A_VAL(src),A_VAL(dst),255,A_VAL(dst),tmp); -/* A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((amod[A_VAL(src_ptr)] * (255 - A_VAL(dst_ptr))) / 255);*/ break; } src_ptr++; ************************************************************************* ***************************************** Index: e17/libs/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_pi xel_mul_pixel.c,v retrieving revision 1.5 diff -u -r1.5 evas_blend_pixel_mul_pixel.c --- e17/libs/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c 18 Mar 2004 09:06:12 -0000 1.5 +++ e17/libs/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c 24 Mar 2004 10:48:48 -0000 @@ -202,6 +202,9 @@ default: a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; + BLEND_COLOR(aa, A_VAL(dst_ptr), + 255, A_VAL(dst_ptr), + tmp); BLEND_COLOR(a, R_VAL(dst_ptr), R_VAL(src_ptr), R_VAL(dst_ptr), tmp); @@ -211,7 +214,6 @@ BLEND_COLOR(a, B_VAL(dst_ptr), B_VAL(src_ptr), B_VAL(dst_ptr), tmp); - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((aa * (255 - A_VAL(dst_ptr))) / 255); break; } src_ptr++; @@ -231,14 +233,17 @@ case 0: break; case 255: + A_VAL(dst_ptr) = 255; R_VAL(dst_ptr) = ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8); G_VAL(dst_ptr) = ((G_VAL(src_ptr) * (G_VAL(&mul_color) + 1)) >> 8); B_VAL(dst_ptr) = ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8); - A_VAL(dst_ptr) = 255; break; default: a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; + BLEND_COLOR(aa, A_VAL(dst_ptr), + 255, A_VAL(dst_ptr), + tmp); BLEND_COLOR(a, R_VAL(dst_ptr), ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8), R_VAL(dst_ptr), tmp); @@ -248,7 +253,6 @@ BLEND_COLOR(a, B_VAL(dst_ptr), ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8), B_VAL(dst_ptr), tmp); - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((aa * (255 - A_VAL(dst_ptr))) / 255); break; } src_ptr++; ************************************************************************* ********************************** Index: e17/libs/evas/src/lib/engines/common/evas_blend_ops.h =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_op s.h,v retrieving revision 1.1 diff -u -r1.1 evas_blend_ops.h --- e17/libs/evas/src/lib/engines/common/evas_blend_ops.h 30 Jan 2004 05:46:57 -0000 1.1 +++ e17/libs/evas/src/lib/engines/common/evas_blend_ops.h 24 Mar 2004 10:47:36 -0000 @@ -9,6 +9,9 @@ if (A_VAL(src)) /* hmmm - do we need this? */ \ { \ __a = _evas_pow_lut[A_VAL(src)][A_VAL(dst)]; \ + BLEND_COLOR(A_VAL(src), A_VAL(dst), \ + 255, A_VAL(dst), \ + __tmp); \ BLEND_COLOR(__a, R_VAL(dst), \ R_VAL(src), R_VAL(dst), \ __tmp); \ @@ -18,7 +21,6 @@ BLEND_COLOR(__a, B_VAL(dst), \ B_VAL(src), B_VAL(dst), \ __tmp); \ - A_VAL(dst) = A_VAL(dst) + ((A_VAL(src) * (255 - A_VAL(dst))) / 255);\ } \ } ************************************************************************* ******************* Index: e17/libs/evas/src/lib/engines/common/evas_line_main.c =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_line_mai n.c,v retrieving revision 1.5 diff -u -r1.5 evas_line_main.c --- e17/libs/evas/src/lib/engines/common/evas_line_main.c 18 Mar 2004 09:22:36 -0000 1.5 +++ e17/libs/evas/src/lib/engines/common/evas_line_main.c 24 Mar 2004 11:07:33 -0000 @@ -31,6 +31,8 @@ sx = SGN(dx); sy = SGN(dy); + col = dc->col.col; + if ((dx == 0) && (dy == 0)) { if ((x1 < 0) || @@ -54,6 +56,9 @@ ptr = dst->image->data + (y1 * dst->image->w) + x1; __blend_a = _evas_pow_lut[A_VAL(&(col))][A_VAL(ptr)]; + BLEND_COLOR(A_VAL(&(col)), A_VAL(ptr), + 255, A_VAL(ptr), + __blend_tmp); BLEND_COLOR(__blend_a, R_VAL(ptr), R_VAL(&(col)), R_VAL(ptr), __blend_tmp); @@ -63,7 +68,6 @@ BLEND_COLOR(__blend_a, B_VAL(ptr), B_VAL(&(col)), B_VAL(ptr), __blend_tmp); - A_VAL(ptr) = A_VAL(ptr) + ((A_VAL(&(col)) * (255 - A_VAL(ptr))) / 255); } else { @@ -86,8 +90,6 @@ im = dst->image->data; im_w = dst->image->w; im_h = dst->image->h; - col = dc->col.col; - if (!A_VAL(&(col))) return; ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h; if (dc->clip.use) @@ -146,6 +148,9 @@ __blend_a = _evas_pow_lut[A_VAL(&(col))][A_VAL(ptr)]; + BLEND_COLOR(A_VAL(&(col)), A_VAL(ptr), + 255, A_VAL(ptr), + __blend_tmp); BLEND_COLOR(__blend_a, R_VAL(ptr), R_VAL(&(col)), R_VAL(ptr), __blend_tmp); @@ -155,7 +160,6 @@ BLEND_COLOR(__blend_a, B_VAL(ptr), B_VAL(&(col)), B_VAL(ptr), __blend_tmp); - A_VAL(ptr) = A_VAL(ptr) + ((A_VAL(&(col)) * (255 - A_VAL(ptr))) / 255); } } if (x == x2) return; @@ -183,6 +187,9 @@ __blend_a = _evas_pow_lut[A_VAL(&(col))][A_VAL(ptr)]; + BLEND_COLOR(A_VAL(&(col)), A_VAL(ptr), + 255, A_VAL(ptr), + __blend_tmp); BLEND_COLOR(__blend_a, R_VAL(ptr), R_VAL(&(col)), R_VAL(ptr), __blend_tmp); @@ -192,7 +199,6 @@ BLEND_COLOR(__blend_a, B_VAL(ptr), B_VAL(&(col)), B_VAL(ptr), __blend_tmp); - A_VAL(ptr) = A_VAL(ptr) + ((A_VAL(&(col)) * (255 - A_VAL(ptr))) / 255); } } if (y == y2) return; ************************************************************************* *************************************** ```
 Re: [E-devel] Alpha Blending (from: Evas patches -- 2) From: Carsten Haitzler (The Rasterman) - 2004-04-05 06:38:32 ```On Wed, 24 Mar 2004 06:32:09 -0500 Jose O Gonzalez babbled: eek - ok - looking into patch. i have a problem.... because you included it in yout mail it has been line-wrapped and mangled and its too big to "unmangle" can you send a patch again as an attachment? that'd be great! :) > > > > > 1) Replace the current formula for the new destination > > > > alpha (when blending to rgba) by the formula > > > > BLEND_COLOR(a, A_VAL(dst), 255, A_VAL(dst), tmp) > > > > where "a" is the relevant alpha value. > > > > > > i tried this and tested it - it is, in fact, wrong :( sorry - the > > > math doesn't > > > work you as you want it to - i actually tested it and the results > > > were - well > > > catastrophically bad in terms of rendering display :( i can't put > > > this in :( > > > > That's odd... I'll see if I can take a look at it in more detail > > and figure out what's happenning... > > > Well, it has taken some time to look into this as it > took me further into things than I'd initially expected ... > But I believe that I've found the problem -- it's actually still > lurking there in the code recently committed to CVS. > > > I found it very odd that you observed such "catastrophic" > results because the difference in the computed alpha values > from using the blend-macro vs using the current formula is at > most 1, and both give 0 iff the input values are 0. > > Nevertheless, I thought perhaps an accuracy issue was > involved and so took a look at the question of "dividing by 255". > I will omit details here, but essentially I found the > following: > > 1) > Let's call the "c-ideal", or best approx for color-blending, > the formula: > > DATA8 nc1 = 0.5 + c1 + (((c0 - c1) * a0) / 255.0); > > for given input DATA8 a0, c0, c1; > > It turns out that this can be evaluated using integer > arithmetic by: > > DATA32 tmp = (255 * c1) + ((c0 - c1) * a0) + 0x80; > DATA8 nc1 = (tmp + (tmp >> 8)) >> 8; > > If it's any faster, one can rewrite the first statement as: > > DATA32 tmp = ((c1 << 8) - c1) + ((c0 - c1) * a0) + 0x80; > > > 2) > Let's call the "a-ideal", or best approx for alpha-blending, > the formula: > > DATA8 na1 = 0.5 + a1 + (((255 - a1) * a0) / 255.0); > > for given input DATA8 a0, a1; > > This too can be evaluated using integer arithmetic by: > > DATA32 tmp = ((255 - a1) * a0) + 0x80; > DATA8 na1 = a1 + ((tmp + (tmp >> 8)) >> 8); > > ---------------------------------------------------------------- > > We may compare the currently used blend-macro formulas > with the "c-ideal" for color-blending, and we find that it differs > from it for 1,938 cases. > > For alpha-blending, using the blend-macro (as proposed > in the patches) differs from the "a-ideal" for only 24 cases, > whereas the formula a1 + (((255 - a1) * a0) / 255) that is > currently used, differs from the "a-ideal" for 21,770 cases. > > Now, from the formulas for all of these, it is > clear that for both the color and alpha components, the > computed values from any of these differ by at most 1, > ie. the absolute value of their difference is 0 or 1. > Also, the computed alpha value na1, is 0 iff > a1 = a0 = 0, for all of these. > > From these facts, one would expect that, visually, > the difference between using any of these would be difficult > to notice, with say one or two blendings, for most common > types of images. > > ---------------------------------------------------------------- > > Now, to the heart of the matter: > > I wrote functions for doing rgba to rgba blending > with the following five different methods: > > -------- > A) > For the color components: the int-arith formula in 1) > for the "c-ideal". > For the alpha component: the int-arith formula in 2) > for the "a-ideal". > > This is the "ideal". > -------- > B) > For the color components: the current blend-macro. > > For the alpha component: the int-arith formula in 2) > for the "a-ideal". > -------- > C) > For the color components: the current blend-macro. > > For the alpha component: the current blend-macro used > to compute alpha (as in the patches). > > So this corresponds to what was in the Evas patches > (and in the Imlib2 patches as well). > -------- > D) > For the color components: the current blend-macro. > > For the alpha component: the formula > a1 + (((255 - a1) * a0) / 255) > > ie. The current blending function in CVS. > -------- > E) > For the color components: the formula > c1 + (((c0 - c1) * a0) / 255) > For the alpha component: the formula > a1 + (((255 - a1) * a0) / 255) > > This one just for completeness. > -------------------------------------------------------- > > > I ran a variety of tests using each of the above, > blending a variety of images (with alpha) together 2^n > times, for n = 0 to 8, in various associative combinations, > from one to 4 layers deep..., and I'll be dammed if I could > see any significant difference in the results at all, much > less anything that could be considered as radically different. > > This led me to believe that you had done something > wrong in writing down the implementations of the functions, > I checked the patches I sent and found them ok. > I thus took a look at the code recently committed > to CVS and I believe that I've found the culprit. > > It seems to be that when you tested this, you wrote > > BLEND_COLOR(A_VAL(src), A_VAL(dst), 255, A_VAL(dst), tmp) > > because, unfortunately, you are iterating over things called > src_ptr and dst_ptr, NOT over the input src, dst pointers. > > You actually still have this in the "evas_blend_ > pixel_cmod_pixel.c" file, but I also found it commented out > of other files in an earlier commit, I guess when first > trying to test this suggestion of mine. > > I'm enclosing *new* patches which hopefully will > be ok. > Please test against the patches and see if you still > obtain odd results. > > If you do, then the problem is very, very odd indeed. > > jose. > > PS. > If it does work, I'd consider increasing the accuracy > further by using the "a-ideal" described in 2), to compute > the alpha values; and if it's not much slower, perhaps also > use the "c-ideal" of 1) to do the color blending -- but I've > not pursued this in the patches. > > > **************************************************************** > > Index: > e17/libs/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c > =================================================================== > RCS file: > /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_al > pha_color_pixel.c,v > retrieving revision 1.5 > diff -u -r1.5 evas_blend_alpha_color_pixel.c > --- > e17/libs/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c 18 > Mar 2004 09:06:11 -0000 1.5 > +++ > e17/libs/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c 24 > Mar 2004 10:45:29 -0000 > @@ -147,12 +147,10 @@ > while (dst_ptr < dst_end_ptr) > { > DATA32 tmp; > - DATA8 a; > - DATA8 aa; > + DATA8 a, aa; > > aa = (((*src_ptr) + 1) * A_VAL(&col)) >> 8; > - a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; > - switch (a) > + switch (aa) > { > case 0: > break; > @@ -160,6 +158,10 @@ > *dst_ptr = col; > break; > default: > + a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; > + BLEND_COLOR(aa, A_VAL(dst_ptr), > + 255, A_VAL(dst_ptr), > + tmp); > BLEND_COLOR(a, R_VAL(dst_ptr), > R_VAL(&col), R_VAL(dst_ptr), > tmp); > @@ -169,7 +171,6 @@ > BLEND_COLOR(a, B_VAL(dst_ptr), > B_VAL(&col), B_VAL(dst_ptr), > tmp); > - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((aa * (255 - A_VAL(dst_ptr))) / > 255); > break; > } > src_ptr++; > > ************************************************************************* > ******************* > > Index: e17/libs/evas/src/lib/engines/common/evas_blend_color_pixel.c > =================================================================== > RCS file: > /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_co > lor_pixel.c,v > retrieving revision 1.5 > diff -u -r1.5 evas_blend_color_pixel.c > --- e17/libs/evas/src/lib/engines/common/evas_blend_color_pixel.c 18 Mar > 2004 09:06:12 -0000 1.5 > +++ e17/libs/evas/src/lib/engines/common/evas_blend_color_pixel.c 24 Mar > 2004 10:46:47 -0000 > @@ -96,6 +96,9 @@ > > a = _evas_pow_lut[A_VAL(&src)][A_VAL(dst_ptr)]; > > + BLEND_COLOR(A_VAL(&src), A_VAL(dst_ptr), > + 255, A_VAL(dst_ptr), > + tmp); > BLEND_COLOR(a, R_VAL(dst_ptr), > R_VAL(&src), R_VAL(dst_ptr), > tmp); > @@ -105,7 +108,6 @@ > BLEND_COLOR(a, B_VAL(dst_ptr), > B_VAL(&src), B_VAL(dst_ptr), > tmp); > - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((A_VAL(&src) * (255 - > A_VAL(dst_ptr))) / 255); > > dst_ptr++; > } > > ************************************************************************* > ************************ > > Index: e17/libs/evas/src/lib/engines/common/evas_blend_pixel_pixel.c > =================================================================== > RCS file: > /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_pi > xel_pixel.c,v > retrieving revision 1.8 > diff -u -r1.8 evas_blend_pixel_pixel.c > --- e17/libs/evas/src/lib/engines/common/evas_blend_pixel_pixel.c 18 Mar > 2004 09:06:12 -0000 1.8 > +++ e17/libs/evas/src/lib/engines/common/evas_blend_pixel_pixel.c 24 Mar > 2004 10:49:19 -0000 > @@ -22,9 +22,12 @@ > while (dst_ptr < dst_end_ptr) > { > DATA32 tmp; > + DATA8 a; > + > + a = A_VAL(src_ptr); > > #ifdef CONDITIONAL_BLEND > - switch (A_VAL(src_ptr)) > + switch (a) > { > case 0: > break; > @@ -32,27 +35,27 @@ > *dst_ptr = *src_ptr; > break; > default: > - BLEND_COLOR(A_VAL(src_ptr), R_VAL(dst_ptr), > + BLEND_COLOR(a, R_VAL(dst_ptr), > R_VAL(src_ptr), R_VAL(dst_ptr), > tmp); > - BLEND_COLOR(A_VAL(src_ptr), G_VAL(dst_ptr), > + BLEND_COLOR(a, G_VAL(dst_ptr), > G_VAL(src_ptr), G_VAL(dst_ptr), > tmp); > - BLEND_COLOR(A_VAL(src_ptr), B_VAL(dst_ptr), > + BLEND_COLOR(a, B_VAL(dst_ptr), > B_VAL(src_ptr), B_VAL(dst_ptr), > tmp); > break; > } > #else > - if (A_VAL(src_ptr)) > + if (a) > { > - BLEND_COLOR(A_VAL(src_ptr), R_VAL(dst_ptr), > + BLEND_COLOR(a, R_VAL(dst_ptr), > R_VAL(src_ptr), R_VAL(dst_ptr), > tmp); > - BLEND_COLOR(A_VAL(src_ptr), G_VAL(dst_ptr), > + BLEND_COLOR(a, G_VAL(dst_ptr), > G_VAL(src_ptr), G_VAL(dst_ptr), > tmp); > - BLEND_COLOR(A_VAL(src_ptr), B_VAL(dst_ptr), > + BLEND_COLOR(a, B_VAL(dst_ptr), > B_VAL(src_ptr), B_VAL(dst_ptr), > tmp); > } > @@ -128,9 +131,10 @@ > while (dst_ptr < dst_end_ptr) > { > DATA32 tmp; > - DATA8 a; > + DATA8 a, aa; > > - switch (A_VAL(src_ptr)) > + aa = A_VAL(src_ptr); > + switch (aa) > { > case 0: > break; > @@ -138,8 +142,11 @@ > *dst_ptr = *src_ptr; > break; > default: > - a = _evas_pow_lut[A_VAL(src_ptr)][A_VAL(dst_ptr)]; > + a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; > > + BLEND_COLOR(aa, A_VAL(dst_ptr), > + 255, A_VAL(dst_ptr), > + tmp); > BLEND_COLOR(a, R_VAL(dst_ptr), > R_VAL(src_ptr), R_VAL(dst_ptr), > tmp); > @@ -149,7 +156,6 @@ > BLEND_COLOR(a, B_VAL(dst_ptr), > B_VAL(src_ptr), B_VAL(dst_ptr), > tmp); > - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((A_VAL(src_ptr) * (255 - > A_VAL(dst_ptr))) / 255); > } > src_ptr++; > dst_ptr++; > > ************************************************************************* > ******************************** > > Index: e17/libs/evas/src/lib/engines/common/evas_blend_pixel_cmod_pixel.c > =================================================================== > RCS file: > /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_pi > xel_cmod_pixel.c,v > retrieving revision 1.4 > diff -u -r1.4 evas_blend_pixel_cmod_pixel.c > --- e17/libs/evas/src/lib/engines/common/evas_blend_pixel_cmod_pixel.c 16 > Mar 2004 08:03:00 -0000 1.4 > +++ e17/libs/evas/src/lib/engines/common/evas_blend_pixel_cmod_pixel.c 24 > Mar 2004 10:48:22 -0000 > @@ -27,7 +27,10 @@ > case 0: > break; > case 255: > - *dst_ptr = *src_ptr; > + A_VAL(dst_ptr) = 0xff; > + R_VAL(dst_ptr) = rmod[R_VAL(src_ptr)]; > + G_VAL(dst_ptr) = gmod[G_VAL(src_ptr)]; > + B_VAL(dst_ptr) = bmod[B_VAL(src_ptr)]; > break; > default: > BLEND_COLOR(a, R_VAL(dst_ptr), > @@ -60,17 +63,23 @@ > while (dst_ptr < dst_end_ptr) > { > DATA32 tmp; > - DATA8 a; > - > - a = _evas_pow_lut[amod[A_VAL(src_ptr)]][A_VAL(dst_ptr)]; > - switch (a) > + DATA8 a, aa; > + > + aa = amod[A_VAL(src_ptr)]; > + switch (aa) > { > case 0: > break; > case 255: > - *dst_ptr = *src_ptr; > + A_VAL(dst_ptr) = 0xff; > + R_VAL(dst_ptr) = rmod[R_VAL(src_ptr)]; > + G_VAL(dst_ptr) = gmod[G_VAL(src_ptr)]; > + B_VAL(dst_ptr) = bmod[B_VAL(src_ptr)]; > break; > default: > + a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; > + BLEND_COLOR(aa,A_VAL(dst_ptr), > + 255,A_VAL(dst_ptr),tmp); > BLEND_COLOR(a, R_VAL(dst_ptr), > rmod[R_VAL(src_ptr)], R_VAL(dst_ptr), > tmp); > @@ -80,8 +89,6 @@ > BLEND_COLOR(a, B_VAL(dst_ptr), > bmod[B_VAL(src_ptr)], B_VAL(dst_ptr), > tmp); > - BLEND_COLOR(A_VAL(src),A_VAL(dst),255,A_VAL(dst),tmp); > -/* A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((amod[A_VAL(src_ptr)] * (255 > - A_VAL(dst_ptr))) / 255);*/ > break; > } > src_ptr++; > > ************************************************************************* > ***************************************** > > Index: e17/libs/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c > =================================================================== > RCS file: > /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_pi > xel_mul_pixel.c,v > retrieving revision 1.5 > diff -u -r1.5 evas_blend_pixel_mul_pixel.c > --- e17/libs/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c 18 > Mar 2004 09:06:12 -0000 1.5 > +++ e17/libs/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c 24 > Mar 2004 10:48:48 -0000 > @@ -202,6 +202,9 @@ > default: > a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; > > + BLEND_COLOR(aa, A_VAL(dst_ptr), > + 255, A_VAL(dst_ptr), > + tmp); > BLEND_COLOR(a, R_VAL(dst_ptr), > R_VAL(src_ptr), R_VAL(dst_ptr), > tmp); > @@ -211,7 +214,6 @@ > BLEND_COLOR(a, B_VAL(dst_ptr), > B_VAL(src_ptr), B_VAL(dst_ptr), > tmp); > - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((aa * (255 - A_VAL(dst_ptr))) / > 255); > break; > } > src_ptr++; > @@ -231,14 +233,17 @@ > case 0: > break; > case 255: > + A_VAL(dst_ptr) = 255; > R_VAL(dst_ptr) = ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8); > G_VAL(dst_ptr) = ((G_VAL(src_ptr) * (G_VAL(&mul_color) + 1)) >> 8); > B_VAL(dst_ptr) = ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8); > - A_VAL(dst_ptr) = 255; > break; > default: > a = _evas_pow_lut[aa][A_VAL(dst_ptr)]; > > + BLEND_COLOR(aa, A_VAL(dst_ptr), > + 255, A_VAL(dst_ptr), > + tmp); > BLEND_COLOR(a, R_VAL(dst_ptr), > ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8), > R_VAL(dst_ptr), > tmp); > @@ -248,7 +253,6 @@ > BLEND_COLOR(a, B_VAL(dst_ptr), > ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8), > B_VAL(dst_ptr), > tmp); > - A_VAL(dst_ptr) = A_VAL(dst_ptr) + ((aa * (255 - A_VAL(dst_ptr))) / > 255); > break; > } > src_ptr++; > > ************************************************************************* > ********************************** > > Index: e17/libs/evas/src/lib/engines/common/evas_blend_ops.h > =================================================================== > RCS file: > /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_blend_op > s.h,v > retrieving revision 1.1 > diff -u -r1.1 evas_blend_ops.h > --- e17/libs/evas/src/lib/engines/common/evas_blend_ops.h 30 Jan 2004 > 05:46:57 -0000 1.1 > +++ e17/libs/evas/src/lib/engines/common/evas_blend_ops.h 24 Mar 2004 > 10:47:36 -0000 > @@ -9,6 +9,9 @@ > if (A_VAL(src)) /* hmmm - do we need this? */ \ > { \ > __a = _evas_pow_lut[A_VAL(src)][A_VAL(dst)]; \ > + BLEND_COLOR(A_VAL(src), A_VAL(dst), \ > + 255, A_VAL(dst), \ > + __tmp); \ > BLEND_COLOR(__a, R_VAL(dst), \ > R_VAL(src), R_VAL(dst), \ > __tmp); \ > @@ -18,7 +21,6 @@ > BLEND_COLOR(__a, B_VAL(dst), \ > B_VAL(src), B_VAL(dst), \ > __tmp); \ > - A_VAL(dst) = A_VAL(dst) + ((A_VAL(src) * (255 - A_VAL(dst))) / 255);\ > } \ > } > > > ************************************************************************* > ******************* > > Index: e17/libs/evas/src/lib/engines/common/evas_line_main.c > =================================================================== > RCS file: > /cvsroot/enlightenment/e17/libs/evas/src/lib/engines/common/evas_line_mai > n.c,v > retrieving revision 1.5 > diff -u -r1.5 evas_line_main.c > --- e17/libs/evas/src/lib/engines/common/evas_line_main.c 18 Mar 2004 > 09:22:36 -0000 1.5 > +++ e17/libs/evas/src/lib/engines/common/evas_line_main.c 24 Mar 2004 > 11:07:33 -0000 > @@ -31,6 +31,8 @@ > sx = SGN(dx); > sy = SGN(dy); > > + col = dc->col.col; > + > if ((dx == 0) && (dy == 0)) > { > if ((x1 < 0) || > @@ -54,6 +56,9 @@ > ptr = dst->image->data + (y1 * dst->image->w) + x1; > __blend_a = _evas_pow_lut[A_VAL(&(col))][A_VAL(ptr)]; > > + BLEND_COLOR(A_VAL(&(col)), A_VAL(ptr), > + 255, A_VAL(ptr), > + __blend_tmp); > BLEND_COLOR(__blend_a, R_VAL(ptr), > R_VAL(&(col)), R_VAL(ptr), > __blend_tmp); > @@ -63,7 +68,6 @@ > BLEND_COLOR(__blend_a, B_VAL(ptr), > B_VAL(&(col)), B_VAL(ptr), > __blend_tmp); > - A_VAL(ptr) = A_VAL(ptr) + ((A_VAL(&(col)) * (255 - A_VAL(ptr))) / > 255); > } > else > { > @@ -86,8 +90,6 @@ > im = dst->image->data; > im_w = dst->image->w; > im_h = dst->image->h; > - col = dc->col.col; > - if (!A_VAL(&(col))) return; > > ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h; > if (dc->clip.use) > @@ -146,6 +148,9 @@ > > __blend_a = _evas_pow_lut[A_VAL(&(col))][A_VAL(ptr)]; > > + BLEND_COLOR(A_VAL(&(col)), A_VAL(ptr), > + 255, A_VAL(ptr), > + __blend_tmp); > BLEND_COLOR(__blend_a, R_VAL(ptr), > R_VAL(&(col)), R_VAL(ptr), > __blend_tmp); > @@ -155,7 +160,6 @@ > BLEND_COLOR(__blend_a, B_VAL(ptr), > B_VAL(&(col)), B_VAL(ptr), > __blend_tmp); > - A_VAL(ptr) = A_VAL(ptr) + ((A_VAL(&(col)) * (255 - > A_VAL(ptr))) / 255); > } > } > if (x == x2) return; > @@ -183,6 +187,9 @@ > > __blend_a = _evas_pow_lut[A_VAL(&(col))][A_VAL(ptr)]; > > + BLEND_COLOR(A_VAL(&(col)), A_VAL(ptr), > + 255, A_VAL(ptr), > + __blend_tmp); > BLEND_COLOR(__blend_a, R_VAL(ptr), > R_VAL(&(col)), R_VAL(ptr), > __blend_tmp); > @@ -192,7 +199,6 @@ > BLEND_COLOR(__blend_a, B_VAL(ptr), > B_VAL(&(col)), B_VAL(ptr), > __blend_tmp); > - A_VAL(ptr) = A_VAL(ptr) + ((A_VAL(&(col)) * (255 - > A_VAL(ptr))) / 255); > } > } > if (y == y2) return; > > > ************************************************************************* > *************************************** > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IBM Linux Tutorials > Free Linux tutorial presented by Daniel Robbins, President and CEO of > GenToo technologies. Learn everything from fundamentals to system > administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click > _______________________________________________ > enlightenment-devel mailing list > enlightenment-devel@... > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel -- ------------- Codito, ergo sum - "I code, therefore I am" -------------- The Rasterman (Carsten Haitzler) raster@... 熊耳 - 車君 (数田) raster@... Tokyo, Japan (東京 日本) ```