1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ 2 /* ***** BEGIN LICENSE BLOCK ***** 3 * This file is part of openfx-supportext <https://github.com/devernay/openfx-supportext>, 4 * Copyright (C) 2013-2018 INRIA 5 * 6 * openfx-supportext is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * openfx-supportext is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with openfx-supportext. If not, see <http://www.gnu.org/licenses/gpl-2.0.html> 18 * ***** END LICENSE BLOCK ***** */ 19 20 #ifndef openfx_supportext_ofxsImageBlenderMasked_h 21 #define openfx_supportext_ofxsImageBlenderMasked_h 22 23 #include "ofxsProcessing.H" 24 #include "ofxsMaskMix.h" 25 #include "ofxsImageBlender.H" 26 27 namespace OFX { 28 /** @brief Base class used to blend two images together */ 29 class ImageBlenderMaskedBase 30 : public ImageBlenderBase 31 { 32 protected: 33 bool _doMasking; 34 const OFX::Image *_maskImg; 35 bool _maskInvert; 36 37 public: 38 /** @brief no arg ctor */ ImageBlenderMaskedBase(OFX::ImageEffect & instance)39 ImageBlenderMaskedBase(OFX::ImageEffect &instance) 40 : ImageBlenderBase(instance) 41 , _doMasking(false) 42 , _maskImg(NULL) 43 , _maskInvert(false) 44 { 45 } 46 setMaskImg(const OFX::Image * v,bool maskInvert)47 void setMaskImg(const OFX::Image *v, 48 bool maskInvert) 49 { 50 _maskImg = v; _maskInvert = maskInvert; 51 } 52 doMasking(bool v)53 void doMasking(bool v) 54 { 55 _doMasking = v; 56 } 57 }; 58 59 /** @brief templated class to blend between two images */ 60 template <class PIX, int nComponents, int maxValue, bool masked> 61 class ImageBlenderMasked 62 : public ImageBlenderMaskedBase 63 { 64 public: 65 // ctor ImageBlenderMasked(OFX::ImageEffect & instance)66 ImageBlenderMasked(OFX::ImageEffect &instance) 67 : ImageBlenderMaskedBase(instance) 68 { 69 } 70 Lerp(const PIX & v1,const PIX & v2,float blend)71 static PIX Lerp(const PIX &v1, 72 const PIX &v2, 73 float blend) 74 { 75 return PIX( (v2 - v1) * blend + v1 ); 76 } 77 78 // and do some processing multiThreadProcessImages(OfxRectI procWindow)79 void multiThreadProcessImages(OfxRectI procWindow) 80 { 81 float tmpPix[nComponents]; 82 float blend = _blend; 83 float blendComp = 1.0f - blend; 84 85 for (int y = procWindow.y1; y < procWindow.y2; y++) { 86 if ( _effect.abort() ) { 87 break; 88 } 89 90 PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); 91 92 for (int x = procWindow.x1; x < procWindow.x2; x++) { 93 PIX *fromPix = (PIX *) (_fromImg ? _fromImg->getPixelAddress(x, y) : 0); 94 PIX *toPix = (PIX *) (_toImg ? _toImg->getPixelAddress(x, y) : 0); 95 96 if ( masked && (fromPix || toPix) ) { 97 for (int c = 0; c < nComponents; ++c) { 98 // all images are supposed to be black and transparent outside o 99 tmpPix[c] = toPix ? (float)toPix[c] : 0.f; 100 } 101 ofxsMaskMixPix<PIX, nComponents, maxValue, masked>(tmpPix, x, y, fromPix, _doMasking, _maskImg, blend, _maskInvert, dstPix); 102 } else if (fromPix && toPix) { 103 assert(!masked); 104 for (int c = 0; c < nComponents; ++c) { 105 dstPix[c] = Lerp(fromPix[c], toPix[c], blend); 106 } 107 } else if (fromPix) { 108 assert(!masked); 109 for (int c = 0; c < nComponents; ++c) { 110 dstPix[c] = PIX(fromPix[c] * blendComp); 111 } 112 } else if (toPix) { 113 assert(!masked); 114 for (int c = 0; c < nComponents; ++c) { 115 dstPix[c] = PIX(toPix[c] * blend); 116 } 117 } else { 118 // everything is black and transparent 119 for (int c = 0; c < nComponents; ++c) { 120 dstPix[c] = PIX(0); 121 } 122 } 123 124 dstPix += nComponents; 125 } 126 } 127 } 128 }; 129 }; 130 131 #endif // ifndef openfx_supportext_ofxsImageBlenderMasked_h 132 133 134