[Gegl-developer] pre-multiplied alpha and other optimizations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

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:

guint8 sample1,sample2,result;

result=(sample1/255)*(sample2/255)*255 == (sample1/255)*sample2;

the approximation is

result = ( (sample1*sample2 + 128 ) >> 8 + (sample1*sample2+128) ) >> 8;

Is this loss of information an acceptable comprimise for the GIMP (Sven, and Yosh might want to comment on this)?

I have done a bit of math to determine whether this is a good idea. I tried to determine how much there would be error on this calculation. My first (albeit a bit naieve) was to use continuous algebra to determine what the error was explictly in terms of the factors in the product. Since >> 8 is almost the same as dividing by 256, I change the bit shifts to divide by 256 and calculated the error. My result was this:

1/2 + 1/(2 * 256) - (sample1*sample2)/(256^3-256^2) == error

Also, since sample1*sample2 <= 255^2 < 256 this is always close to 1/2. I thought this was pretty cool. The error is always high and less than one, just round down the result and you are exact (and this happens anyway when you cast to integer). However, that result seemed suspecious to me, so I dug a little further. bit shift 8 steps is not the same as dividing by 256. It is exactly this:

a >>8 == floor(a/256)

And there are two bit shifts so this rounding down may happen twice. Further more, in a really bad situation the floor will round down by a number close to 1, which means you might get an off by one error on nearly every result. I wanted to see how bad this was, but my discrete algebra is not up to par. . .

So I did it the brute force way.

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.

There is an awful lot of non-gray on that image. In precise terms, 70% of the pixels are gray. Which means 30 percent of the time, the calculation will be wrong. This gets really bad when you start convolving images. Suppose a rather small kernel size of 3 by 3. That means each pixel gets multiplied 9 times. With this approximation, there is a pretty good chance that any particular pixel is off by 2 or 3, and may be off my as much as 9 (though with pretty low probability) And this is only for a single operation.

I don't really think this kind of comprimise should be acceptable. Errors like this lead to ugly results, which comprimises the quality of output possible with the gimp and discourages its use.

That is all for now.

--
Dan


[Index of Archives]     [Yosemite News]     [Yosemite Photos]     [gtk]     [GIMP Users]     [KDE]     [Gimp's Home]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux