diff options
Diffstat (limited to 'src/libs/dimg/dcolorcomposer.cpp')
-rw-r--r-- | src/libs/dimg/dcolorcomposer.cpp | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/src/libs/dimg/dcolorcomposer.cpp b/src/libs/dimg/dcolorcomposer.cpp new file mode 100644 index 00000000..653dbab3 --- /dev/null +++ b/src/libs/dimg/dcolorcomposer.cpp @@ -0,0 +1,436 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-03-02 + * Description : DColor methods for composing + * + * Copyright (C) 2006-2007 by Marcel Wiesweg <[email protected]> + * + * 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. + * + * ============================================================ */ + +// Integer arithmetic inspired by DirectFB, +// src/gfx/generic/generic.c and src/display/idirectfbsurface.c: + +/* + (c) Copyright 2000-2002 convergence integrated media GmbH <[email protected]> + (c) Copyright 2002-2005 convergence GmbH. + + All rights reserved. + + Written by Denis Oliver Kropp <[email protected]>, + Andreas Hundt <[email protected]>, + Sven Neumann <[email protected]>, + Ville Syrj�l� <[email protected]> and + Claudio Ciccani <[email protected]>. + +*/ + +// C++ includes. + +#include <cmath> + +// Local includes. + +#include "dcolorcomposer.h" + +namespace Digikam +{ + +class DColorComposerPorterDuffNone : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffClear : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); + virtual void compose(DColor &dest, DColor src, MultiplicationFlags multiplicationFlags); +}; + +class DColorComposerPorterDuffSrc : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); + virtual void compose(DColor &dest, DColor src, MultiplicationFlags multiplicationFlags); +}; + +class DColorComposerPorterDuffSrcOver : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffDstOver : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffSrcIn : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffDstIn : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffSrcOut : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffDstOut : public DColorComposer +{ +public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffSrcAtop : public DColorComposer +{ + public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffDstAtop : public DColorComposer +{ + public: + virtual void compose(DColor &dest, DColor src); +}; + +class DColorComposerPorterDuffXor : public DColorComposer +{ + public: + virtual void compose(DColor &dest, DColor src); +}; + +// Porter-Duff None +// component = (source * sa + destination * (1-sa)) +// Src blending function Src Alpha +// Dst blending function Inv Src Alpha +void DColorComposerPorterDuffNone::compose(DColor &dest, DColor src) +{ + // preserve src alpha value for dest blending, + // src.alpha() will be changed after blending src + int sa = src.alpha(); + if (dest.sixteenBit()) + { + src.blendAlpha16(sa); + dest.blendInvAlpha16(sa); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendAlpha8(sa); + dest.blendInvAlpha8(sa); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Clear +// component = (source * 0 + destination * 0) +// Src blending function Zero +// Dst blending function Zero +void DColorComposerPorterDuffClear::compose(DColor &dest, DColor src) +{ + src.blendZero(); + dest.blendZero(); + dest.blendAdd(src); +} + +void DColorComposerPorterDuffClear::compose(DColor &dest, DColor src, MultiplicationFlags) +{ + // skip pre- and demultiplication + compose(dest, src); +} + +// Porter-Duff Src +// Normal Painter's algorithm +// component = (source * 1 + destination * 0) +// Src blending function One +// Dst blending function Zero +void DColorComposerPorterDuffSrc::compose(DColor &dest, DColor src) +{ + // src: no-op + dest.blendZero(); + dest.blendAdd(src); +} + +void DColorComposerPorterDuffSrc::compose(DColor &dest, DColor src, MultiplicationFlags) +{ + // skip pre- and demultiplication + compose(dest, src); +} + +// Porter-Duff Src Over +// component = (source * 1 + destination * (1-sa)) +// Src blending function One +// Dst blending function Inv Src Alpha +void DColorComposerPorterDuffSrcOver::compose(DColor &dest, DColor src) +{ + if (dest.sixteenBit()) + { + // src: no-op + dest.blendInvAlpha16(src.alpha()); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + // src: no-op + dest.blendInvAlpha8(src.alpha()); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Dst over +// component = (source * (1.0-da) + destination * 1) +// Src blending function Inv Dst Alpha +// Dst blending function One +void DColorComposerPorterDuffDstOver::compose(DColor &dest, DColor src) +{ + if (dest.sixteenBit()) + { + src.blendInvAlpha16(dest.alpha()); + // dest: no-op + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendInvAlpha8(dest.alpha()); + // dest: no-op + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Src In +// component = (source * da + destination * 0) +// Src blending function Dst Alpha +// Dst blending function Zero +void DColorComposerPorterDuffSrcIn::compose(DColor &dest, DColor src) +{ + if (dest.sixteenBit()) + { + src.blendAlpha16(dest.alpha()); + dest.blendZero(); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendAlpha8(dest.alpha()); + dest.blendZero(); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Dst In +// component = (source * 0 + destination * sa) +// Src blending function Zero +// Dst blending function Src Alpha +void DColorComposerPorterDuffDstIn::compose(DColor &dest, DColor src) +{ + int sa = src.alpha(); + if (dest.sixteenBit()) + { + src.blendZero(); + dest.blendAlpha16(sa); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendZero(); + dest.blendAlpha8(sa); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Src Out +// component = (source * (1-da) + destination * 0) +// Src blending function Inv Dst Alpha +// Dst blending function Zero +void DColorComposerPorterDuffSrcOut::compose(DColor &dest, DColor src) +{ + if (dest.sixteenBit()) + { + src.blendInvAlpha16(dest.alpha()); + dest.blendZero(); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendInvAlpha8(dest.alpha()); + dest.blendZero(); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Dst Out +// component = (source * 0 + destination * (1-sa)) +// Src blending function Zero +// Dst blending function Inv Src Alpha +void DColorComposerPorterDuffDstOut::compose(DColor &dest, DColor src) +{ + int sa = src.alpha(); + if (dest.sixteenBit()) + { + src.blendZero(); + dest.blendInvAlpha16(sa); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendZero(); + dest.blendInvAlpha8(sa); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Src Atop +// component = (source * da + destination * (1-sa)) +// Src blending function Dst Alpha +// Dst blending function Inv Src Alpha +void DColorComposerPorterDuffSrcAtop::compose(DColor &dest, DColor src) +{ + int sa = src.alpha(); + if (dest.sixteenBit()) + { + src.blendAlpha16(dest.alpha()); + dest.blendInvAlpha16(sa); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendAlpha8(dest.alpha()); + dest.blendInvAlpha8(sa); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Dst Atop +// component = (source * (1-da) + destination * sa) +// Src blending function Inv Dest Alpha +// Dst blending function Src Alpha +void DColorComposerPorterDuffDstAtop::compose(DColor &dest, DColor src) +{ + int sa = src.alpha(); + if (dest.sixteenBit()) + { + src.blendInvAlpha16(dest.alpha()); + dest.blendAlpha16(sa); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendInvAlpha8(dest.alpha()); + dest.blendInvAlpha8(sa); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// Porter-Duff Xor +// component = (source * (1-da) + destination * (1-sa)) +// Src blending function Inv Dst Alpha +// Dst blending function Inv Src Alpha +void DColorComposerPorterDuffXor::compose(DColor &dest, DColor src) +{ + int sa = src.alpha(); + if (dest.sixteenBit()) + { + src.blendInvAlpha16(dest.alpha()); + dest.blendInvAlpha16(sa); + dest.blendAdd(src); + dest.blendClamp16(); + } + else + { + src.blendInvAlpha8(dest.alpha()); + dest.blendInvAlpha8(sa); + dest.blendAdd(src); + dest.blendClamp8(); + } +} + +// ----------------------------------------------------------------------- + +void DColorComposer::compose(DColor &dest, DColor src, DColorComposer::MultiplicationFlags multiplicationFlags) +{ + if (multiplicationFlags & PremultiplySrc) + src.premultiply(); + if (multiplicationFlags & PremultiplyDst) + dest.premultiply(); + + compose(dest, src); + + if (multiplicationFlags & DemultiplyDst) + dest.demultiply(); +} + +DColorComposer *DColorComposer::getComposer(DColorComposer::CompositingOperation rule) +{ + switch(rule) + { + case PorterDuffNone: + return new DColorComposerPorterDuffNone; + case PorterDuffClear: + return new DColorComposerPorterDuffClear; + case PorterDuffSrc: + return new DColorComposerPorterDuffSrc; + case PorterDuffSrcOver: + return new DColorComposerPorterDuffSrcOver; + case PorterDuffDstOver: + return new DColorComposerPorterDuffDstOver; + case PorterDuffSrcIn: + return new DColorComposerPorterDuffSrcIn; + case PorterDuffDstIn: + return new DColorComposerPorterDuffDstIn; + case PorterDuffSrcOut: + return new DColorComposerPorterDuffSrcOut; + case PorterDuffDstOut: + return new DColorComposerPorterDuffDstOut; + case PorterDuffSrcAtop: + return new DColorComposerPorterDuffDstOut; + case PorterDuffDstAtop: + return new DColorComposerPorterDuffDstOut; + case PorterDuffXor: + return new DColorComposerPorterDuffDstOut; + } + return 0; +} + +} // namespace DigiKam |