Commit b366cad5 authored by Halla Rempt's avatar Halla Rempt
Browse files

BUG:309384

This cleans up pigment by removing the old, unused and confusing
composite op implementations. It turns out that the new softlight
was already conforming to the W3C SVG definitions; but I added
a new softlight definition specially for importing photoshop documents.

See http://en.wikipedia.org/wiki/Blend_modes#Soft_Light for the
difference.
parent 149eaad6
......@@ -77,7 +77,7 @@ QString psd_blendmode_to_composite_op(const QString& blendmode)
if (blendmode == "scrn") return COMPOSITE_SCREEN; //screen
if (blendmode == "over") return COMPOSITE_OVERLAY; //overlay
if (blendmode == "hLit") return COMPOSITE_HARD_LIGHT; //hard light
if (blendmode == "sLit") return COMPOSITE_SOFT_LIGHT; //soft light
if (blendmode == "sLit") return COMPOSITE_SOFT_LIGHT_PHOTOSHOP; //soft light
if (blendmode == "diff") return COMPOSITE_DIFF; //difference
if (blendmode == "smud") return COMPOSITE_EXCLUSION; //exclusion
if (blendmode == "div ") return COMPOSITE_DIVIDE; // color dodge
......@@ -108,7 +108,8 @@ QString composite_op_to_psd_blendmode(const QString& compositeop)
if (compositeop == COMPOSITE_SCREEN) return "scrn"; //screen
if (compositeop == COMPOSITE_OVERLAY) return "over"; //overlay
if (compositeop == COMPOSITE_HARD_LIGHT) return "hLit"; //hard light
if (compositeop == COMPOSITE_SOFT_LIGHT) return "sLit"; //soft light
if (compositeop == COMPOSITE_SOFT_LIGHT_PHOTOSHOP) return "sLit"; //soft light
if (compositeop == COMPOSITE_SOFT_LIGHT_SVG) return "sLit"; //soft light
if (compositeop == COMPOSITE_DIFF) return "diff"; //difference
if (compositeop == COMPOSITE_EXCLUSION) return "smud"; //exclusion
if (compositeop == COMPOSITE_DIVIDE) return "div "; // color dodge
......
......@@ -135,7 +135,7 @@ void KisOpenRasterStackLoadVisitor::loadLayerInfo(const QDomElement& elem, KisLa
if (compop == "svg:color-dodge") layer->setCompositeOp(COMPOSITE_DODGE);
if (compop == "svg:color-burn") layer->setCompositeOp(COMPOSITE_BURN);
if (compop == "svg:hard-light") layer->setCompositeOp(COMPOSITE_HARD_LIGHT);
if (compop == "svg:soft-light") layer->setCompositeOp(COMPOSITE_SOFT_LIGHT);
if (compop == "svg:soft-light") layer->setCompositeOp(COMPOSITE_SOFT_LIGHT_SVG);
if (compop == "svg:difference") layer->setCompositeOp(COMPOSITE_DIFF);
if (compop == "difference") layer->setCompositeOp(COMPOSITE_DIFF); // to fix an old bug in krita's ora export
if (compop == "svg:color") layer->setCompositeOp(COMPOSITE_COLOR);
......
......@@ -78,7 +78,7 @@ void KisOpenRasterStackSaveVisitor::saveLayerInfo(QDomElement& elt, KisLayer* la
else if (layer->compositeOpId() == COMPOSITE_DODGE) compop = "color-dodge";
else if (layer->compositeOpId() == COMPOSITE_BURN) compop = "svg:color-burn";
else if (layer->compositeOpId() == COMPOSITE_HARD_LIGHT) compop = "svg:hard-light";
else if (layer->compositeOpId() == COMPOSITE_SOFT_LIGHT) compop = "svg:soft-light";
else if (layer->compositeOpId() == COMPOSITE_SOFT_LIGHT_SVG) compop = "svg:soft-light";
else if (layer->compositeOpId() == COMPOSITE_DIFF) compop = "svg:difference";
else if (layer->compositeOpId() == COMPOSITE_COLOR) compop = "svg:color";
else if (layer->compositeOpId() == COMPOSITE_LUMINIZE) compop = "svg:luminosity";
......
......@@ -58,7 +58,8 @@ KoCompositeOpRegistry::KoCompositeOpRegistry()
m_map.insert(m_categories[2], KoID(COMPOSITE_PIN_LIGHT , i18n("Pin Light")));
m_map.insert(m_categories[2], KoID(COMPOSITE_VIVID_LIGHT , i18n("Vivid Light")));
m_map.insert(m_categories[2], KoID(COMPOSITE_HARD_LIGHT , i18n("Hard Light")));
m_map.insert(m_categories[2], KoID(COMPOSITE_SOFT_LIGHT , i18n("Soft Light")));
m_map.insert(m_categories[2], KoID(COMPOSITE_SOFT_LIGHT_PHOTOSHOP, i18n("Soft Light (Photoshop)")));
m_map.insert(m_categories[2], KoID(COMPOSITE_SOFT_LIGHT_SVG, i18n("Soft Light (SVG)")));
m_map.insert(m_categories[2], KoID(COMPOSITE_GAMMA_LIGHT , i18n("Gamma Light")));
m_map.insert(m_categories[3], KoID(COMPOSITE_DIFF , i18n("Difference")));
......
......@@ -71,7 +71,8 @@ const QString COMPOSITE_DODGE = "dodge";
const QString COMPOSITE_LINEAR_DODGE = "linear_dodge";
const QString COMPOSITE_SCREEN = "screen";
const QString COMPOSITE_HARD_LIGHT = "hard_light";
const QString COMPOSITE_SOFT_LIGHT = "soft_light";
const QString COMPOSITE_SOFT_LIGHT_PHOTOSHOP = "soft_light";
const QString COMPOSITE_SOFT_LIGHT_SVG = "soft_light_svg";
const QString COMPOSITE_GAMMA_LIGHT = "gamma_light";
const QString COMPOSITE_VIVID_LIGHT = "vivid_light";
const QString COMPOSITE_LINEAR_LIGHT = "linear light";
......
......@@ -23,15 +23,6 @@
#include "../compositeops/KoCompositeOpOver.h"
#include <KoColorSpaceTraits.h>
#include <KoCompositeOpAdd.h>
#include <KoCompositeOpBurn.h>
#include <KoCompositeOpDivide.h>
#include <KoCompositeOpDodge.h>
#include <KoCompositeOpInversedSubtract.h>
#include <KoCompositeOpMultiply.h>
#include <KoCompositeOpOverlay.h>
#include <KoCompositeOpScreen.h>
#include <KoCompositeOpSubtract.h>
const int TILE_WIDTH = 64;
const int TILE_HEIGHT = 64;
......@@ -84,14 +75,6 @@ void KoCompositeOpsBenchmark::benchmarkCompositeOver()
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeAdd()
{
KoCompositeOpAdd<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeAlphaDarken()
{
KoCompositeOpAlphaDarken<KoBgrU16Traits> compositeOp(0);
......@@ -100,69 +83,6 @@ void KoCompositeOpsBenchmark::benchmarkCompositeAlphaDarken()
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeBurn()
{
KoCompositeOpBurn<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeDivide()
{
KoCompositeOpDivide<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeDodge()
{
KoCompositeOpDodge<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeInversedSubtract()
{
KoCompositeOpInversedSubtract<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeMulitply()
{
KoCompositeOpMultiply<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeOverlay()
{
KoCompositeOpOverlay<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeScreen()
{
KoCompositeOpScreen<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
void KoCompositeOpsBenchmark::benchmarkCompositeSubtract()
{
KoCompositeOpSubtract<KoBgrU16Traits> compositeOp(0);
QBENCHMARK{
COMPOSITE_BENCHMARK
}
}
QTEST_KDEMAIN(KoCompositeOpsBenchmark, NoGUI)
#include "KoCompositeOpsBenchmark.moc"
......
......@@ -32,15 +32,6 @@ private slots:
void benchmarkCompositeOver();
void benchmarkCompositeAlphaDarken();
void benchmarkCompositeAdd();
void benchmarkCompositeBurn();
void benchmarkCompositeDivide();
void benchmarkCompositeDodge();
void benchmarkCompositeInversedSubtract();
void benchmarkCompositeMulitply();
void benchmarkCompositeOverlay();
void benchmarkCompositeScreen();
void benchmarkCompositeSubtract();
private:
quint8 * m_dstBuffer;
......
/*
* Copyright (c) 2008 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOCOMPOSITEOPADD_H_
#define KOCOMPOSITEOPADD_H_
#include "KoCompositeOpAlphaBase.h"
/**
* A template version of the divide composite operation to use in colorspaces.
*/
template<class _CSTraits>
class KoCompositeOpAdd : public KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpAdd<_CSTraits>, true >
{
typedef typename _CSTraits::channels_type channels_type;
typedef typename KoColorSpaceMathsTraits<typename _CSTraits::channels_type>::compositetype compositetype;
public:
KoCompositeOpAdd(const KoColorSpace * cs)
: KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpAdd<_CSTraits>, true >(cs, COMPOSITE_ADD, i18n("Add"), KoCompositeOp::categoryArithmetic()) {
}
public:
inline static channels_type selectAlpha(channels_type srcAlpha, channels_type dstAlpha) {
return qMin(srcAlpha, dstAlpha);
}
inline static void composeColorChannels(channels_type srcBlend,
const channels_type* src,
channels_type* dst,
bool allChannelFlags,
const QBitArray & channelFlags) {
for (uint i = 0; i < _CSTraits::channels_nb; i++) {
if ((int)i != _CSTraits::alpha_pos && (allChannelFlags || channelFlags.testBit(i))) {
compositetype srcColor = src[i];
compositetype dstColor = dst[i];
srcColor += dstColor;
srcColor = qMin(srcColor, (compositetype)NATIVE_MAX_VALUE);
dst[i] = KoColorSpaceMaths<channels_type>::blend(srcColor, dstColor, srcBlend);
}
}
}
};
#endif
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOCOMPOSITEOPBURN_H_
#define KOCOMPOSITEOPBURN_H_
#include "KoCompositeOpAlphaBase.h"
/**
* A template version of the burn composite operation to use in colorspaces.
*/
template<class _CSTraits>
class KoCompositeOpBurn : public KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpBurn<_CSTraits>, true >
{
typedef typename _CSTraits::channels_type channels_type;
typedef typename KoColorSpaceMathsTraits<channels_type>::compositetype composite_type;
public:
KoCompositeOpBurn(const KoColorSpace * cs)
: KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpBurn<_CSTraits>, true >(cs, COMPOSITE_BURN, i18n("Burn"), KoCompositeOp::categoryLight()) {
}
public:
inline static channels_type selectAlpha(channels_type srcAlpha, channels_type dstAlpha) {
return qMin(srcAlpha, dstAlpha);
}
inline static void composeColorChannels(channels_type srcBlend,
const channels_type* src,
channels_type* dst,
bool allChannelFlags,
const QBitArray & channelFlags) {
for (uint i = 0; i < _CSTraits::channels_nb; i++) {
if ((int)i != _CSTraits::alpha_pos && (allChannelFlags || channelFlags.testBit(i))) {
composite_type unitValue = KoColorSpaceMathsTraits<channels_type>::unitValue;
composite_type invDst = unitValue - dst[i];
if(src[i] != KoColorSpaceMathsTraits<channels_type>::zeroValue) {
composite_type result = unitValue - qMin<composite_type>(invDst * unitValue / src[i], unitValue);
dst[i] = KoColorSpaceMaths<channels_type>::blend(result, dst[i], srcBlend);
}
else {
//composite_type result = KoColorSpaceMathsTraits<channels_type>::zeroValue;
composite_type result = unitValue - qMin<composite_type>(invDst * unitValue, unitValue);
dst[i] = KoColorSpaceMaths<channels_type>::blend(result, dst[i], srcBlend);
}
}
}
}
};
#endif
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOCOMPOSITEOPDivide_H_
#define KOCOMPOSITEOPDivide_H_
#include "KoCompositeOpAlphaBase.h"
/**
* A template version of the divide composite operation to use in colorspaces.
*/
template<class _CSTraits>
class KoCompositeOpDivide : public KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpDivide<_CSTraits>, true >
{
typedef typename _CSTraits::channels_type channels_type;
typedef typename KoColorSpaceMathsTraits<typename _CSTraits::channels_type>::compositetype compositetype;
public:
KoCompositeOpDivide(const KoColorSpace * cs)
: KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpDivide<_CSTraits>, true >(cs, COMPOSITE_DIVIDE, i18n("Divide"), KoCompositeOp::categoryArithmetic()) {
}
public:
inline static channels_type selectAlpha(channels_type srcAlpha, channels_type dstAlpha) {
return qMin(srcAlpha, dstAlpha);
}
inline static void composeColorChannels(channels_type srcBlend,
const channels_type* src,
channels_type* dst,
bool allChannelFlags,
const QBitArray & channelFlags) {
for (uint i = 0; i < _CSTraits::channels_nb; i++) {
if ((int)i != _CSTraits::alpha_pos && (allChannelFlags || channelFlags.testBit(i))) {
compositetype srcColor = src[i];
compositetype dstColor = dst[i];
srcColor = qMin((dstColor * (NATIVE_MAX_VALUE + 1) + (srcColor / 2)) / (1 + srcColor), (compositetype)NATIVE_MAX_VALUE);
dst[i] = KoColorSpaceMaths<channels_type>::blend(srcColor, dstColor, srcBlend);
}
}
}
};
#endif
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef _KOCOMPOSITEOPDODGE_H_
#define _KOCOMPOSITEOPDODGE_H_
#include "KoCompositeOpAlphaBase.h"
/**
* A template version of the dodge composite operation to use in colorspaces.
*/
template<class _CSTraits>
class KoCompositeOpDodge : public KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpDodge<_CSTraits>, true >
{
typedef typename _CSTraits::channels_type channels_type;
typedef typename KoColorSpaceMathsTraits<typename _CSTraits::channels_type>::compositetype compositetype;
public:
KoCompositeOpDodge(const KoColorSpace * cs)
: KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpDodge<_CSTraits>, true >(cs, COMPOSITE_DODGE, i18n("Dodge"), KoCompositeOp::categoryLight()) {
}
public:
inline static channels_type selectAlpha(channels_type srcAlpha, channels_type dstAlpha) {
return qMin(srcAlpha, dstAlpha);
}
inline static void composeColorChannels(channels_type srcBlend,
const channels_type* src,
channels_type* dst,
bool allChannelFlags,
const QBitArray & channelFlags) {
for (uint channel = 0; channel < _CSTraits::channels_nb; channel++) {
if ((int)channel != _CSTraits::alpha_pos && (allChannelFlags || channelFlags.testBit(channel))) {
compositetype srcColor = src[channel];
compositetype dstColor = dst[channel];
srcColor = qMin((compositetype)(dstColor * (NATIVE_MAX_VALUE + 1)) / (NATIVE_MAX_VALUE + 1 - srcColor), (compositetype)NATIVE_MAX_VALUE);
channels_type newColor = KoColorSpaceMaths<channels_type>::blend(srcColor, dstColor, srcBlend);
dst[channel] = newColor;
}
}
}
};
#endif
......@@ -177,6 +177,22 @@ inline T cfHardLight(T src, T dst) {
return clamp<T>(src2*dst / unitValue<T>());
}
template<class T>
inline T cfSoftLightSvg(T src, T dst) {
using namespace Arithmetic;
qreal fsrc = scale<qreal>(src);
qreal fdst = scale<qreal>(dst);
if(fsrc > 0.5f) {
qreal D = (fdst > 0.25f) ? sqrt(fdst) : ((16.0f*fdst - 12.0)*fdst + 4.0f)*fdst;
return scale<T>(fdst + (2.0f*fsrc - 1.0f) * (D - fdst));
}
return scale<T>(fdst - (1.0f - 2.0f * fsrc) * fdst * (1.0f - fdst));
}
template<class T>
inline T cfSoftLight(T src, T dst) {
using namespace Arithmetic;
......@@ -185,8 +201,7 @@ inline T cfSoftLight(T src, T dst) {
qreal fdst = scale<qreal>(dst);
if(fsrc > 0.5f) {
qreal D = (fdst > 0.25f) ? sqrt(fdst) : ((16.0f*fdst - 12.0)*fdst + 4.0f)*fdst;
return scale<T>(fdst + (2.0f*fsrc - 1.0f) * (D - fdst));
return scale<T>(fdst + (2.0f * fsrc - 1.0f) * (sqrt(fdst) - fdst));
}
return scale<T>(fdst - (1.0f - 2.0f*fsrc) * fdst * (1.0f - fdst));
......
/*
* Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
* Copyright (c) 2010 Boudewijn Rempt <boud@valdyas.org>
*
* This library is free hardware; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Hardware Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Hardware Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOCOMPOSITEOPHARDLIGHT_H_
#define KOCOMPOSITEOPHARDLIGHT_H_
#include "KoCompositeOpAlphaBase.h"
/**
* A template version of the hard light composite operation to use in colorspaces.
*/
template<class _CSTraits>
class KoCompositeOpHardlight : public KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpHardlight<_CSTraits>, true >
{
typedef typename _CSTraits::channels_type channels_type;
public:
KoCompositeOpHardlight(const KoColorSpace * cs)
: KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpHardlight<_CSTraits>, true >(cs, COMPOSITE_HARD_LIGHT, i18n("Hard light"), KoCompositeOp::categoryLight()) {
}
public:
inline static channels_type selectAlpha(channels_type srcAlpha, channels_type dstAlpha) {
return qMin(srcAlpha, dstAlpha);
}
inline static void composeColorChannels(channels_type srcBlend,
const channels_type* src,
channels_type* dst,
bool allChannelFlags,
const QBitArray & channelFlags) {
for (uint i = 0; i < _CSTraits::channels_nb; i++) {
if ((int)i != _CSTraits::alpha_pos && (allChannelFlags || channelFlags.testBit(i))) {
channels_type srcChannel = src[i];
channels_type dstChannel = dst[i];
if (srcChannel <= NATIVE_MAX_VALUE / 2) {
// Multiply
srcChannel = srcChannel * 2;
srcChannel = KoColorSpaceMaths<channels_type>::multiply(srcChannel, dstChannel);
dst[i] = KoColorSpaceMaths<channels_type>::blend(srcChannel, dstChannel, srcBlend);
}
else {
// Screen
srcChannel = 2 * srcChannel - NATIVE_MAX_VALUE;
srcChannel = NATIVE_MAX_VALUE - KoColorSpaceMaths<channels_type>::multiply(NATIVE_MAX_VALUE - dstChannel, NATIVE_MAX_VALUE - srcChannel);
dst[i] = KoColorSpaceMaths<channels_type>::blend(srcChannel, dstChannel, srcBlend);
}
}
}
}
};
#endif
/*
* Copyright (c) 2008 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOCOMPOSITEOPINVERSEDSUBTRACT_H_
#define KOCOMPOSITEOPINVERSEDSUBTRACT_H_
#include <QDebug>
#include "KoCompositeOpAlphaBase.h"
/**
* A template version of the subtract composite operation to use in colorspaces.
*/
template<class _CSTraits>
class KoCompositeOpInversedSubtract : public KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpInversedSubtract