Nick Lamb <[EMAIL PROTECTED]> writes:

> General purpose compose operations usually include a division by 255 of
> a number in the range 0 ... 65025. While fixing up Mozilla's alpha
> compositor I disturbed a sleeping hacker who has provided a (tested and
> working) macro which computes this operation much more quickly than
> any other solution tested, including GCC -On speed-ups using similar
> but different tricks.
> 
> Of course, GCC cannot use this FAST_DIVIDE_BY_255 because it is safe
> only for 0 ... 65025, but I think it might be useful to Gimp, both in
> the core (which I presume has several alpha compositors) and in
> plug-ins, where alpha composition is also a popular operation.
> 
> So, does Gimp already have something like this in core? Or should we
> consider borrowing this macro from wherever it originated and using
> it throughout Gimp (after 1.2, naturally) ?

You have to make sure that the code that uses such techniques indeed
has 255*255 as an upper bound.  A long time ago the GIMP was full of
inconsistencies where some parts assumed 256*256, others 255*255, yet
buggier ones 256*255.

Anyways, in libart and gdk-pixbuf we have code like this to composite
an RGBA image over an RGB pixel:

        a0 = p[3];

        if (a0 == 255) {
                dest[0] = p[0];
                dest[1] = p[1];
                dest[2] = p[2];
        } else {
                int tmp;

                tmp = ((int) p[0] - r2) * a0;
                dest[0] = r2 + ((tmp + (tmp >> 8) + 0x80) >> 8);
                tmp = ((int) p[1] - g2) * a0;
                dest[1] = g2 + ((tmp + (tmp >> 8) + 0x80) >> 8);
                tmp = ((int) p[2] - b2) * a0;
                dest[2] = b2 + ((tmp + (tmp >> 8) + 0x80) >> 8);
        }

Here, dest points to the position of the destination pixel in a guchar
array, and p points to the source pixel.  r2/g2/b2 are the background
color (here it is from a checkerboard, but it could be the background
RGB pixel).  a0 is p[3], which is the alpha value for the source
pixel.

In the border cases (alpha = 0, alpha = 255) this produces exact
results.  In the intermediate ones, the maximum difference between
doing a "slow but accurate" division and all this bit twiddling is at
most 1.  So it is just what you want.

For compositing RGBA over RGBA, you could pull similar tricks.

I think the bigger problem is auditing the GIMP to make sure that
there are no inconsistencies in the valid ranges for color values when
compositing stuff together.

What code does Mozilla use?  If it is different, could we run some
benchmarks for speed and accuracy?

  Federico

Reply via email to