nppiAlphaComp_32f_AC4R incorrect behaviour?

I’m using nppiDivC_32f_C4IR in an infinite impulse response filter. A buffer is divided, using the function, by {1, 1, 1, alpha_scale} before being composited using nppiAlphaComp_32f_AC4R with NPPI_OP_ALPHA_OVER to create a trail-off in the image. The alphas my vary across each image and vary from image to image. The result should be a slow trail off on moving objects. My problem is that the divide seems to be dividing the colour as well as the alpha as I’m getting a fade to black before the fade to transparency.

I’m investigating as I type but I suspect my problem either lies in the divide affecting the colour (though I doubt this from some playing), the alpha compose possibly pre-multiplying (which I don’t believe it should) or some other little technicality. I’d be grateful if anyone has any thoughts or can clarify what exactly nppiAlphaComp_32f_AC4R is doing.

Many thanks,
James

Hi James,

for pSrc1 pix


  • el P1 = (r1, g1, b1, a1) and pSrc2 pixel P2 = (r2, g2, b2, a2), the result pixel
    R = (r3, g3, b3, a3) is computed as follows:

    for the color channels (red as example): r3 = a1 * r1 + (1 - a1) * a2 * r2
    for the alpha channel: a3 = a1 + (1 - a1) * a2

    All this obviously for Porter-Duff “OVER”. If I interpret what you’re saying about “pre-multiplying” correctly, this should confirm your suspicion that the function is designed to composits images that are not pre-multiplied.

    I suspect it’s specified this way because for 8-bit integer images the quantization losses of pre-multiplied images would be too noticable for the function to be useful and so to be consistent all pixel formats, even those that would not suffer from quantization errors.

    PS: Since posting my original answer I talked to the NPP engineer in charge of alpha blending. It turns out that whether the primitive expects and produces pre-multiplied vs. not can be specified with the enum value that specifies the blend mode. Below the definition of the enum values.

    typedef enum {
        NPPI_OP_ALPHA_OVER,
        NPPI_OP_ALPHA_IN,
        NPPI_OP_ALPHA_OUT,
        NPPI_OP_ALPHA_ATOP,
        NPPI_OP_ALPHA_XOR,
        NPPI_OP_ALPHA_PLUS,
        NPPI_OP_ALPHA_OVER_PREMUL,
        NPPI_OP_ALPHA_IN_PREMUL,
        NPPI_OP_ALPHA_OUT_PREMUL,
        NPPI_OP_ALPHA_ATOP_PREMUL,
        NPPI_OP_ALPHA_XOR_PREMUL,
        NPPI_OP_ALPHA_PLUS_PREMUL,
        NPPI_OP_ALPHA_PREMUL
    } NppiAlphaOp;