> > > 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
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel