1 #ifndef _ofxsImageBlender_h_ 2 #define _ofxsImageBlender_h_ 3 4 #include "ofxsProcessing.H" 5 6 namespace OFX { 7 8 /** @brief Base class used to blend two images together */ 9 class ImageBlenderBase : public OFX::ImageProcessor { 10 protected : 11 const OFX::Image *_fromImg; // be this at 0 12 const OFX::Image *_toImg; // be this at 1 13 float _blend; // how much to blend 14 15 public : 16 /** @brief no arg ctor */ ImageBlenderBase(OFX::ImageEffect & instance)17 ImageBlenderBase(OFX::ImageEffect &instance) 18 : OFX::ImageProcessor(instance) 19 , _fromImg(NULL) 20 , _toImg(NULL) 21 , _blend(0.5f) 22 { 23 } 24 25 /** @brief set the src image */ setFromImg(const OFX::Image * v)26 void setFromImg(const OFX::Image *v) {_fromImg = v;} setToImg(const OFX::Image * v)27 void setToImg(const OFX::Image *v) {_toImg = v;} 28 29 /** @brief set the scale */ setBlend(float v)30 void setBlend(float v) {_blend = v;} 31 }; 32 33 /** @brief templated class to blend between two images */ 34 template <class PIX, int nComponents> 35 class ImageBlender : public ImageBlenderBase { 36 public : 37 // ctor ImageBlender(OFX::ImageEffect & instance)38 ImageBlender(OFX::ImageEffect &instance) 39 : ImageBlenderBase(instance) 40 {} 41 Lerp(const PIX & v1,const PIX & v2,float blend)42 static PIX Lerp(const PIX &v1, 43 const PIX &v2, 44 float blend) 45 { 46 return PIX((v2 - v1) * blend + v1); 47 } 48 49 // and do some processing multiThreadProcessImages(OfxRectI procWindow)50 void multiThreadProcessImages(OfxRectI procWindow) 51 { 52 float blend = _blend; 53 float blendComp = 1.0f - blend; 54 55 for(int y = procWindow.y1; y < procWindow.y2; y++) { 56 if(_effect.abort()) break; 57 58 PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); 59 60 for(int x = procWindow.x1; x < procWindow.x2; x++) { 61 62 PIX *fromPix = (PIX *) (_fromImg ? _fromImg->getPixelAddress(x, y) : 0); 63 PIX *toPix = (PIX *) (_toImg ? _toImg->getPixelAddress(x, y) : 0); 64 65 if(fromPix && toPix) { 66 for(int c = 0; c < nComponents; c++) 67 dstPix[c] = Lerp(fromPix[c], toPix[c], blend); 68 } 69 else if(fromPix) { 70 for(int c = 0; c < nComponents; c++) 71 dstPix[c] = PIX(fromPix[c] * blendComp); 72 } 73 else if(toPix) { 74 for(int c = 0; c < nComponents; c++) 75 dstPix[c] = PIX(toPix[c] * blend); 76 } 77 else { 78 for(int c = 0; c < nComponents; c++) 79 dstPix[c] = PIX(0); 80 } 81 82 dstPix += nComponents; 83 } 84 } 85 } 86 87 }; 88 89 }; 90 91 #endif 92 93 94