2009.04.27 19:49 "[Tiff] Question regarding unassociated alpha", by Amir Ebrahimi

2009.04.27 21:14 "Re: [Tiff] Question regarding unassociated alpha", by Daniel McCoy

From Chris Cox <ccox@adobe.com>, Mon, Apr 27, 2009 at 01:00:31PM -0700:

Unassociated alpha should never be premultiplied - it is not associated with the color channels. Only assoicated alpha should be premultiplied.

The statement "it is not associated with the color channels" seems like one that would be really easy to misinterpret.

It also seems important to make a distinction between "pre-multiply" and "multiply". For unassociate alpha, the color is always supposed to be eventually multiplied by the alpha channel, which stores opacity/coverage.

The tag is meant to indicate whether or not the sofware which wrote the image file has already done the multiplication or not.

(Background: Sam Leffler and I were the two who talked the tiff committee into adding this tag back in the previous century, so I am quite familiar with the original intent of the tag.)

EXTRASAMPLE_ASSOCALPHA - The sample is alpha representing coverage/opacity.

    The color has already been pre-multiplied by the value.
    The color value can be used directly in an over operation:

        Cnew = C + (1-AA) * Cbg

    To display the image, one usually does an implicit "over black"
    by discarding the alpha and just displaying the color.

EXTRASAMPLE_UNASSALPHA - The sample value is alpha representing coverage/opacity.

    The color has NOT been pre-multiplied by the value.
    The color value needs to be multiplied before being used in an over operation:

        Cnew = UA * C + (1-UA) * Cbg

    To display the image, one must do a more explicit "over black"
    by multiplying in the alpha and displaying the resulting color.

EXTRASAMPLE_UNSPECIFIED - the sample value is just data.

Please do not confuse with UNASSALPHA with UNSPECIFIED.

The code in question is in tif_getimage.c

I'm not entirely sure of all the things it's being used for these days, but back in the day, the module provided the TIFFReadRGBAImage() function for reading a wide variety of tiff images into a single generic internal image format suitable for immediate display or some kind of conversion, all without the burden of checking a bazillion tiff tags.

The generic image format was defined to be RGBA where A is associated alpha.

TIFFReadRGBAImage has been called in the past by the tools tiff2rgba.c and rgb2ycbcr.c as well as many different image display programs.

In the case of tiff2rgba.c, I do believe it sets the output extra samples tag to EXTRASAMPLE_ASSOCALPHA, so it is expecting the TIFFReadRGBAImage package to convert unassociated alpha into associated alpha, ie multiply.

In the case of rgb2ycbcr.c, there is no output alpha channel, so it is expecting the the image to be essentially comped over black before being converted, so it's expecting TIFFReadRGBAImage to convert to associated alpha, ie. multiply.

The case of display programs is usally equivalent. The diplay program is expecting associated alpha because it's either going to discard alpha, or it's going to place the image over a background.

If you want to change TIFFReadRGBAImage to return RGBA where A might or might not be associated, you will force all existing clients to read the extra samples tag and perform any desired alpha operations itself. Defeating the original purpose of TIFFReadRGBAImage.

Another possible solution which would not impact all of the existing clients of TIFFReadRGBAImage() would be to add either another call which defines its return format as unassociated alpha, ie TIFFReadRGBUAImage(), or another alpha-agnostic function which requires one to check the tag to see what kind of alpha it just read.

In other words, the code is correct if the package is defined to perform an implicit UA -> AA conversion, which is always has in the past.

Dan McCoy - Pixar

From: tiff-bounces@lists.maptools.org [tiff-bounces@lists.maptools.org] On Behalf Of Amir Ebrahimi [amir@unity3d.com]

I'm using libtiff via FreeImage in our development tool: Unity.

We've had an image support regression with TIFF files after switching to FreeImage/libtiff from the QuickTime SDK. A file with unassociated alpha still seems to be getting pre-multiplied in with the RGB channels. Is this by design? I'd like to get the TIFF file with RGBA channels intact without it being pre-multiplied. If the image had associated alpha, then it would make sense that it was pre-multiplied, however, that isn't the case.

In libtiff (v3.9.0) line 268:269 has these comments:

case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */

case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */

which causes libtiff to use the following ContigPutFunc starting at line 1262:

putRGBUAcontig8bittile
{
        ...
        a = pp[3];

                r = (a*pp[0] + 127) / 255;
                g = (a*pp[1] + 127) / 255;
                b = (a*pp[2] + 127) / 255;

}

The alpha is still written out, however, why is the alpha being pre- multiplied here?