[PATCH 11/15] Done a bit of cleanup and renaming.
Silvio Heinrich
plassy at web.de
Sun Jan 9 19:05:08 CET 2011
And The KoCompositeOpBase template class now has an own header file.
---
libs/pigment/compositeops/KoCompositeOpBase.h | 122 ++++++++++++++++
libs/pigment/compositeops/KoCompositeOpFunctions.h | 151 +-------------------
libs/pigment/compositeops/KoCompositeOpGeneric.h | 69 ++++++++-
libs/pigment/compositeops/KoCompositeOps.h | 5 +-
4 files changed, 190 insertions(+), 157 deletions(-)
create mode 100644 libs/pigment/compositeops/KoCompositeOpBase.h
diff --git a/libs/pigment/compositeops/KoCompositeOpBase.h b/libs/pigment/compositeops/KoCompositeOpBase.h
new file mode 100644
index 0000000..eaa672b
--- /dev/null
+++ b/libs/pigment/compositeops/KoCompositeOpBase.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy at web.de>
+ *
+ * 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 KOCOMPOSITEO_BASE_H_
+#define KOCOMPOSITEO_BASE_H_
+
+#include <KoCompositeOp.h>
+#include "KoCompositeOpFunctions.h"
+
+/**
+ * A template base class that can be used for most composite modes/ops
+ *
+ * @param _compositeOp this template parameter is a class that must be
+ * derived fom KoCompositeOpBase and must define the static member function
+ * template<bool alphaLocked, bool allChannelFlags>
+ * inline static channels_type composeColorChannels(
+ * const channels_type* src,
+ * channels_type srcAlpha,
+ * channels_type* dst,
+ * channels_type dstAlpha,
+ * channels_type opacity,
+ * const QBitArray& channelFlags
+ * )
+ *
+ * where channels_type is _CSTraits::channels_type
+ */
+template<class _CSTraits, class _compositeOp>
+class KoCompositeOpBase : public KoCompositeOp
+{
+ typedef typename _CSTraits::channels_type channels_type;
+ static const qint32 channels_nb = _CSTraits::channels_nb;
+ static const qint32 alpha_pos = _CSTraits::alpha_pos;
+
+public:
+
+ KoCompositeOpBase(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible)
+ : KoCompositeOp(cs, id, description, category, userVisible) { }
+
+private:
+ template<bool alphaLocked, bool allChannelFlags>
+ void genericComposite(quint8* dstRowStart , qint32 dstRowStride ,
+ const quint8* srcRowStart , qint32 srcRowStride ,
+ const quint8* maskRowStart, qint32 maskRowStride,
+ qint32 rows, qint32 cols, quint8 U8_opacity, const QBitArray& channelFlags) const {
+
+ qint32 srcInc = (srcRowStride == 0) ? 0 : channels_nb;
+ bool useMask = maskRowStart != 0;
+ channels_type unitValue = KoColorSpaceMathsTraits<channels_type>::unitValue;
+ channels_type opacity = KoColorSpaceMaths<quint8,channels_type>::scaleToA(U8_opacity);
+
+ for(; rows>0; --rows) {
+ const channels_type* src = reinterpret_cast<const channels_type*>(srcRowStart);
+ channels_type* dst = reinterpret_cast<channels_type*>(dstRowStart);
+ const quint8* mask = maskRowStart;
+
+ for(qint32 c=cols; c>0; --c) {
+ channels_type srcAlpha = (alpha_pos == -1) ? unitValue : src[alpha_pos];
+ channels_type dstAlpha = (alpha_pos == -1) ? unitValue : dst[alpha_pos];
+ channels_type blend = useMask ? mul(opacity, scale<channels_type>(*mask)) : opacity;
+
+ channels_type newDstAlpha = _compositeOp::template composeColorChannels<alphaLocked,allChannelFlags>(
+ src, srcAlpha, dst, dstAlpha, blend, channelFlags
+ );
+
+ if(alpha_pos != -1)
+ dst[alpha_pos] = alphaLocked ? dstAlpha : newDstAlpha;
+
+ src += srcInc;
+ dst += channels_nb;
+ ++mask;
+ }
+
+ srcRowStart += srcRowStride;
+ dstRowStart += dstRowStride;
+ maskRowStart += maskRowStride;
+ }
+ }
+
+public:
+ using KoCompositeOp::composite;
+
+ virtual void composite(quint8* dstRowStart , qint32 dstRowStride ,
+ const quint8* srcRowStart , qint32 srcRowStride ,
+ const quint8* maskRowStart, qint32 maskRowStride,
+ qint32 rows, qint32 cols, quint8 U8_opacity, const QBitArray& channelFlags) const {
+
+ const QBitArray& flags = channelFlags.isEmpty() ? QBitArray(channels_nb,true) : channelFlags;
+ bool allChannelFlags = channelFlags.isEmpty();
+ bool alphaLocked = (alpha_pos != -1) && !flags.testBit(alpha_pos);
+
+ if(alphaLocked) {
+ if(allChannelFlags)
+ genericComposite<true,true>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
+ else
+ genericComposite<true,false>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
+ }
+ else {
+ if(allChannelFlags)
+ genericComposite<false,true>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
+ else
+ genericComposite<false,false>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
+ }
+ }
+};
+
+#endif // KOCOMPOSITEO_BASE_H_
diff --git a/libs/pigment/compositeops/KoCompositeOpFunctions.h b/libs/pigment/compositeops/KoCompositeOpFunctions.h
index 417df68..7f1fa7a 100644
--- a/libs/pigment/compositeops/KoCompositeOpFunctions.h
+++ b/libs/pigment/compositeops/KoCompositeOpFunctions.h
@@ -17,12 +17,10 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef KOCOMPOSITEOPFUNCTIONS_H_
-#define KOCOMPOSITEOPFUNCTIONS_H_
+#ifndef KOCOMPOSITEOP_FUNCTIONS_H_
+#define KOCOMPOSITEOP_FUNCTIONS_H_
#include <KoColorSpaceMaths.h>
-#include <KoColorSpaceConstants.h>
-#include <KoCompositeOp.h>
/* --------------------- Arithmetic functions ----------------------------- /
* definitions of standard arithmetic functions. all computations are meant
@@ -407,147 +405,4 @@ inline T cfDarkenOnly(T src, T dst) { return qMin(src, dst); }
template<class T>
inline T cfLightenOnly(T src, T dst) { return qMax(src, dst); }
-/**
- * A template base class that can be used for most composite modes/ops
- *
- * @param _compositeOp this template parameter is a class that must be
- * derived fom KoCompositeOpBase and must define the static member function
- * template<bool alphaLocked, bool allChannelFlags>
- * inline static channels_type composeColorChannels(
- * const channels_type* src,
- * channels_type srcAlpha,
- * channels_type* dst,
- * channels_type dstAlpha,
- * channels_type opacity,
- * const QBitArray& channelFlags
- * )
- *
- * where channels_type is _CSTraits::channels_type
- */
-template<class _CSTraits, class _compositeOp>
-class KoCompositeOpBase : public KoCompositeOp
-{
- typedef typename _CSTraits::channels_type channels_type;
- static const qint32 channels_nb = _CSTraits::channels_nb;
- static const qint32 alpha_pos = _CSTraits::alpha_pos;
-
-public:
-
- KoCompositeOpBase(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible)
- : KoCompositeOp(cs, id, description, category, userVisible) { }
-
-private:
- template<bool alphaLocked, bool allChannelFlags>
- void genericComposite(quint8* dstRowStart , qint32 dstRowStride ,
- const quint8* srcRowStart , qint32 srcRowStride ,
- const quint8* maskRowStart, qint32 maskRowStride,
- qint32 rows, qint32 cols, quint8 U8_opacity, const QBitArray& channelFlags) const {
-
- qint32 srcInc = (srcRowStride == 0) ? 0 : channels_nb;
- bool useMask = maskRowStart != 0;
- channels_type unitValue = KoColorSpaceMathsTraits<channels_type>::unitValue;
- channels_type opacity = KoColorSpaceMaths<quint8,channels_type>::scaleToA(U8_opacity);
-
- for(; rows>0; --rows) {
- const channels_type* src = reinterpret_cast<const channels_type*>(srcRowStart);
- channels_type* dst = reinterpret_cast<channels_type*>(dstRowStart);
- const quint8* mask = maskRowStart;
-
- for(qint32 c=cols; c>0; --c) {
- channels_type srcAlpha = (alpha_pos == -1) ? unitValue : src[alpha_pos];
- channels_type dstAlpha = (alpha_pos == -1) ? unitValue : dst[alpha_pos];
- channels_type blend = useMask ? mul(opacity, scale<channels_type>(*mask)) : opacity;
-
- channels_type newDstAlpha = _compositeOp::template composeColorChannels<alphaLocked,allChannelFlags>(
- src, srcAlpha, dst, dstAlpha, blend, channelFlags
- );
-
- if(alpha_pos != -1)
- dst[alpha_pos] = alphaLocked ? dstAlpha : newDstAlpha;
-
- src += srcInc;
- dst += channels_nb;
- ++mask;
- }
-
- srcRowStart += srcRowStride;
- dstRowStart += dstRowStride;
- maskRowStart += maskRowStride;
- }
- }
-
-public:
- using KoCompositeOp::composite;
-
- virtual void composite(quint8* dstRowStart , qint32 dstRowStride ,
- const quint8* srcRowStart , qint32 srcRowStride ,
- const quint8* maskRowStart, qint32 maskRowStride,
- qint32 rows, qint32 cols, quint8 U8_opacity, const QBitArray& channelFlags) const {
-
- const QBitArray& flags = channelFlags.isEmpty() ? QBitArray(channels_nb,true) : channelFlags;
- bool allChannelFlags = channelFlags.isEmpty();
- bool alphaLocked = (alpha_pos != -1) && !flags.testBit(alpha_pos);
-
- if(alphaLocked) {
- if(allChannelFlags)
- genericComposite<true,true>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
- else
- genericComposite<true,false>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
- }
- else {
- if(allChannelFlags)
- genericComposite<false,true>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
- else
- genericComposite<false,false>(dstRowStart, dstRowStride, srcRowStart, srcRowStride, maskRowStart, maskRowStride, rows, cols, U8_opacity, flags);
- }
- }
-};
-
-
-
-
-
-template<class Traits, void compositeFunc(float, float, float, float&, float&, float&)>
-class KoCompositeOpGenericLum : public KoCompositeOpBase< Traits, KoCompositeOpGenericLum<Traits,compositeFunc> >
-{
- typedef KoCompositeOpBase< Traits, KoCompositeOpGenericLum<Traits,compositeFunc> > base_class;
- typedef typename Traits::channels_type channels_type;
-
- static const qint32 red_pos = Traits::red_pos;
- static const qint32 green_pos = Traits::green_pos;
- static const qint32 blue_pos = Traits::blue_pos;
-
-public:
- KoCompositeOpGenericLum(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true)
- : base_class(cs, id, description, category, userVisible) { }
-
-public:
- template<bool alphaLocked, bool allChannelFlags>
- inline static channels_type composeColorChannels(const channels_type* src, channels_type srcAlpha,
- channels_type* dst, channels_type dstAlpha,
- channels_type opacity, const QBitArray& channelFlags) {
- Q_UNUSED(channelFlags);
-
- srcAlpha = mul(srcAlpha, opacity);
- channels_type newDstAlpha = unionShapeOpacy(srcAlpha, dstAlpha);
-
- if(newDstAlpha != KoColorSpaceMathsTraits<channels_type>::zeroValue) {
- float srcR = scale<float>(src[red_pos]);
- float srcG = scale<float>(src[green_pos]);
- float srcB = scale<float>(src[blue_pos]);
-
- float dstR = scale<float>(dst[red_pos]);
- float dstG = scale<float>(dst[green_pos]);
- float dstB = scale<float>(dst[blue_pos]);
-
- compositeFunc(srcR, srcG, srcB, dstR, dstG, dstB);
- dst[red_pos] = div(blend(src[red_pos] , srcAlpha, dst[red_pos] , dstAlpha, scale<channels_type>(dstR)), newDstAlpha);
- dst[green_pos] = div(blend(src[green_pos], srcAlpha, dst[green_pos], dstAlpha, scale<channels_type>(dstG)), newDstAlpha);
- dst[blue_pos] = div(blend(src[blue_pos] , srcAlpha, dst[blue_pos] , dstAlpha, scale<channels_type>(dstB)), newDstAlpha);
- }
-
- return newDstAlpha;
- }
-};
-
-#endif // KOCOMPOSITEOPFUNCTIONS_H_
+#endif // KOCOMPOSITEOP_FUNCTIONS_H_
diff --git a/libs/pigment/compositeops/KoCompositeOpGeneric.h b/libs/pigment/compositeops/KoCompositeOpGeneric.h
index 6a03e6b..308cc0a 100644
--- a/libs/pigment/compositeops/KoCompositeOpGeneric.h
+++ b/libs/pigment/compositeops/KoCompositeOpGeneric.h
@@ -21,25 +21,30 @@
#define _KOCOMPOSITEO_GENERIC_H_
#include "KoCompositeOpFunctions.h"
+#include "KoCompositeOpBase.h"
/**
- * A template version of the burn composite operation to use in colorspaces.
+ * Generic CompositeOp for separable channel compositing functions
+ *
+ * A template to generate a KoCompositeOp class by just specifying a
+ * blending/compositing function. This template works with compositing functions
+ * for separable channels (means each channel of a pixel can be processed separately)
*/
template<
class Traits,
typename Traits::channels_type compositeFunc(typename Traits::channels_type, typename Traits::channels_type)
>
-class KoCompositeOpGeneric : public KoCompositeOpBase< Traits, KoCompositeOpGeneric<Traits,compositeFunc> >
+class KoCompositeOpGenericSC: public KoCompositeOpBase< Traits, KoCompositeOpGenericSC<Traits,compositeFunc> >
{
- typedef KoCompositeOpBase< Traits, KoCompositeOpGeneric<Traits,compositeFunc> > base_class;
- typedef typename Traits::channels_type channels_type;
- typedef typename KoColorSpaceMathsTraits<channels_type>::compositetype composite_type;
+ typedef KoCompositeOpBase< Traits, KoCompositeOpGenericSC<Traits,compositeFunc> > base_class;
+ typedef typename Traits::channels_type channels_type;
+ typedef typename KoColorSpaceMathsTraits<channels_type>::compositetype composite_type;
static const qint32 channels_nb = Traits::channels_nb;
static const qint32 alpha_pos = Traits::alpha_pos;
public:
- KoCompositeOpGeneric(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true)
+ KoCompositeOpGenericSC(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true)
: base_class(cs, id, description, category, userVisible) { }
public:
@@ -63,4 +68,56 @@ public:
}
};
+
+/**
+ * Generic CompositeOp for nonseparable/HSL channel compositing functions
+ *
+ * A template to generate a KoCompositeOp class by just specifying a
+ * blending/compositing function. This template works with compositing functions
+ * for RGB channels only (the channels can not be processed separately)
+ */
+template<class Traits, void compositeFunc(float, float, float, float&, float&, float&)>
+class KoCompositeOpGenericHSL: public KoCompositeOpBase< Traits, KoCompositeOpGenericHSL<Traits,compositeFunc> >
+{
+ typedef KoCompositeOpBase< Traits, KoCompositeOpGenericHSL<Traits,compositeFunc> > base_class;
+ typedef typename Traits::channels_type channels_type;
+
+ static const qint32 red_pos = Traits::red_pos;
+ static const qint32 green_pos = Traits::green_pos;
+ static const qint32 blue_pos = Traits::blue_pos;
+
+public:
+ KoCompositeOpGenericHSL(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true)
+ : base_class(cs, id, description, category, userVisible) { }
+
+public:
+ template<bool alphaLocked, bool allChannelFlags>
+ inline static channels_type composeColorChannels(const channels_type* src, channels_type srcAlpha,
+ channels_type* dst, channels_type dstAlpha,
+ channels_type opacity, const QBitArray& channelFlags) {
+ Q_UNUSED(channelFlags);
+
+ srcAlpha = mul(srcAlpha, opacity);
+ channels_type newDstAlpha = unionShapeOpacy(srcAlpha, dstAlpha);
+
+ if(newDstAlpha != KoColorSpaceMathsTraits<channels_type>::zeroValue) {
+ float srcR = scale<float>(src[red_pos]);
+ float srcG = scale<float>(src[green_pos]);
+ float srcB = scale<float>(src[blue_pos]);
+
+ float dstR = scale<float>(dst[red_pos]);
+ float dstG = scale<float>(dst[green_pos]);
+ float dstB = scale<float>(dst[blue_pos]);
+
+ compositeFunc(srcR, srcG, srcB, dstR, dstG, dstB);
+
+ dst[red_pos] = div(blend(src[red_pos] , srcAlpha, dst[red_pos] , dstAlpha, scale<channels_type>(dstR)), newDstAlpha);
+ dst[green_pos] = div(blend(src[green_pos], srcAlpha, dst[green_pos], dstAlpha, scale<channels_type>(dstG)), newDstAlpha);
+ dst[blue_pos] = div(blend(src[blue_pos] , srcAlpha, dst[blue_pos] , dstAlpha, scale<channels_type>(dstB)), newDstAlpha);
+ }
+
+ return newDstAlpha;
+ }
+};
+
#endif // _KOCOMPOSITEO_GENERIC_H_
diff --git a/libs/pigment/compositeops/KoCompositeOps.h b/libs/pigment/compositeops/KoCompositeOps.h
index d553128..d00f2d1 100644
--- a/libs/pigment/compositeops/KoCompositeOps.h
+++ b/libs/pigment/compositeops/KoCompositeOps.h
@@ -26,7 +26,6 @@
#include "KoColorSpace.h"
#include "KoColorSpaceTraits.h"
-#include "compositeops/KoCompositeOpFunctions.h"
#include "compositeops/KoCompositeOpGeneric.h"
#include "compositeops/KoCompositeOpAlphaDarken.h"
#include "compositeops/KoCompositeOpErase.h"
@@ -60,7 +59,7 @@ struct AddGeneralOps<Traits, true>
template<Arg compositeFunc(Arg, Arg)>
static void add(KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true) {
- cs->addCompositeOp(new KoCompositeOpGeneric<Traits, compositeFunc>(cs, id, description, category, userVisible));
+ cs->addCompositeOp(new KoCompositeOpGenericSC<Traits, compositeFunc>(cs, id, description, category, userVisible));
}
static void add(KoColorSpace* cs) {
@@ -115,7 +114,7 @@ struct AddHSLOps<Traits, true>
template<void compositeFunc(Arg, Arg, Arg, Arg&, Arg&, Arg&)>
static void add(KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true) {
- cs->addCompositeOp(new KoCompositeOpGenericLum<Traits, compositeFunc>(cs, id, description, category, userVisible));
+ cs->addCompositeOp(new KoCompositeOpGenericHSL<Traits, compositeFunc>(cs, id, description, category, userVisible));
}
static void add(KoColorSpace* cs) {
--
1.7.1
More information about the kimageshop
mailing list