Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

223 lines
5.3 KiB

/**************************************************************************\
*
* Copyright (c) 1999-2000 Microsoft Corporation
*
* Module name:
*
* The "AlphaMultiply" and "AlphaDivide" scan operations.
*
* Abstract:
*
* See Gdiplus\Specs\ScanOperation.doc for an overview.
*
* These scan operations multiply/divide the color components by the alpha
* component. API-level input colors are (usually) specified in
* 'non-premultiplied'. Given a non-premultiplied
* color (R, G, B, A), its 'premultiplied' form is (RA, GA, BA, A).
*
* Notes:
*
* Since "AlphaMultiply" loses information, "AlphaDivide" is not a true
* inverse operation. (But it is an inverse if all pixels have an alpha of 1.)
*
* If the alpha is 0, "AlphaDivide" won't cause a divide-by-zero exception or
* do anything drastic. But it may do something random. Currently, the pixel
* value is unchanged. It could, instead, set the pixel to 0.
*
* Revision History:
*
* 12/14/1999 agodfrey
* Created it.
*
\**************************************************************************/
#include "precomp.hpp"
/**************************************************************************\
*
* Operation Description:
*
* AlphaMultiply/AlphaDivide: Convert between premultiplied and
* non-premultiplied alpha.
*
* Arguments:
*
* dst - The destination scan
* src - The source scan
* count - The length of the scan, in pixels
* otherParams - Additional data. (Ignored.)
*
* Return Value:
*
* None
*
* Notes:
*
* !!![agodfrey] Currently we use 'Unpremultiply' from imgutils.cpp.
* While we may keep the tables and lookup in imgutils.cpp,
* it needs better naming, and we want the alpha=0 and alpha=255 cases in
* here, not out-of-line in imgutils.cpp.
*
* History:
*
* 12/14/1999 agodfrey
* Created it.
*
\**************************************************************************/
ARGB Unpremultiply(ARGB argb);
// AlphaDivide from 32bpp PARGB
VOID FASTCALL
ScanOperation::AlphaDivide_sRGB(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, ARGB)
while (count--)
{
sRGB::sRGBColor c;
c.argb = *s;
if (sRGB::isTranslucent(c.argb))
{
c.argb = Unpremultiply(c.argb);
}
*d = c.argb;
d++;
s++;
}
}
// !!![agodfrey] This should be sorted out. It should be out-of-line, and kept
// with its mates in imgutils.cpp (which should maybe move), but it
// shouldn't have a translucency check (we want to do that in
// AlphaMultiply_sRGB).
ARGB MyPremultiply(ARGB argb)
{
ARGB a = (argb >> ALPHA_SHIFT);
ARGB _000000gg = (argb >> 8) & 0x000000ff;
ARGB _00rr00bb = (argb & 0x00ff00ff);
ARGB _0000gggg = _000000gg * a + 0x00000080;
_0000gggg += (_0000gggg >> 8);
ARGB _rrrrbbbb = _00rr00bb * a + 0x00800080;
_rrrrbbbb += ((_rrrrbbbb >> 8) & 0x00ff00ff);
return (a << ALPHA_SHIFT) |
(_0000gggg & 0x0000ff00) |
((_rrrrbbbb >> 8) & 0x00ff00ff);
}
// AlphaMultiply from 32bpp ARGB
VOID FASTCALL
ScanOperation::AlphaMultiply_sRGB(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, ARGB)
while (count--)
{
sRGB::sRGBColor c;
c.argb = *s;
ARGB alpha = c.argb & 0xff000000;
if (alpha != 0xff000000)
{
if (alpha != 0x00000000)
{
c.argb = MyPremultiply(c.argb);
}
else
{
c.argb = 0;
}
}
*d = c.argb;
d++;
s++;
}
}
// !!![agodfrey] We may want to round off, in both AlphaDivide_sRGB64 and
// AlphaMultiply_sRGB64.
// AlphaDivide from 64bpp PARGB
VOID FASTCALL
ScanOperation::AlphaDivide_sRGB64(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB64, ARGB64)
while (count--)
{
using namespace sRGB;
sRGB64Color c;
c.argb = *s;
if (isTranslucent64(c.a))
{
c.r = ((INT) c.r << SRGB_FRACTIONBITS) / c.a;
c.g = ((INT) c.g << SRGB_FRACTIONBITS) / c.a;
c.b = ((INT) c.b << SRGB_FRACTIONBITS) / c.a;
}
*d = c.argb;
d++;
s++;
}
}
// AlphaMultiply from 64bpp ARGB
VOID FASTCALL
ScanOperation::AlphaMultiply_sRGB64(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB64, ARGB64)
while (count--)
{
using namespace sRGB;
sRGB64Color c;
c.argb = *s;
if (c.a != SRGB_ONE)
{
if (c.a != 0)
{
c.r = ((INT) c.r * c.a) >> SRGB_FRACTIONBITS;
c.g = ((INT) c.g * c.a) >> SRGB_FRACTIONBITS;
c.b = ((INT) c.b * c.a) >> SRGB_FRACTIONBITS;
}
else
{
c.argb = 0;
}
}
*d = c.argb;
d++;
s++;
}
}