[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