[PATCH 06/15] Added "Soft Light", "Hard Light" and "Overlay" blending functions.
Silvio Heinrich
plassy at web.de
Sat Jan 8 16:10:09 CET 2011
---
libs/pigment/KoColorSpaceMaths.cpp | 3 +
libs/pigment/KoColorSpaceMaths.h | 7 ++
libs/pigment/compositeops/KoCompositeOpFunctions.h | 70 +++++++++++++++-----
libs/pigment/compositeops/KoCompositeOps.h | 47 +++++++------
4 files changed, 88 insertions(+), 39 deletions(-)
diff --git a/libs/pigment/KoColorSpaceMaths.cpp b/libs/pigment/KoColorSpaceMaths.cpp
index 891c8a2..b2f82ed 100644
--- a/libs/pigment/KoColorSpaceMaths.cpp
+++ b/libs/pigment/KoColorSpaceMaths.cpp
@@ -26,6 +26,7 @@
#ifdef HAVE_OPENEXR
const half KoColorSpaceMathsTraits<half>::zeroValue = 0.0;
const half KoColorSpaceMathsTraits<half>::unitValue = 1.0;
+const half KoColorSpaceMathsTraits<half>::halfValue = 0.5;
const half KoColorSpaceMathsTraits<half>::max = HALF_MAX;
const half KoColorSpaceMathsTraits<half>::min = -HALF_MAX;
const half KoColorSpaceMathsTraits<half>::epsilon = HALF_EPSILON;
@@ -34,6 +35,7 @@ const KoChannelInfo::enumChannelValueType KoColorSpaceMathsTraits<half>::channel
const float KoColorSpaceMathsTraits<float>::zeroValue = 0.0;
const float KoColorSpaceMathsTraits<float>::unitValue = 1.0;
+const float KoColorSpaceMathsTraits<float>::halfValue = 0.5;
const float KoColorSpaceMathsTraits<float>::max = FLT_MAX;
const float KoColorSpaceMathsTraits<float>::min = -FLT_MAX;
const float KoColorSpaceMathsTraits<float>::epsilon = FLT_EPSILON;
@@ -41,6 +43,7 @@ const KoChannelInfo::enumChannelValueType KoColorSpaceMathsTraits<float>::channe
const double KoColorSpaceMathsTraits<double>::zeroValue = 0.0;
const double KoColorSpaceMathsTraits<double>::unitValue = 1.0;
+const double KoColorSpaceMathsTraits<double>::halfValue = 0.5;
const double KoColorSpaceMathsTraits<double>::max = DBL_MAX;
const double KoColorSpaceMathsTraits<double>::min = -DBL_MAX;
const double KoColorSpaceMathsTraits<double>::epsilon = DBL_EPSILON;
diff --git a/libs/pigment/KoColorSpaceMaths.h b/libs/pigment/KoColorSpaceMaths.h
index a0ba9cf..f577a7d 100644
--- a/libs/pigment/KoColorSpaceMaths.h
+++ b/libs/pigment/KoColorSpaceMaths.h
@@ -56,6 +56,7 @@ public:
typedef qint32 compositetype;
static const quint8 zeroValue = 0;
static const quint8 unitValue = 0x00FF;
+ static const quint8 halfValue = 0x00FF / 2;
static const quint8 max = 0x00FF;
static const quint8 min = 0;
static const quint8 epsilon = 1;
@@ -70,6 +71,7 @@ public:
typedef qint64 compositetype;
static const quint16 zeroValue = 0;
static const quint16 unitValue = 0xFFFF;
+ static const quint16 halfValue = 0xFFFF / 2;
static const quint16 max = 0xFFFF;
static const quint16 min = 0;
static const quint16 epsilon = 1;
@@ -84,6 +86,7 @@ public:
typedef qint64 compositetype;
static const qint16 zeroValue = 0;
static const qint16 unitValue = 32767;
+ static const qint16 halfValue = 32767 / 2;
static const qint16 max = 32767;
static const qint16 min = -32768;
static const qint16 epsilon = 1;
@@ -98,6 +101,7 @@ public:
typedef qint64 compositetype;
static const quint32 zeroValue = 0;
static const quint32 unitValue = 0xFFFFFFFF;
+ static const quint32 halfValue = 0xFFFFFFFF / 2;
static const quint32 max = 0xFFFFFFFF;
static const quint32 min = 0;
static const quint32 epsilon = 1;
@@ -116,6 +120,7 @@ public:
typedef double compositetype;
static const half zeroValue;
static const half unitValue;
+ static const half halfValue;
static const half max;
static const half min;
static const half epsilon;
@@ -131,6 +136,7 @@ public:
typedef double compositetype;
static const float zeroValue;
static const float unitValue;
+ static const float halfValue;
static const float max;
static const float min;
static const float epsilon;
@@ -145,6 +151,7 @@ public:
typedef double compositetype;
static const double zeroValue;
static const double unitValue;
+ static const double halfValue;
static const double max;
static const double min;
static const double epsilon;
diff --git a/libs/pigment/compositeops/KoCompositeOpFunctions.h b/libs/pigment/compositeops/KoCompositeOpFunctions.h
index 0656fa5..de41921 100644
--- a/libs/pigment/compositeops/KoCompositeOpFunctions.h
+++ b/libs/pigment/compositeops/KoCompositeOpFunctions.h
@@ -30,10 +30,16 @@
* if non floating point types are used, fixed point arithmetic is used
*/
+// template<class T>
+// inline T mul(T a, T b) { T(KoColorSpaceMaths<T>::multiply(a, b)); }
+
+// template<class T>
+// inline T mul(T a, T b, T c) { T(KoColorSpaceMaths<T>::multiply(a, b, c)); }
+
template<class T>
inline T mul(T a, T b) {
typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
- return T(composite_type(a) * composite_type(b) / KoColorSpaceMathsTraits<T>::unitValue);
+ return T(composite_type(a) * b / KoColorSpaceMathsTraits<T>::unitValue);
}
template<class T>
@@ -43,6 +49,21 @@ inline T mul(T a, T b, T c) {
}
template<class T>
+inline T inv(T a) { return KoColorSpaceMathsTraits<T>::unitValue - a; }
+
+template<class T>
+inline T lerp(T a, T b, T alpha) { return KoColorSpaceMaths<T>::blend(b, a, alpha); }
+
+template<class TRet, class T>
+inline TRet scale(T a) { return KoColorSpaceMaths<T,TRet>::scaleToA(a); }
+
+// template<class TRet, class T>
+// inline TRet scale(T a) {
+// typedef typename KoColorSpaceMathsTraits<TRet>::compositetype composite_type;
+// return TRet(composite_type(a) * KoColorSpaceMathsTraits<TRet>::unitValue / KoColorSpaceMathsTraits<T>::unitValue);
+// }
+
+template<class T>
inline typename KoColorSpaceMathsTraits<T>::compositetype
div(T a, T b) {
typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
@@ -50,27 +71,11 @@ div(T a, T b) {
}
template<class T>
-inline T inv(T a) {
- return KoColorSpaceMathsTraits<T>::unitValue - a;
-}
-
-template<class T>
inline T clamp(typename KoColorSpaceMathsTraits<T>::compositetype a) {
typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
return qBound<composite_type>(KoColorSpaceMathsTraits<T>::zeroValue, a, KoColorSpaceMathsTraits<T>::unitValue);
}
-template<class T>
-inline T lerp(T a, T b, T alpha) {
- return KoColorSpaceMaths<T>::blend(b, a, alpha);
-}
-
-template<class TRet, class T>
-inline TRet scale(T a) {
- typedef typename KoColorSpaceMathsTraits<TRet>::compositetype composite_type;
- return TRet(composite_type(a) * KoColorSpaceMathsTraits<TRet>::unitValue / KoColorSpaceMathsTraits<T>::unitValue);
-}
-
/* ---------------- Blending/Compositing functions ------------------------ /
* definitions of standard blending/compositing functions compatible
* to the ISO 32000-1 specification (for PDF filed) which also defines
@@ -136,9 +141,40 @@ inline T cfDivide(T src, T dst) {
}
template<class T>
+inline T cfHardLight(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ composite_type src2 = composite_type(src) + src;
+
+ if(src > KoColorSpaceMathsTraits<T>::halfValue) {
+ // screen(src*2.0 - 1.0, dst)
+ src2 -= KoColorSpaceMathsTraits<T>::unitValue;
+ return T((src2+dst) - (src2*dst / KoColorSpaceMathsTraits<T>::unitValue));
+ }
+
+ // multiply(src*2.0, dst)
+ return clamp<T>(src2*dst / KoColorSpaceMathsTraits<T>::unitValue);
+}
+
+template<class T>
+inline T cfSoftLight(T src, T dst) {
+ 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 cfOver(T src, T dst) { Q_UNUSED(dst); return src; }
template<class T>
+inline T cfOverlay(T src, T dst) { return cfHardLight(dst, src); }
+
+template<class T>
inline T cfMultiply(T src, T dst) { return mul(src, dst); }
template<class T>
diff --git a/libs/pigment/compositeops/KoCompositeOps.h b/libs/pigment/compositeops/KoCompositeOps.h
index b662f3a..b563261 100644
--- a/libs/pigment/compositeops/KoCompositeOps.h
+++ b/libs/pigment/compositeops/KoCompositeOps.h
@@ -26,17 +26,17 @@
// #include "compositeops/KoCompositeOpAdd.h"
#include "compositeops/KoCompositeOpAlphaDarken.h"
// #include "compositeops/KoCompositeOpBurn.h"
-#include "compositeops/KoCompositeOpDivide.h"
+// #include "compositeops/KoCompositeOpDivide.h"
// #include "compositeops/KoCompositeOpDodge.h"
#include "compositeops/KoCompositeOpErase.h"
// #include "compositeops/KoCompositeOpMultiply.h"
// #include "compositeops/KoCompositeOpOver.h"
-#include "compositeops/KoCompositeOpOverlay.h"
+// #include "compositeops/KoCompositeOpOverlay.h"
// #include "compositeops/KoCompositeOpScreen.h"
// #include "compositeops/KoCompositeOpSubtract.h"
-#include "compositeops/KoCompositeOpInversedSubtract.h"
-#include "compositeops/KoCompositeOpSoftlight.h"
-#include "compositeops/KoCompositeOpHardlight.h"
+// #include "compositeops/KoCompositeOpInversedSubtract.h"
+// #include "compositeops/KoCompositeOpSoftlight.h"
+// #include "compositeops/KoCompositeOpHardlight.h"
#include "compositeops/KoCompositeOpCopy2.h"
#include "compositeops/KoCompositeOpGeneric.h"
@@ -59,26 +59,29 @@ void addStandardCompositeOps(KoColorSpace* cs)
//cs->addCompositeOp(new KoCompositeOpOverlay<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpScreen<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpSubtract<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpSoftlight<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpHardlight<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpSoftlight<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpHardlight<_Traits_>(cs));
- typedef typename _Traits_::channels_type type;
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfOver <type> >(cs, COMPOSITE_OVER, i18n("Normal"), KoCompositeOp::categoryMix()));
+ typedef typename _Traits_::channels_type T;
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfOver<T> >(cs, COMPOSITE_OVER, i18n("Normal"), KoCompositeOp::categoryMix()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorBurn <type> >(cs, COMPOSITE_BURN , i18n("Color Burn"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorDodge <type> >(cs, COMPOSITE_DODGE , i18n("Color Dodge"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLinearBurn <type> >(cs, COMPOSITE_LINEAR_BURN , i18n("Linear Burn"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition <type> >(cs, COMPOSITE_LINEAR_DODGE, i18n("Linear Dodge"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDarkenOnly <type> >(cs, COMPOSITE_DARKEN , i18n("Darken"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLightenOnly<type> >(cs, COMPOSITE_LIGHTEN , i18n("Lighten"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorBurn<T> >(cs, COMPOSITE_BURN , i18n("Color Burn"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorDodge<T> >(cs, COMPOSITE_DODGE , i18n("Color Dodge"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLinearBurn<T> >(cs, COMPOSITE_LINEAR_BURN , i18n("Linear Burn"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition<T> >(cs, COMPOSITE_LINEAR_DODGE, i18n("Linear Dodge"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDarkenOnly<T> >(cs, COMPOSITE_DARKEN , i18n("Darken"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLightenOnly<T> >(cs, COMPOSITE_LIGHTEN , i18n("Lighten"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfHardLight<T> >(cs, COMPOSITE_HARD_LIGHT , i18n("Hard Light"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfSoftLight<T> >(cs, COMPOSITE_SOFT_LIGHT , i18n("Soft Light"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition <type> >(cs, COMPOSITE_ADD , i18n("Addition"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfSubtract <type> >(cs, COMPOSITE_SUBTRACT , i18n("Subtract"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDifference<type> >(cs, COMPOSITE_DIFF , i18n("Difference"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfMultiply <type> >(cs, COMPOSITE_MULT , i18n("Multiply"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDivide <type> >(cs, COMPOSITE_DIVIDE , i18n("Divide"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfExclusion <type> >(cs, COMPOSITE_EXCLUSION, i18n("Exclusion"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfScreen <type> >(cs, COMPOSITE_SCREEN , i18n("Screen"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfScreen<T> >(cs, COMPOSITE_SCREEN , i18n("Screen"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfOverlay<T> >(cs, COMPOSITE_OVERLAY , i18n("Overlay"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition<T> >(cs, COMPOSITE_ADD , i18n("Addition"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfSubtract<T> >(cs, COMPOSITE_SUBTRACT , i18n("Subtract"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDifference<T> >(cs, COMPOSITE_DIFF , i18n("Difference"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfMultiply<T> >(cs, COMPOSITE_MULT , i18n("Multiply"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDivide<T> >(cs, COMPOSITE_DIVIDE , i18n("Divide"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfExclusion<T> >(cs, COMPOSITE_EXCLUSION, i18n("Exclusion"), KoCompositeOp::categoryArithmetic()));
}
#endif
--
1.7.1
More information about the kimageshop
mailing list