Files
oak-editor/third_party/openfx/Support/Plugins/include/ofxsImageBlender.H
T

96 lines
2.8 KiB
C++

#ifndef _ofxsImageBlender_h_
#define _ofxsImageBlender_h_
#include "ofxsProcessing.H"
namespace OFX {
/** @brief Base class used to blend two images together */
class ImageBlenderBase : public OFX::ImageProcessor {
protected :
const OFX::Image *_fromImg; // be this at 0
const OFX::Image *_toImg; // be this at 1
float _blend; // how much to blend
public :
/** @brief no arg ctor */
ImageBlenderBase(OFX::ImageEffect &instance)
: OFX::ImageProcessor(instance)
, _fromImg(0)
, _toImg(0)
, _blend(0.5f)
{
}
/** @brief set the src image */
void setFromImg(const OFX::Image *v) {_fromImg = v;}
void setToImg(const OFX::Image *v) {_toImg = v;}
/** @brief set the scale */
void setBlend(float v) {_blend = v;}
};
/** @brief templated class to blend between two images */
template <class PIX, int nComponents>
class ImageBlender : public ImageBlenderBase {
public :
// ctor
ImageBlender(OFX::ImageEffect &instance)
: ImageBlenderBase(instance)
{}
static PIX Lerp(const PIX &v1,
const PIX &v2,
float blend)
{
return PIX((v2 - v1) * blend + v1);
}
// and do some processing
void multiThreadProcessImages(OfxRectI procWindow)
{
float blend = _blend;
float blendComp = 1.0f - blend;
for(int y = procWindow.y1; y < procWindow.y2; y++) {
if(_effect.abort()) break;
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
for(int x = procWindow.x1; x < procWindow.x2; x++) {
PIX *fromPix = (PIX *) (_fromImg ? _fromImg->getPixelAddress(x, y) : 0);
PIX *toPix = (PIX *) (_toImg ? _toImg->getPixelAddress(x, y) : 0);
if(fromPix && toPix) {
for(int c = 0; c < nComponents; c++)
dstPix[c] = Lerp(fromPix[c], toPix[c], blend);
}
else if(fromPix) {
for(int c = 0; c < nComponents; c++)
dstPix[c] = PIX(fromPix[c] * blendComp);
}
else if(toPix) {
for(int c = 0; c < nComponents; c++)
dstPix[c] = PIX(toPix[c] * blend);
}
else {
for(int c = 0; c < nComponents; c++)
dstPix[c] = PIX(0);
}
dstPix += nComponents;
}
}
}
};
};
#endif