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.
digikam/digikam/libs/dimg/dcolorblend.h

180 lines
4.1 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2006-03-01
* Description : DColor methods for blending
*
* Copyright (C) 2006-2007 by Marcel Wiesweg <marcel.wiesweg@gmx.de>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation;
* either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ============================================================ */
// Inspired by DirectFB, src/gfx/generic/generic.c:
/*
(c) Copyright 2000-2002 convergence integrated media GmbH <curanz@convergence.de>
(c) Copyright 2002-2005 convergence GmbH.
All rights reserved.
Written by Denis Oliver Kropp <dok@directfb.org>,
Andreas Hundt <andi@fischlustig.de>,
Sven Neumann <neo@directfb.org>,
Ville Syrjälä <syrjala@sci.fi> and
Claudio Ciccani <klan@users.sf.net>.
*/
#ifndef DCOLORBLEND_H
#define DCOLORBLEND_H
namespace Digikam
{
inline void DColor::premultiply()
{
if (sixteenBit())
premultiply16(alpha());
else
premultiply8(alpha());
}
inline void DColor::demultiply()
{
if (sixteenBit())
{
demultiply16(alpha());
blendClamp16();
}
else
{
demultiply8(alpha());
blendClamp8();
}
}
inline void DColor::blendZero()
{
setAlpha(0);
setRed(0);
setGreen(0);
setBlue(0);
}
inline void DColor::blendAlpha16(int alphaValue)
{
uint Sa = alphaValue + 1;
setRed ((Sa * (uint)red()) >> 16);
setGreen((Sa * (uint)green()) >> 16);
setBlue ((Sa * (uint)blue()) >> 16);
setAlpha((Sa * (uint)alpha()) >> 16);
}
inline void DColor::blendAlpha8(int alphaValue)
{
uint Sa = alphaValue + 1;
setRed ((Sa * red()) >> 8);
setGreen((Sa * green()) >> 8);
setBlue ((Sa * blue()) >> 8);
setAlpha((Sa * alpha()) >> 8);
}
inline void DColor::blendInvAlpha16(int alphaValue)
{
uint Sa = 65536 - alphaValue;
setRed ((Sa * (uint)red()) >> 16);
setGreen((Sa * (uint)green()) >> 16);
setBlue ((Sa * (uint)blue()) >> 16);
setAlpha((Sa * (uint)alpha()) >> 16);
}
inline void DColor::blendInvAlpha8(int alphaValue)
{
uint Sa = 256 - alphaValue;
setRed ((Sa * red()) >> 8);
setGreen((Sa * green()) >> 8);
setBlue ((Sa * blue()) >> 8);
setAlpha((Sa * alpha()) >> 8);
}
inline void DColor::premultiply16(int alphaValue)
{
uint Da = alphaValue + 1;
setRed ((Da * (uint)red()) >> 16);
setGreen((Da * (uint)green()) >> 16);
setBlue ((Da * (uint)blue()) >> 16);
}
inline void DColor::premultiply8(int alphaValue)
{
uint Da = alphaValue + 1;
setRed ((Da * red()) >> 8);
setGreen((Da * green()) >> 8);
setBlue ((Da * blue()) >> 8);
}
inline void DColor::demultiply16(int alphaValue)
{
uint Da = alphaValue + 1;
setRed (((uint)red() << 16) / Da);
setGreen(((uint)green() << 16) / Da);
setBlue (((uint)blue() << 16) / Da);
}
inline void DColor::demultiply8(int alphaValue)
{
uint Da = alphaValue + 1;
setRed ((red() << 8) / Da);
setGreen((green() << 8) / Da);
setBlue ((blue() << 8) / Da);
}
inline void DColor::blendAdd(const DColor &src)
{
setRed (red() + src.red());
setGreen(green() + src.green());
setBlue (blue() + src.blue());
setAlpha(alpha() + src.alpha());
}
inline void DColor::blendClamp16()
{
if (0xFFFF0000 & red()) setRed(65535);
if (0xFFFF0000 & green()) setGreen(65535);
if (0xFFFF0000 & blue()) setBlue(65535);
if (0xFFFF0000 & alpha()) setAlpha(65535);
}
inline void DColor::blendClamp8()
{
if (0xFF00 & red()) setRed(255);
if (0xFF00 & green()) setGreen(255);
if (0xFF00 & blue()) setBlue(255);
if (0xFF00 & alpha()) setAlpha(255);
}
} // namespace Digikam
#endif // DCOLORBLEND_H