On Wed, 2003-03-19 at 15:49, Daniel Rogers wrote: > There seems to be a fairly good agreement that post-multiplied alpha is > the way to go. It is more accurate, and there are currently features of > gimp that depend on it. > > I think for those reasons gegl should use post-multiplied alpha (afaik, > it currently doesn't). The loudest dissenters tend to be a little > flamey, but I think the most accurate way to go should be where we > start, since we want the gimp to look good. After the gimp looks good, > we can optimize without sacrificing image quality. I suspect there > might even be a way to get gegl to decide when pre multipling is a good > plan and do it, which would be cool. I prefer to store my image data without premultiplied alpha for the very slight accuracy improvement, but using premultiplied alpha can be a signifigant performance win when doing a sequence of convolutions and/or composite operations. I think it makes sense for us to support both even if premultipled alpha is only used as a temporary storage format passed between image ops which support it. I think I am agreeing with you, except that I don't think it is necessary to wait so long before implementing it. > In the same vein, I noticed that to multiply two integer samples you use > a macro called INT_MULT that does a non-fp division (a bit shift and > addition) that approximates the formula: <snip> > > http://www.phasevelocity.org/errimage.png > > The above image represents the error of multiplying any 2 numbers from 0 > to 255 using the above method. Gray means zero error, black means the > approximation was one low and white means the approximation was one > high. 0 times 0 is in the upper left corner. > That is a very pretty picture, but I think you made a mistake somewhere. The macro that gimp uses is exact for all input values [0-255]. The formula we are trying to match is rint(a*b/255.0) Here is a short program that shows that the macro gimp uses is correct. #define INT_MULT(a,b,t) ((t)=(a)*(b)+0x80,((((t) >> 8) + (t)) >> 8)) #define INT_MULT_EXACT(a,b) rint(a*b/255.0) #define OTHER_INT_MULT_EXACT(a,b) ((int)(((a)*(b) + 127)/255.0)) #include <stdio.h> #include <math.h> int main() { int a, b, c, t, correct = 0, bad = 0; for (a = 0; a < 256; a++) for (b = 0; b < 256; b++) { if (INT_MULT(a,b,t) != INT_MULT_EXACT(a,b)) bad++; else correct++; } printf("%d bad\n%d correct\n\n", bad, correct); } -- Jay Cox <jaycox@xxxxxxxx>