diff options
Diffstat (limited to 'source/blender/compositor/operations')
298 files changed, 21455 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp new file mode 100644 index 00000000000..2dba9572ee8 --- /dev/null +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_AlphaOverKeyOperation.h" + +AlphaOverKeyOperation::AlphaOverKeyOperation(): MixBaseOperation() { +} + +void AlphaOverKeyOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputOverColor[4]; + float value[4]; + + inputValueOperation->read(value, x, y, sampler, inputBuffers); + inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); + inputColor2Operation->read(inputOverColor, x, y, sampler, inputBuffers); + + if(inputOverColor[3]<=0.0f) { + outputValue[0] = inputColor1[0]; + outputValue[1] = inputColor1[1]; + outputValue[2] = inputColor1[2]; + outputValue[3] = inputColor1[3]; + } + else if(value[0]==1.0f && inputOverColor[3]>=1.0f) { + outputValue[0] = inputOverColor[0]; + outputValue[1] = inputOverColor[1]; + outputValue[2] = inputOverColor[2]; + outputValue[3] = inputOverColor[3]; + } + else { + float premul= value[0]*inputOverColor[3]; + float mul= 1.0f - premul; + + outputValue[0]= (mul*inputColor1[0]) + premul*inputOverColor[0]; + outputValue[1]= (mul*inputColor1[1]) + premul*inputOverColor[1]; + outputValue[2]= (mul*inputColor1[2]) + premul*inputOverColor[2]; + outputValue[3]= (mul*inputColor1[3]) + value[0]*inputOverColor[3]; + } +} diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h new file mode 100644 index 00000000000..5ed99d0dbc6 --- /dev/null +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_AlphaOverKeyOperation_h +#define _COM_AlphaOverKeyOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class AlphaOverKeyOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + AlphaOverKeyOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp new file mode 100644 index 00000000000..9deb00ae71a --- /dev/null +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_AlphaOverMixedOperation.h" + +AlphaOverMixedOperation::AlphaOverMixedOperation(): MixBaseOperation() { + this->x = 0.0f; +} + +void AlphaOverMixedOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputOverColor[4]; + float value[4]; + + inputValueOperation->read(value, x, y, sampler, inputBuffers); + inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); + inputColor2Operation->read(inputOverColor, x, y, sampler, inputBuffers); + + if(inputOverColor[3]<=0.0f) { + outputValue[0] = inputColor1[0]; + outputValue[1] = inputColor1[1]; + outputValue[2] = inputColor1[2]; + outputValue[3] = inputColor1[3]; + } + else if(value[0]==1.0f && inputOverColor[3]>=1.0f) { + outputValue[0] = inputOverColor[0]; + outputValue[1] = inputOverColor[1]; + outputValue[2] = inputOverColor[2]; + outputValue[3] = inputOverColor[3]; + } + else { + float addfac= 1.0f - this->x + inputOverColor[3]*this->x; + float premul= value[0]*addfac; + float mul= 1.0f - value[0]*inputOverColor[3]; + + outputValue[0]= (mul*inputColor1[0]) + premul*inputOverColor[0]; + outputValue[1]= (mul*inputColor1[1]) + premul*inputOverColor[1]; + outputValue[2]= (mul*inputColor1[2]) + premul*inputOverColor[2]; + outputValue[3]= (mul*inputColor1[3]) + value[0]*inputOverColor[3]; + } +} + diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h new file mode 100644 index 00000000000..3ee5f243303 --- /dev/null +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_AlphaOverMixedOperation_h +#define _COM_AlphaOverMixedOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class AlphaOverMixedOperation : public MixBaseOperation { +private: + float x; +public: + /** + * Default constructor + */ + AlphaOverMixedOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void setX(float x) {this->x = x;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp new file mode 100644 index 00000000000..635a6308601 --- /dev/null +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_AlphaOverPremultiplyOperation.h" + +AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation(): MixBaseOperation() { +} + +void AlphaOverPremultiplyOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputOverColor[4]; + float value[4]; + + inputValueOperation->read(value, x, y, sampler, inputBuffers); + inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); + inputColor2Operation->read(inputOverColor, x, y, sampler, inputBuffers); + + /* Zero alpha values should still permit an add of RGB data */ + if(inputOverColor[3]<0.0f) { + outputValue[0] = inputColor1[0]; + outputValue[1] = inputColor1[1]; + outputValue[2] = inputColor1[2]; + outputValue[3] = inputColor1[3]; + } + else if(value[0]==1.0f && inputOverColor[3]>=1.0f) { + outputValue[0] = inputOverColor[0]; + outputValue[1] = inputOverColor[1]; + outputValue[2] = inputOverColor[2]; + outputValue[3] = inputOverColor[3]; + } + else { + float mul= 1.0f - value[0]*inputOverColor[3]; + + outputValue[0]= (mul*inputColor1[0]) + value[0]*inputOverColor[0]; + outputValue[1]= (mul*inputColor1[1]) + value[0]*inputOverColor[1]; + outputValue[2]= (mul*inputColor1[2]) + value[0]*inputOverColor[2]; + outputValue[3]= (mul*inputColor1[3]) + value[0]*inputOverColor[3]; + } +} + diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h new file mode 100644 index 00000000000..4fc3b482942 --- /dev/null +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_AlphaOverPremultiplyOperation_h +#define _COM_AlphaOverPremultiplyOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class AlphaOverPremultiplyOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + AlphaOverPremultiplyOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp new file mode 100644 index 00000000000..729d04c182e --- /dev/null +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_AntiAliasOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" +extern "C" { + #include "RE_render_ext.h" +} + + +AntiAliasOperation::AntiAliasOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->valueReader = NULL; + this->buffer = NULL; + this->setComplex(true); +} +void AntiAliasOperation::initExecution() { + this->valueReader = this->getInputSocketReader(0); + NodeOperation::initMutex(); +} + +void AntiAliasOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data) { + if (y < 0 || y >= this->height || x < 0 || x >= this->width) { + color[0] = 0.0f; + } else { + int offset = y*this->width + x; + color[0] = buffer[offset]/255.0f; + } + +} + +void AntiAliasOperation::deinitExecution() { + this->valueReader = NULL; + if (this->buffer) { + delete buffer; + } + NodeOperation::deinitMutex(); +} + +bool AntiAliasOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti imageInput; + if (this->buffer) { + return false; + } else { + NodeOperation* operation = getInputOperation(0); + imageInput.xmax = operation->getWidth(); + imageInput.xmin = 0; + imageInput.ymax = operation->getHeight(); + imageInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&imageInput, readOperation, output) ) { + return true; + } + } + return false; +} + +void* AntiAliasOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + if (this->buffer) {return buffer;} + BLI_mutex_lock(getMutex()); + if (this->buffer == NULL) { + MemoryBuffer* tile = (MemoryBuffer*)valueReader->initializeTileData(rect, memoryBuffers); + int size = tile->getHeight()*tile->getWidth(); + float * input = tile->getBuffer(); + char* valuebuffer = new char[size]; + for (int i = 0 ; i < size ; i ++) { + float in = input[i* COM_NUMBER_OF_CHANNELS]; + if (in < 0.0f) { in = 0.0f;} + if (in > 1.0f) {in = 1.0f;} + valuebuffer[i] = in * 255; + } + antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer); + this->buffer = valuebuffer; + } + BLI_mutex_unlock(getMutex()); + return this->buffer; +} diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.h b/source/blender/compositor/operations/COM_AntiAliasOperation.h new file mode 100644 index 00000000000..1b8b4c42ff9 --- /dev/null +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.h @@ -0,0 +1,61 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_AntiAliasOperation_h +#define _COM_AntiAliasOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" + +/** + * @brief AntiAlias operations + * it only supports anti aliasing on BW buffers. + * @ingroup operation + */ +class AntiAliasOperation : public NodeOperation { +protected: + /** + * @brief Cached reference to the reader + */ + SocketReader * valueReader; + char *buffer; +public: + AntiAliasOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + + /** + * Initialize the execution + */ + void initExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +}; +#endif diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp new file mode 100644 index 00000000000..5743b388705 --- /dev/null +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_BilateralBlurOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +BilateralBlurOperation::BilateralBlurOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + + this->inputColorProgram = NULL; + this->inputDeterminatorProgram = NULL; +} + +void BilateralBlurOperation::initExecution() { + this->inputColorProgram = getInputSocketReader(0); + this->inputDeterminatorProgram = getInputSocketReader(1); + this->space = this->data->sigma_space + this->data->iter; + QualityStepHelper::initExecution(COM_QH_INCREASE); +} + +void BilateralBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + // read the determinator color at x, y, this will be used as the reference color for the determinator + float determinatorReferenceColor[4]; + float determinator[4]; + float tempColor[4]; + float blurColor[4]; + float blurDivider; + float space = this->space; + float sigmacolor = this->data->sigma_color; + int minx = floor(x - space); + int maxx = ceil(x + space); + int miny = floor(y - space); + int maxy = ceil(y + space); + float deltaColor; + this->inputDeterminatorProgram->read(determinatorReferenceColor, x, y, inputBuffers, data); + + blurColor[0] = 0.0f; + blurColor[1] = 0.0f; + blurColor[2] = 0.0f; + blurColor[3] = 0.0f; + blurDivider = 0.0f; + for (int yi = miny ; yi < maxy ; yi+=QualityStepHelper::getStep()) { + for (int xi = minx ; xi < maxx ; xi+=QualityStepHelper::getStep()) { + // read determinator + this->inputDeterminatorProgram->read(determinator, xi, yi, inputBuffers, data); + deltaColor = fabsf(determinatorReferenceColor[0] - determinator[0])+ + fabsf(determinatorReferenceColor[1] - determinator[1])+ + fabsf(determinatorReferenceColor[2] - determinator[2]); // do not take the alpha channel into account + if (deltaColor< sigmacolor) { + // add this to the blur + this->inputColorProgram->read(tempColor, xi, yi, inputBuffers, data); + blurColor[0]+=tempColor[0]; + blurColor[1]+=tempColor[1]; + blurColor[2]+=tempColor[2]; + blurColor[3]+=tempColor[3]; + blurDivider += 1.0f; + } + } + } + + if (blurDivider > 0.0f) { + color[0] = blurColor[0]/blurDivider; + color[1] = blurColor[1]/blurDivider; + color[2] = blurColor[2]/blurDivider; + color[3] = blurColor[3]/blurDivider; + } else { + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 1.0f; + } +} + +void BilateralBlurOperation::deinitExecution() { + this->inputColorProgram = NULL; + this->inputDeterminatorProgram = NULL; +} + +bool BilateralBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + int add = ceil(this->space)+1; + + newInput.xmax = input->xmax + (add); + newInput.xmin = input->xmin - (add); + newInput.ymax = input->ymax + (add); + newInput.ymin = input->ymin - (add); + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.h b/source/blender/compositor/operations/COM_BilateralBlurOperation.h new file mode 100644 index 00000000000..295797fb0b8 --- /dev/null +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BokehBilateralBlurOperation_h +#define _COM_BilateralBlurOperation_h +#include "COM_NodeOperation.h" +#include "COM_QualityStepHelper.h" + +class BilateralBlurOperation : public NodeOperation, public QualityStepHelper { +private: + SocketReader* inputColorProgram; + SocketReader* inputDeterminatorProgram; + NodeBilateralBlurData* data; + float space; + +public: + BilateralBlurOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setData(NodeBilateralBlurData *data) {this->data = data;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp new file mode 100644 index 00000000000..b18c0762c1a --- /dev/null +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -0,0 +1,102 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_BlurBaseOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +BlurBaseOperation::BlurBaseOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + this->inputProgram = NULL; + this->data = NULL; + this->size = 1.0f; + this->deleteData = false; +} +void BlurBaseOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); + this->inputSize = this->getInputSocketReader(1); + this->data->image_in_width= this->getWidth(); + this->data->image_in_height= this->getHeight(); + if(this->data->relative) { + switch (this->data->aspect) { + case CMP_NODE_BLUR_ASPECT_NONE: + this->data->sizex= (int)(this->data->percentx*0.01f*this->data->image_in_width); + this->data->sizey= (int)(this->data->percenty*0.01f*this->data->image_in_height); + break; + case CMP_NODE_BLUR_ASPECT_Y: + this->data->sizex= (int)(this->data->percentx*0.01f*this->data->image_in_width); + this->data->sizey= (int)(this->data->percenty*0.01f*this->data->image_in_width); + break; + case CMP_NODE_BLUR_ASPECT_X: + this->data->sizex= (int)(this->data->percentx*0.01f*this->data->image_in_height); + this->data->sizey= (int)(this->data->percenty*0.01f*this->data->image_in_height); + break; + } + } + + QualityStepHelper::initExecution(COM_QH_MULTIPLY); + +} + +float* BlurBaseOperation::make_gausstab(int rad) +{ + float *gausstab, sum, val; + int i, n; + + n = 2 * rad + 1; + + gausstab = new float[n]; + + sum = 0.0f; + for (i = -rad; i <= rad; i++) { + val= RE_filter_value(this->data->filtertype, (float)i/(float)rad); + sum += val; + gausstab[i+rad] = val; + } + + sum= 1.0f/sum; + for(i=0; i<n; i++) + gausstab[i]*= sum; + + return gausstab; +} + +void BlurBaseOperation::deinitExecution() { + this->inputProgram = NULL; + this->inputSize = NULL; + if (this->deleteData) { + delete this->data; + } + this->data = NULL; +} + +void BlurBaseOperation::updateSize(MemoryBuffer **memoryBuffers){ + float result[4]; + this->getInputSocketReader(1)->read(result, 0, 0, COM_PS_NEAREST, memoryBuffers); + this->size = result[0]; +} diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h new file mode 100644 index 00000000000..3eb36f29865 --- /dev/null +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h @@ -0,0 +1,58 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BlurBaseOperation_h +#define _COM_BlurBaseOperation_h +#include "COM_NodeOperation.h" +#include "COM_QualityStepHelper.h" + +class BlurBaseOperation : public NodeOperation, public QualityStepHelper { +private: + +protected: + /** + * Cached reference to the inputProgram + */ + SocketReader* inputProgram; + SocketReader* inputSize; + NodeBlurData * data; + BlurBaseOperation(); + float* make_gausstab(int rad); + float size; + bool deleteData; + void updateSize(MemoryBuffer **memoryBuffers); +public: + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setData(NodeBlurData* data) {this->data= data;} + + void deleteDataWhenFinished() {this->deleteData = true;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp new file mode 100644 index 00000000000..31345dbaeff --- /dev/null +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -0,0 +1,159 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_BokehBlurOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +BokehBlurOperation::BokehBlurOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + + this->size = .01; + + this->inputProgram = NULL; + this->inputBokehProgram = NULL; + this->inputBoundingBoxReader = NULL; +} + +void* BokehBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + void* buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void BokehBlurOperation::initExecution() { + this->inputProgram = getInputSocketReader(0); + this->inputBokehProgram = getInputSocketReader(1); + this->inputBoundingBoxReader = getInputSocketReader(2); + + int width = inputBokehProgram->getWidth(); + int height = inputBokehProgram->getHeight(); + + float dimension; + if (width<height) { + dimension = width; + } else { + dimension = height; + } + this->bokehMidX = width/2.0f; + this->bokehMidY = height/2.0f; + this->bokehDimension = dimension/2.0f; + QualityStepHelper::initExecution(COM_QH_INCREASE); +} + +void BokehBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float tempColor[4]; + float tempBoundingBox[4]; + float bokeh[4]; + + inputBoundingBoxReader->read(tempBoundingBox, x, y, COM_PS_NEAREST, inputBuffers); + if (tempBoundingBox[0] >0.0f) { + tempColor[0] = 0; + tempColor[1] = 0; + tempColor[2] = 0; + tempColor[3] = 0; + float overallmultiplyerr = 0; + float overallmultiplyerg = 0; + float overallmultiplyerb = 0; + MemoryBuffer* inputBuffer = (MemoryBuffer*)data; + float* buffer = inputBuffer->getBuffer(); + int bufferwidth = inputBuffer->getWidth(); + int bufferstartx = inputBuffer->getRect()->xmin; + int bufferstarty = inputBuffer->getRect()->ymin; + int pixelSize = this->size*this->getWidth(); + + int miny = y - pixelSize; + int maxy = y + pixelSize; + int minx = x - pixelSize; + int maxx = x + pixelSize; + miny = max(miny, inputBuffer->getRect()->ymin); + minx = max(minx, inputBuffer->getRect()->xmin); + maxy = min(maxy, inputBuffer->getRect()->ymax); + maxx = min(maxx, inputBuffer->getRect()->xmax); + + int step = getStep(); + int offsetadd = getOffsetAdd(); + + float m = this->bokehDimension/pixelSize; + for (int ny = miny ; ny < maxy ; ny +=step) { + int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); + for (int nx = minx ; nx < maxx ; nx +=step) { + float u = this->bokehMidX - (nx-x) *m; + float v = this->bokehMidY - (ny-y) *m; + inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); + tempColor[0] += bokeh[0] * buffer[bufferindex]; + tempColor[1] += bokeh[1] * buffer[bufferindex+1]; + tempColor[2] += bokeh[2]* buffer[bufferindex+2]; + overallmultiplyerr += bokeh[0]; + overallmultiplyerg += bokeh[1]; + overallmultiplyerb += bokeh[2]; + bufferindex +=offsetadd; + } + } + color[0] = tempColor[0]*(1.0/overallmultiplyerr); + color[1] = tempColor[1]*(1.0/overallmultiplyerg); + color[2] = tempColor[2]*(1.0/overallmultiplyerb); + color[3] = 1.0f; + } else { + inputProgram->read(color, x, y, COM_PS_NEAREST, inputBuffers); + } +} + +void BokehBlurOperation::deinitExecution() { + this->inputProgram = NULL; + this->inputBokehProgram = NULL; + this->inputBoundingBoxReader = NULL; +} + +bool BokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + rcti bokehInput; + + newInput.xmax = input->xmax + (size*this->getWidth()); + newInput.xmin = input->xmin - (size*this->getWidth()); + newInput.ymax = input->ymax + (size*this->getWidth()); + newInput.ymin = input->ymin - (size*this->getWidth()); + + NodeOperation* operation = getInputOperation(1); + bokehInput.xmax = operation->getWidth(); + bokehInput.xmin = 0; + bokehInput.ymax = operation->getHeight(); + bokehInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&bokehInput, readOperation, output) ) { + return true; + } + operation = getInputOperation(0); + if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) { + return true; + } + operation = getInputOperation(2); + if (operation->determineDependingAreaOfInterest(input, readOperation, output) ) { + return true; + } + return false; +} diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h new file mode 100644 index 00000000000..c782c421966 --- /dev/null +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h @@ -0,0 +1,60 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BokehBokehBlurOperation_h +#define _COM_BokehBlurOperation_h +#include "COM_NodeOperation.h" +#include "COM_QualityStepHelper.h" + +class BokehBlurOperation : public NodeOperation, public QualityStepHelper { +private: + SocketReader* inputProgram; + SocketReader* inputBokehProgram; + SocketReader* inputBoundingBoxReader; + float size; + float bokehMidX; + float bokehMidY; + float bokehDimension; +public: + BokehBlurOperation(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setSize(float size) {this->size = size;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cpp b/source/blender/compositor/operations/COM_BokehImageOperation.cpp new file mode 100644 index 00000000000..3286217e71d --- /dev/null +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cpp @@ -0,0 +1,112 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_BokehImageOperation.h" +#include "BLI_math.h" + +BokehImageOperation::BokehImageOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_COLOR); + this->deleteData = false; +} +void BokehImageOperation::initExecution() { + this->centerX = getWidth() / 2; + this->centerY = getHeight() / 2; + this->center[0] = this->centerX; + this->center[1] = this->centerY; + this->inverseRounding = 1.0-this->data->rounding; + this->circularDistance = getWidth()/2; + this->flapRad = (M_PI*2)/this->data->flaps; + this->flapRadAdd = (this->data->angle/360.0)*M_PI*2; + if (this->flapRadAdd>M_PI) { + this->flapRadAdd-=M_PI*2; + } +} +void BokehImageOperation::detemineStartPointOfFlap(float r[2], int flapNumber, float distance) { + r[0] = sin(flapRad*flapNumber + flapRadAdd)*distance+centerX; + r[1] = cos(flapRad*flapNumber + flapRadAdd)*distance+centerY; +} +float BokehImageOperation::isInsideBokeh(float distance, float x, float y) { + float insideBokeh = 0.0; + const float deltaX = x - centerX; + const float deltaY = y - centerY; + float closestPoint[2]; + float lineP1[2]; + float lineP2[2]; + float point[2]; + point[0] = x; + point[1] = y; + + const float distanceToCenter = len_v2v2(point, center); + const float bearing = (atan2f(deltaX, deltaY) + (M_PI*2)); + int flapNumber = (int)((bearing-flapRadAdd)/flapRad); + + detemineStartPointOfFlap(lineP1, flapNumber, distance); + detemineStartPointOfFlap(lineP2, flapNumber+1, distance); + closest_to_line_v2(closestPoint, point, lineP1, lineP2); + + const float distanceLineToCenter = len_v2v2(center, closestPoint); + const float distanceRoundingToCenter = inverseRounding*distanceLineToCenter+this->data->rounding*distance; + + const float catadioptricDistanceToCenter = distanceRoundingToCenter*this->data->catadioptric; + if (distanceRoundingToCenter>=distanceToCenter && catadioptricDistanceToCenter<=distanceToCenter) { + if (distanceRoundingToCenter-distanceToCenter<1.0) { + insideBokeh = (distanceRoundingToCenter-distanceToCenter); + } else if (this->data->catadioptric != 0.0 && distanceToCenter-catadioptricDistanceToCenter<1.0) { + insideBokeh = (distanceToCenter-catadioptricDistanceToCenter); + } else { + insideBokeh = 1.0; + } + } + return insideBokeh; +} +void BokehImageOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float shift = this->data->lensshift; + float shift2 = shift/2.0f; + float distance = this->circularDistance; + float insideBokehMax = isInsideBokeh(distance, x, y); + float insideBokehMed = isInsideBokeh(distance-fabs(shift2*distance), x, y); + float insideBokehMin = isInsideBokeh(distance-fabs(shift*distance), x, y); + if (shift<0) { + color[0] = insideBokehMax; + color[1] = insideBokehMed; + color[2] = insideBokehMin; + } else { + color[0] = insideBokehMin; + color[1] = insideBokehMed; + color[2] = insideBokehMax; + } + color[3] = 1.0f; +} + +void BokehImageOperation::deinitExecution() { + if (deleteData) { + if (data) { + delete data; + data = NULL; + } + } +} + +void BokehImageOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + resolution[0] = 512; + resolution[1] = 512; +} diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h new file mode 100644 index 00000000000..3089ca6f12e --- /dev/null +++ b/source/blender/compositor/operations/COM_BokehImageOperation.h @@ -0,0 +1,67 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BokehImageOperation_h +#define _COM_BokehImageOperation_h +#include "COM_NodeOperation.h" + + +class BokehImageOperation : public NodeOperation { +private: + NodeBokehImage *data; + + float center[2]; + float centerX; + float centerY; + float inverseRounding; + float circularDistance; + float flapRad; + float flapRadAdd; + + bool deleteData; + + void detemineStartPointOfFlap(float r[2], int flapNumber, float distance); + float isInsideBokeh(float distance, float x, float y); +public: + BokehImageOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + void setData(NodeBokehImage *data) {this->data = data;} + void deleteDataOnFinish() {this->deleteData = true;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp new file mode 100644 index 00000000000..44157051089 --- /dev/null +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp @@ -0,0 +1,110 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_BoxMaskOperation.h" +#include "BLI_math.h" +#include "DNA_node_types.h" + +BoxMaskOperation::BoxMaskOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->inputMask = NULL; + this->inputValue = NULL; + this->cosine = 0.0f; + this->sine = 0.0f; +} +void BoxMaskOperation::initExecution() { + this->inputMask = this->getInputSocketReader(0); + this->inputValue = this->getInputSocketReader(1); + const double rad = DEG2RAD(this->data->rotation); + this->cosine = cos(rad); + this->sine = sin(rad); + this->aspectRatio = ((float)this->getWidth())/this->getHeight(); +} + +void BoxMaskOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputMask[4]; + float inputValue[4]; + + float rx = x/this->getWidth(); + float ry = y/this->getHeight(); + + const float dy = (ry - this->data->y)/this->aspectRatio; + const float dx = rx - this->data->x; + rx = this->data->x+(this->cosine*dx + this->sine*dy); + ry = this->data->y+(-this->sine*dx + this->cosine*dy); + + this->inputMask->read(inputMask, x, y, sampler, inputBuffers); + this->inputValue->read(inputValue, x, y, sampler, inputBuffers); + + float halfHeight = (this->data->height)/2.0f; + float halfWidth = this->data->width/2.0f; + bool inside = rx > this->data->x-halfWidth + && rx < this->data->x+halfWidth + && ry > this->data->y-halfHeight + && ry < this->data->y+halfHeight; + + switch (this->maskType) { + case CMP_NODE_MASKTYPE_ADD: + if (inside) { + color[0] = max(inputMask[0],inputValue[0]); + } else { + color[0] = inputMask[0]; + } + break; + case CMP_NODE_MASKTYPE_SUBTRACT: + if (inside) { + color[0] = inputMask[0]-inputValue[0]; + CLAMP(color[0], 0, 1); + } else { + color[0] = inputMask[0]; + } + break; + case CMP_NODE_MASKTYPE_MULTIPLY: + if (inside) { + color[0] = inputMask[0]*inputValue[0]; + } else { + color[0] = 0; + } + break; + case CMP_NODE_MASKTYPE_NOT: + if (inside) { + if (inputMask[0]>0.0f) { + color[0] = 0; + } else { + color[0] = inputValue[0]; + } + } else { + color[0] = inputMask[0]; + } + break; + } + + +} + +void BoxMaskOperation::deinitExecution() { + this->inputMask = NULL; + this->inputValue = NULL; +} + diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h new file mode 100644 index 00000000000..3436eec8b4c --- /dev/null +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.h @@ -0,0 +1,65 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BoxMaskOperation_h +#define _COM_BoxMaskOperation_h +#include "COM_NodeOperation.h" + + +class BoxMaskOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputMask; + SocketReader * inputValue; + + float sine; + float cosine; + float aspectRatio; + int maskType; + + NodeBoxMask *data; +public: + BoxMaskOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setData(NodeBoxMask *data) {this->data = data;} + + void setMaskType(int maskType) {this->maskType = maskType;} + +}; +#endif diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cpp b/source/blender/compositor/operations/COM_BrightnessOperation.cpp new file mode 100644 index 00000000000..bb481f71cc1 --- /dev/null +++ b/source/blender/compositor/operations/COM_BrightnessOperation.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_BrightnessOperation.h" + +BrightnessOperation::BrightnessOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->inputProgram = NULL; +} +void BrightnessOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); + this->inputBrightnessProgram = this->getInputSocketReader(1); + this->inputContrastProgram = this->getInputSocketReader(2); +} + +void BrightnessOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + float a, b; + float inputBrightness[4]; + float inputContrast[4]; + this->inputProgram->read(inputValue, x, y, sampler, inputBuffers); + this->inputBrightnessProgram->read(inputBrightness, x, y, sampler, inputBuffers); + this->inputContrastProgram->read(inputContrast, x, y, sampler, inputBuffers); + float brightness = inputBrightness[0]; + float contrast = inputContrast[0]; + brightness /= 100.0f; + float delta = contrast / 200.0f; + a = 1.0f - delta * 2.0f; + /* + * The algorithm is by Werner D. Streidt + * (http://visca.com/ffactory/archives/5-99/msg00021.html) + * Extracted of OpenCV demhist.c + */ + if( contrast > 0 ) + { + a = 1.0f / a; + b = a * (brightness - delta); + } + else + { + delta *= -1; + b = a * (brightness + delta); + } + + color[0] = a*inputValue[0]+b; + color[1] = a*inputValue[1]+b; + color[2] = a*inputValue[2]+b; + color[3] = inputValue[3]; +} + +void BrightnessOperation::deinitExecution() { + this->inputProgram = NULL; + this->inputBrightnessProgram = NULL; + this->inputContrastProgram = NULL; +} + diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h new file mode 100644 index 00000000000..60666098bc1 --- /dev/null +++ b/source/blender/compositor/operations/COM_BrightnessOperation.h @@ -0,0 +1,56 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BrightnessOperation_h +#define _COM_BrightnessOperation_h +#include "COM_NodeOperation.h" + + +class BrightnessOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + SocketReader * inputBrightnessProgram; + SocketReader* inputContrastProgram; + +public: + BrightnessOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp new file mode 100644 index 00000000000..062e7fc69fe --- /dev/null +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp @@ -0,0 +1,122 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_CalculateMeanOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + + + +CalculateMeanOperation::CalculateMeanOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); + this->addOutputSocket(COM_DT_VALUE); + this->imageReader = NULL; + this->iscalculated = false; + this->setting = 1; + this->setComplex(true); +} +void CalculateMeanOperation::initExecution() { + this->imageReader = this->getInputSocketReader(0); + this->iscalculated = false; + NodeOperation::initMutex(); +} + +void CalculateMeanOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data) { + color[0] = this->result; +} + +void CalculateMeanOperation::deinitExecution() { + this->imageReader = NULL; + NodeOperation::deinitMutex(); +} + +bool CalculateMeanOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti imageInput; + if (iscalculated) { + return false; + } + NodeOperation* operation = getInputOperation(0); + imageInput.xmax = operation->getWidth(); + imageInput.xmin = 0; + imageInput.ymax = operation->getHeight(); + imageInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&imageInput, readOperation, output) ) { + return true; + } + return false; +} + +void* CalculateMeanOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + BLI_mutex_lock(getMutex()); + if (!this->iscalculated) { + MemoryBuffer* tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + calculateMean(tile); + this->iscalculated = true; + } + BLI_mutex_unlock(getMutex()); + return NULL; +} + +void CalculateMeanOperation::calculateMean(MemoryBuffer * tile) { + this->result = 0.0f; + float* buffer = tile->getBuffer(); + int size = tile->getWidth()*tile->getHeight(); + int pixels = 0; + float sum; + for (int i = 0, offset = 0 ; i < size ; i ++, offset +=4) { + if (buffer[offset+3] > 0) { + pixels ++; + + switch(this->setting) + { + case 1: + { + sum += buffer[offset]*0.35f + buffer[offset+1]*0.45f + buffer[offset+2]*0.2f; + break; + } + case 2: + { + sum+= buffer[offset]; + break; + } + case 3: + { + sum+= buffer[offset+1]; + break; + } + case 4: + { + sum+= buffer[offset+2]; + break; + } + case 5: + { + float yuv[3]; + rgb_to_yuv(buffer[offset], buffer[offset+1], buffer[offset+2], &yuv[0], &yuv[1], &yuv[2]); + sum+=yuv[0]; + break; + } + } + } + } + this->result = sum / pixels; +} diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.h b/source/blender/compositor/operations/COM_CalculateMeanOperation.h new file mode 100644 index 00000000000..e77b864c5c8 --- /dev/null +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.h @@ -0,0 +1,69 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_CalculateMeanOperation_h +#define _COM_CalculateMeanOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" + +/** + * @brief base class of CalculateMean, implementing the simple CalculateMean + * @ingroup operation + */ +class CalculateMeanOperation : public NodeOperation { +protected: + /** + * @brief Cached reference to the reader + */ + SocketReader * imageReader; + + bool iscalculated; + float result; + int setting; + +public: + CalculateMeanOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + + /** + * Initialize the execution + */ + void initExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void setSetting(int setting) {this->setting = setting;} + +protected: + void calculateMean(MemoryBuffer* tile); +}; +#endif diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp new file mode 100644 index 00000000000..4cd990e417e --- /dev/null +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_CalculateStandardDeviationOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + + + +CalculateStandardDeviationOperation::CalculateStandardDeviationOperation(): CalculateMeanOperation() { +} + +void CalculateStandardDeviationOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data) { + color[0] = this->standardDeviation; +} + +void* CalculateStandardDeviationOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + BLI_mutex_lock(getMutex()); + if (!this->iscalculated) { + MemoryBuffer* tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + CalculateMeanOperation::calculateMean(tile); + this->standardDeviation = 0.0f; + float* buffer = tile->getBuffer(); + int size = tile->getWidth()*tile->getHeight(); + int pixels = 0; + float sum; + float mean = this->result; + for (int i = 0, offset = 0 ; i < size ; i ++, offset +=4) { + if (buffer[offset+3] > 0) { + pixels ++; + + switch(this->setting) + { + case 1: + { + float value = buffer[offset]*0.35f + buffer[offset+1]*0.45f + buffer[offset+2]*0.2f; + sum+=(value-mean)*(value-mean); + break; + } + case 2: + { + float value = buffer[offset]; + sum+=value; + sum+=(value-mean)*(value-mean); + break; + } + case 3: + { + float value = buffer[offset+1]; + sum+=value; + sum+=(value-mean)*(value-mean); + break; + } + case 4: + { + float value = buffer[offset+2]; + sum+=value; + sum+=(value-mean)*(value-mean); + } + case 5: + { + float yuv[3]; + rgb_to_yuv(buffer[offset], buffer[offset+1], buffer[offset+2], &yuv[0], &yuv[1], &yuv[2]); + sum+=(yuv[0]-mean)*(yuv[0]-mean); + break; + } + } + } + } + this->standardDeviation = sqrt(sum / (float)(pixels-1)); + this->iscalculated = true; + } + BLI_mutex_unlock(getMutex()); + return NULL; +} diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h new file mode 100644 index 00000000000..9da8823acd1 --- /dev/null +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_CalculateStandardDeviationOperation_h +#define _COM_CalculateStandardDeviationOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" +#include "COM_CalculateMeanOperation.h" +/** + * @brief base class of CalculateStandardDeviation, implementing the simple CalculateStandardDeviation + * @ingroup operation + */ +class CalculateStandardDeviationOperation : public CalculateMeanOperation { +protected: + float standardDeviation; + +public: + CalculateStandardDeviationOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp new file mode 100644 index 00000000000..fd2bd3991ec --- /dev/null +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ChangeHSVOperation.h" + +ChangeHSVOperation::ChangeHSVOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ChangeHSVOperation::initExecution() { + this->inputOperation = getInputSocketReader(0); +} + +void ChangeHSVOperation::deinitExecution() { + this->inputOperation = NULL; +} + +void ChangeHSVOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + + inputOperation->read(inputColor1, x, y, sampler, inputBuffers); + + outputValue[0] = inputColor1[0] + (this->hue - 0.5f); + if (outputValue[0]>1.0f) outputValue[0]-=1.0; else if(outputValue[0]<0.0) outputValue[0]+= 1.0; + outputValue[1] = inputColor1[1] * this->saturation; + outputValue[2] = inputColor1[2] * this->value; + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h new file mode 100644 index 00000000000..8adae8e8ce7 --- /dev/null +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ChangeHSVOperation_h +#define _COM_ChangeHSVOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ChangeHSVOperation : public NodeOperation { +private: + SocketReader * inputOperation; + + float hue; + float saturation; + float value; + +public: + /** + * Default constructor + */ + ChangeHSVOperation(); + + void initExecution(); + void deinitExecution(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void setHue(float hue) {this->hue = hue;} + void setSaturation(float saturation) {this->saturation = saturation;} + void setValue(float value) {this->value = value;} + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp new file mode 100644 index 00000000000..b595aca3c46 --- /dev/null +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ChannelMatteOperation.h" +#include "BLI_math.h" + +ChannelMatteOperation::ChannelMatteOperation(): NodeOperation() { + addInputSocket(COM_DT_COLOR); + addOutputSocket(COM_DT_VALUE); + + inputImageProgram = NULL; +} + +void ChannelMatteOperation::initExecution() { + this->inputImageProgram = this->getInputSocketReader(0); + + this->limit_range = this->limit_max - this->limit_min; + + switch (this->limit_method) { + /* SINGLE */ + case 0: { + /* 123 / RGB / HSV / YUV / YCC */ + const int matte_channel=this->matte_channel-1; + const int limit_channel=this->limit_channel-1; + this->ids[0] = matte_channel; + this->ids[1] = limit_channel; + this->ids[2] = limit_channel; + break; + } + /* MAX */ + case 1: { + switch (this->matte_channel) { + case 1: { + this->ids[0] = 0; + this->ids[1] = 1; + this->ids[2] = 2; + break; + } + case 2: { + this->ids[0] = 1; + this->ids[1] = 0; + this->ids[2] = 2; + break; + } + case 3: { + this->ids[0] = 2; + this->ids[1] = 0; + this->ids[2] = 1; + break; + } + default: + break; + } + break; + } + default: + break; + } +} + +void ChannelMatteOperation::deinitExecution() { + this->inputImageProgram= NULL; +} + +void ChannelMatteOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inColor[4]; + float alpha; + + const float limit_max = this->limit_max; + const float limit_min = this->limit_min; + const float limit_range = this->limit_range; + + this->inputImageProgram->read(inColor, x, y, sampler, inputBuffers); + + /* matte operation */ + alpha = inColor[this->ids[0]] - max(inColor[this->ids[1]], inColor[this->ids[2]]); + + /* flip because 0.0 is transparent, not 1.0 */ + alpha = 1.f - alpha; + + /* test range*/ + if(alpha > limit_max) { + alpha = inColor[3]; /*whatever it was prior */ + } + else if(alpha < limit_min){ + alpha = 0.f; + } + else {/*blend */ + alpha = (alpha - limit_min) / limit_range; + } + + /* store matte(alpha) value in [0] to go with + * COM_SetAlphaOperation and the Value output + */ + + /* don't make something that was more transparent less transparent */ + outputValue[0] = min(alpha, inColor[3]); +} + diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h new file mode 100644 index 00000000000..33e502fe565 --- /dev/null +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.h @@ -0,0 +1,76 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ChannelMatteOperation_h +#define _COM_ChannelMatteOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ChannelMatteOperation : public NodeOperation { +private: + SocketReader *inputImageProgram; + + int color_space; /* node->custom1 */ + int matte_channel; /* node->custom2 */ + int limit_method; /* node->algorithm */ + int limit_channel; /* node->channel */ + float limit_max; /* node->storage->t1 */ + float limit_min; /* node->storage->t2 */ + + float limit_range; + + /** ids to use for the operations (max and simple) + * alpha = in[ids[0]] - max(in[ids[1]], in[ids[2]]) + * the simple operation is using: + * alpha = in[ids[0]] - in[ids[1]] + * but to use the same formula and operation for both we do: + * ids[2] = ids[1] + * alpha = in[ids[0]] - max(in[ids[1]], in[ids[2]]) + */ + int ids[3]; +public: + /** + * Default constructor + */ + ChannelMatteOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeChroma* nodeChroma, const int custom2) + { + this->limit_max = nodeChroma->t1; + this->limit_min = nodeChroma->t2; + this->limit_method = nodeChroma->algorithm; + this->limit_channel = nodeChroma->channel; + this->matte_channel = custom2; + } +}; +#endif diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp new file mode 100644 index 00000000000..8e793f08a3b --- /dev/null +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ChromaMatteOperation.h" +#include "BLI_math.h" + +ChromaMatteOperation::ChromaMatteOperation(): NodeOperation() { + addInputSocket(COM_DT_COLOR); + addInputSocket(COM_DT_COLOR); + addOutputSocket(COM_DT_VALUE); + + inputImageProgram = NULL; + inputKeyProgram = NULL; +} + +void ChromaMatteOperation::initExecution() { + this->inputImageProgram = this->getInputSocketReader(0); + this->inputKeyProgram = this->getInputSocketReader(1); +} + +void ChromaMatteOperation::deinitExecution() { + this->inputImageProgram= NULL; + this->inputKeyProgram= NULL; +} + +void ChromaMatteOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inKey[4]; + float inImage[4]; + + const float acceptance = this->settings->t1; /* in radians */ + const float cutoff = this->settings->t2; /* in radians */ + const float gain = this->settings->fstrength; + + float x_angle, z_angle, alpha; + float theta, beta; + float kfg; + + this->inputKeyProgram->read(inKey, x, y, sampler, inputBuffers); + this->inputImageProgram->read(inImage, x, y, sampler, inputBuffers); + + /* store matte(alpha) value in [0] to go with + * COM_SetAlphaOperation and the Value output + */ + + /* Algorithm from book "Video Demistified," does not include the spill reduction part */ + /* find theta, the angle that the color space should be rotated based on key*/ + theta=atan2(inKey[2], inKey[1]); + + /*rotate the cb and cr into x/z space */ + x_angle=inImage[1]*cosf(theta)+inImage[2]*sinf(theta); + z_angle=inImage[2]*cosf(theta)-inImage[1]*sinf(theta); + + /*if within the acceptance angle */ + /* if kfg is <0 then the pixel is outside of the key color */ + kfg= x_angle-(fabsf(z_angle)/tanf(acceptance/2.f)); + + if(kfg>0.f) { /* found a pixel that is within key color */ + alpha=(1.f-kfg)*(gain); + + beta=atan2(z_angle,x_angle); + + /* if beta is within the cutoff angle */ + if(fabsf(beta) < (cutoff/2.f)) { + alpha=0.f; + } + + /* don't make something that was more transparent less transparent */ + if (alpha<inImage[3]) { + outputValue[0]=alpha; + } + else { + outputValue[0]=inImage[3]; + } + } + else { /*pixel is outside key color */ + outputValue[0]=inImage[3]; /* make pixel just as transparent as it was before */ + } +} + diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h new file mode 100644 index 00000000000..21f0f4b4fe6 --- /dev/null +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.h @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ChromaMatteOperation_h +#define _COM_ChromaMatteOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ChromaMatteOperation : public NodeOperation { +private: + NodeChroma *settings; + SocketReader *inputImageProgram; + SocketReader *inputKeyProgram; +public: + /** + * Default constructor + */ + ChromaMatteOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeChroma* nodeChroma) {this->settings= nodeChroma;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp new file mode 100644 index 00000000000..317d84b0299 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ColorBalanceASCCDLOperation.h" +#include "BLI_math.h" + +inline float colorbalance_cdl(float in, float offset, float power, float slope) +{ + float x = in * slope + offset; + + /* prevent NaN */ + CLAMP(x, 0.0, 1.0); + + return powf(x, power); +} + +ColorBalanceASCCDLOperation::ColorBalanceASCCDLOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputValueOperation = NULL; + this->inputColorOperation = NULL; + this->setResolutionInputSocketIndex(1); +} + +void ColorBalanceASCCDLOperation::initExecution() { + this->inputValueOperation = this->getInputSocketReader(0); + this->inputColorOperation = this->getInputSocketReader(1); +} + +void ColorBalanceASCCDLOperation::executePixel(float* outputColor, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + float value[4]; + + inputValueOperation->read(value, x, y, sampler, inputBuffers); + inputColorOperation->read(inputColor, x, y, sampler, inputBuffers); + + float fac = value[0]; + fac = min(1.0f, fac); + const float mfac= 1.0f - fac; + + outputColor[0] = mfac*inputColor[0] + fac * colorbalance_cdl(inputColor[0], this->lift[0], this->gamma[0], this->gain[0]); + outputColor[1] = mfac*inputColor[1] + fac * colorbalance_cdl(inputColor[1], this->lift[1], this->gamma[1], this->gain[1]); + outputColor[2] = mfac*inputColor[2] + fac * colorbalance_cdl(inputColor[2], this->lift[2], this->gamma[2], this->gain[2]); + outputColor[3] = inputColor[3]; + +} + +void ColorBalanceASCCDLOperation::deinitExecution() { + this->inputValueOperation = NULL; + this->inputColorOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h new file mode 100644 index 00000000000..a7e9680c98d --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h @@ -0,0 +1,81 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ColorBalanceASCCDLOperation_h +#define _COM_ColorBalanceASCCDLOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ColorBalanceASCCDLOperation : public NodeOperation { +protected: + /** + * Prefetched reference to the inputProgram + */ + SocketReader * inputValueOperation; + SocketReader * inputColorOperation; + + float gain[3]; + float lift[3]; + float gamma[3]; + +public: + /** + * Default constructor + */ + ColorBalanceASCCDLOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setGain(float gain[3]) { + this->gain[0] = gain[0]; + this->gain[1] = gain[1]; + this->gain[2] = gain[2]; + } + void setLift(float lift[3]) { + this->lift[0] = lift[0]; + this->lift[1] = lift[1]; + this->lift[2] = lift[2]; + } + void setGamma(float gamma[3]) { + this->gamma[0] = gamma[0]; + this->gamma[1] = gamma[1]; + this->gamma[2] = gamma[2]; + } +}; +#endif diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp new file mode 100644 index 00000000000..b853c28136f --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ColorBalanceLGGOperation.h" +#include "BLI_math.h" + + +inline float colorbalance_lgg(float in, float lift_lgg, float gamma_inv, float gain) +{ + /* 1:1 match with the sequencer with linear/srgb conversions, the conversion isnt pretty + * but best keep it this way, sice testing for durian shows a similar calculation + * without lin/srgb conversions gives bad results (over-saturated shadows) with colors + * slightly below 1.0. some correction can be done but it ends up looking bad for shadows or lighter tones - campbell */ + float x= (((linearrgb_to_srgb(in) - 1.0f) * lift_lgg) + 1.0f) * gain; + + /* prevent NaN */ + if (x < 0.f) x = 0.f; + + return powf(srgb_to_linearrgb(x), gamma_inv); +} + +ColorBalanceLGGOperation::ColorBalanceLGGOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputValueOperation = NULL; + this->inputColorOperation = NULL; + this->setResolutionInputSocketIndex(1); +} + +void ColorBalanceLGGOperation::initExecution() { + this->inputValueOperation = this->getInputSocketReader(0); + this->inputColorOperation = this->getInputSocketReader(1); +} + +void ColorBalanceLGGOperation::executePixel(float* outputColor, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + float value[4]; + + inputValueOperation->read(value, x, y, sampler, inputBuffers); + inputColorOperation->read(inputColor, x, y, sampler, inputBuffers); + + float fac = value[0]; + fac = min(1.0f, fac); + const float mfac= 1.0f - fac; + + outputColor[0] = mfac*inputColor[0] + fac * colorbalance_lgg(inputColor[0], this->lift[0], this->gamma_inv[0], this->gain[0]); + outputColor[1] = mfac*inputColor[1] + fac * colorbalance_lgg(inputColor[1], this->lift[1], this->gamma_inv[1], this->gain[1]); + outputColor[2] = mfac*inputColor[2] + fac * colorbalance_lgg(inputColor[2], this->lift[2], this->gamma_inv[2], this->gain[2]); + outputColor[3] = inputColor[3]; + +} + +void ColorBalanceLGGOperation::deinitExecution() { + this->inputValueOperation = NULL; + this->inputColorOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h new file mode 100644 index 00000000000..ebaabfeb736 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h @@ -0,0 +1,81 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ColorBalanceLGGOperation_h +#define _COM_ColorBalanceLGGOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ColorBalanceLGGOperation : public NodeOperation { +protected: + /** + * Prefetched reference to the inputProgram + */ + SocketReader * inputValueOperation; + SocketReader * inputColorOperation; + + float gain[3]; + float lift[3]; + float gamma_inv[3]; + +public: + /** + * Default constructor + */ + ColorBalanceLGGOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setGain(float gain[3]) { + this->gain[0] = gain[0]; + this->gain[1] = gain[1]; + this->gain[2] = gain[2]; + } + void setLift(float lift[3]) { + this->lift[0] = lift[0]; + this->lift[1] = lift[1]; + this->lift[2] = lift[2]; + } + void setGammaInv(float gamma_inv[3]) { + this->gamma_inv[0] = gamma_inv[0]; + this->gamma_inv[1] = gamma_inv[1]; + this->gamma_inv[2] = gamma_inv[2]; + } +}; +#endif diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp new file mode 100644 index 00000000000..fef045481f7 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ColorCorrectionOperation.h" +#include "BLI_math.h" + +ColorCorrectionOperation::ColorCorrectionOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->inputImage = NULL; + this->inputMask = NULL; + this->redChannelEnabled = true; + this->greenChannelEnabled = true; + this->blueChannelEnabled = true; +} +void ColorCorrectionOperation::initExecution() { + this->inputImage = this->getInputSocketReader(0); + this->inputMask = this->getInputSocketReader(1); +} + +void ColorCorrectionOperation::executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputImageColor[4]; + float inputMask[4]; + this->inputImage->read(inputImageColor, x, y, sampler, inputBuffers); + this->inputMask->read(inputMask, x, y, sampler, inputBuffers); + + float level = (inputImageColor[0] + inputImageColor[1] + inputImageColor[2])/3.0f; + float contrast= this->data->master.contrast; + float saturation = this->data->master.saturation; + float gamma = this->data->master.gamma; + float gain = this->data->master.gain; + float lift = this->data->master.lift; + float r, g, b; + + float value = inputMask[0]; + value = min(1.0f, value); + const float mvalue= 1.0f - value; + + float levelShadows = 0.0; + float levelMidtones = 0.0; + float levelHighlights = 0.0; +#define MARGIN 0.10 +#define MARGIN_DIV (0.5/MARGIN) + if ( level < this->data->startmidtones-MARGIN) { + levelShadows = 1.0f; + } else if (level < this->data->startmidtones+MARGIN) { + levelMidtones = ((level-this->data->startmidtones)*MARGIN_DIV)+0.5; + levelShadows = 1.0- levelMidtones; + } else if (level < this->data->endmidtones-MARGIN) { + levelMidtones = 1.0f; + } else if (level < this->data->endmidtones+MARGIN) { + levelHighlights = ((level-this->data->endmidtones)*MARGIN_DIV)+0.5; + levelMidtones = 1.0- levelHighlights; + } else { + levelHighlights = 1.0f; + } +#undef MARGIN +#undef MARGIN_DIV + contrast *= (levelShadows*this->data->shadows.contrast)+(levelMidtones*this->data->midtones.contrast)+(levelHighlights*this->data->highlights.contrast); + saturation *= (levelShadows*this->data->shadows.saturation)+(levelMidtones*this->data->midtones.saturation)+(levelHighlights*this->data->highlights.saturation); + gamma *= (levelShadows*this->data->shadows.gamma)+(levelMidtones*this->data->midtones.gamma)+(levelHighlights*this->data->highlights.gamma); + gain *= (levelShadows*this->data->shadows.gain)+(levelMidtones*this->data->midtones.gain)+(levelHighlights*this->data->highlights.gain); + lift += (levelShadows*this->data->shadows.lift)+(levelMidtones*this->data->midtones.lift)+(levelHighlights*this->data->highlights.lift); + + r = inputImageColor[0]; + g = inputImageColor[1]; + b = inputImageColor[2]; + + float invgamma = 1.0f/gamma; + float luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; + r = ( luma + saturation * (r - luma)); + g = ( luma + saturation * (g - luma)); + b = ( luma + saturation * (b - luma)); + CLAMP (r, 0.0f, 1.0f); + CLAMP (g, 0.0f, 1.0f); + CLAMP (b, 0.0f, 1.0f); + + r = 0.5+((r-0.5)*contrast); + g = 0.5+((g-0.5)*contrast); + b = 0.5+((b-0.5)*contrast); + + r = powf(r*gain+lift, invgamma); + g = powf(g*gain+lift, invgamma); + b = powf(b*gain+lift, invgamma); + + + // mix with mask + r = mvalue*inputImageColor[0] + value * r; + g = mvalue*inputImageColor[1] + value * g; + b = mvalue*inputImageColor[2] + value * b; + + if (this->redChannelEnabled) { + output[0] = r; + } else { + output[0] = inputImageColor[0]; + } + if (this->greenChannelEnabled) { + output[1] = g; + } else { + output[1] = inputImageColor[1]; + } + if (this->blueChannelEnabled) { + output[2] = b; + } else { + output[2] = inputImageColor[2]; + } + output[3] = inputImageColor[3]; +} + +void ColorCorrectionOperation::deinitExecution() { + this->inputImage = NULL; + this->inputMask = NULL; +} + diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h new file mode 100644 index 00000000000..9a3eefe30c6 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ColorCorrectionOperation_h +#define _COM_ColorCorrectionOperation_h +#include "COM_NodeOperation.h" + + +class ColorCorrectionOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputImage; + SocketReader* inputMask; + NodeColorCorrection *data; + + bool redChannelEnabled; + bool greenChannelEnabled; + bool blueChannelEnabled; + +public: + ColorCorrectionOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setData(NodeColorCorrection * data) {this->data = data;} + void setRedChannelEnabled(bool enabled) {this->redChannelEnabled = enabled;} + void setGreenChannelEnabled(bool enabled) {this->greenChannelEnabled = enabled;} + void setBlueChannelEnabled(bool enabled) {this->blueChannelEnabled = enabled;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp new file mode 100644 index 00000000000..cb16b99f06b --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ColorCurveOperation.h" + +#ifdef __cplusplus +extern "C" { +#endif + #include "BKE_colortools.h" +#ifdef __cplusplus +} +#endif + +ColorCurveOperation::ColorCurveOperation(): CurveBaseOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + + this->inputFacProgram = NULL; + this->inputImageProgram = NULL; + this->inputBlackProgram = NULL; + this->inputWhiteProgram = NULL; + + this->setResolutionInputSocketIndex(1); +} +void ColorCurveOperation::initExecution() { + CurveBaseOperation::initExecution(); + this->inputFacProgram = this->getInputSocketReader(0); + this->inputImageProgram = this->getInputSocketReader(1); + this->inputBlackProgram = this->getInputSocketReader(2); + this->inputWhiteProgram = this->getInputSocketReader(3); + + curvemapping_premultiply(this->curveMapping, 0); + +} + +void ColorCurveOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float black[4]; + float white[4]; + float fac[4]; + float image[4]; + + this->inputBlackProgram->read(black, x, y, sampler, inputBuffers); + this->inputWhiteProgram->read(white, x, y, sampler, inputBuffers); + + curvemapping_set_black_white(this->curveMapping, black, white); + + this->inputFacProgram->read(fac, x, y, sampler, inputBuffers); + this->inputImageProgram->read(image, x, y, sampler, inputBuffers); + + if(fac[0]>=1.0) + curvemapping_evaluate_premulRGBF(this->curveMapping, color, image); + else if(*fac<=0.0) { + color[0]= image[0]; + color[1]= image[1]; + color[2]= image[2]; + } + else { + float col[4], mfac= 1.0f-*fac; + curvemapping_evaluate_premulRGBF(this->curveMapping, col, image); + color[0]= mfac*image[0] + *fac*col[0]; + color[1]= mfac*image[1] + *fac*col[1]; + color[2]= mfac*image[2] + *fac*col[2]; + } + color[3]= image[3]; +} + +void ColorCurveOperation::deinitExecution() { + this->inputFacProgram = NULL; + this->inputImageProgram = NULL; + this->inputBlackProgram = NULL; + this->inputWhiteProgram = NULL; + curvemapping_premultiply(this->curveMapping, 1); +} diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h new file mode 100644 index 00000000000..986f6fcfcc2 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.h @@ -0,0 +1,56 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ColorCurveOperation_h +#define _COM_ColorCurveOperation_h +#include "COM_NodeOperation.h" +#include "DNA_color_types.h" +#include "COM_CurveBaseOperation.h" + +class ColorCurveOperation : public CurveBaseOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputFacProgram; + SocketReader * inputImageProgram; + SocketReader * inputBlackProgram; + SocketReader * inputWhiteProgram; +public: + ColorCurveOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp new file mode 100644 index 00000000000..a80788ddd33 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ColorMatteOperation.h" +#include "BLI_math.h" + +ColorMatteOperation::ColorMatteOperation(): NodeOperation() { + addInputSocket(COM_DT_COLOR); + addInputSocket(COM_DT_COLOR); + addOutputSocket(COM_DT_VALUE); + + inputImageProgram = NULL; + inputKeyProgram = NULL; +} + +void ColorMatteOperation::initExecution() { + this->inputImageProgram = this->getInputSocketReader(0); + this->inputKeyProgram = this->getInputSocketReader(1); +} + +void ColorMatteOperation::deinitExecution() { + this->inputImageProgram= NULL; + this->inputKeyProgram= NULL; +} + +void ColorMatteOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inColor[4]; + float inKey[4]; + + const float hue=this->settings->t1; + const float sat=this->settings->t2; + const float val=this->settings->t3; + + float h_wrap; + + this->inputImageProgram->read(inColor, x, y, sampler, inputBuffers); + this->inputKeyProgram->read(inKey, x, y, sampler, inputBuffers); + + + /* store matte(alpha) value in [0] to go with + * COM_SetAlphaOperation and the Value output + */ + + if( + /* do hue last because it needs to wrap, and does some more checks */ + + /* sat */ (fabsf(inColor[1]-inKey[1]) < sat) && + /* val */ (fabsf(inColor[2]-inKey[2]) < val) && + + /* multiply by 2 because it wraps on both sides of the hue, + * otherwise 0.5 would key all hue's */ + + /* hue */ ((h_wrap= 2.f * fabsf(inColor[0]-inKey[0])) < hue || (2.f - h_wrap) < hue) + ) { + outputValue[0]=0.f; /*make transparent*/ + } + + else { /*pixel is outside key color */ + outputValue[0]=inColor[3]; /* make pixel just as transparent as it was before */ + } +} + diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h new file mode 100644 index 00000000000..954a5bbb3e8 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.h @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ColorMatteOperation_h +#define _COM_ColorMatteOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ColorMatteOperation : public NodeOperation { +private: + NodeChroma *settings; + SocketReader *inputImageProgram; + SocketReader *inputKeyProgram; +public: + /** + * Default constructor + */ + ColorMatteOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeChroma* nodeChroma) {this->settings= nodeChroma;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.cpp b/source/blender/compositor/operations/COM_ColorRampOperation.cpp new file mode 100644 index 00000000000..a7cfb30b439 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorRampOperation.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ColorRampOperation.h" + +#ifdef __cplusplus +extern "C" { +#endif + #include "BKE_texture.h" +#ifdef __cplusplus +} +#endif + +ColorRampOperation::ColorRampOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + + this->inputProgram = NULL; + this->colorBand = NULL; +} +void ColorRampOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); +} + +void ColorRampOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float values[4]; + + this->inputProgram->read(values, x, y, sampler, inputBuffers); + do_colorband(this->colorBand, values[0], color); +} + +void ColorRampOperation::deinitExecution() { + this->inputProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.h b/source/blender/compositor/operations/COM_ColorRampOperation.h new file mode 100644 index 00000000000..08a6c26a8bf --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorRampOperation.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ColorRampOperation_h +#define _COM_ColorRampOperation_h +#include "COM_NodeOperation.h" +#include "DNA_texture_types.h" + +class ColorRampOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + ColorBand* colorBand; +public: + ColorRampOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setColorBand(ColorBand* colorBand) {this->colorBand = colorBand;} + + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp new file mode 100644 index 00000000000..9f054540332 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp @@ -0,0 +1,110 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This Reader is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This Reader is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Reader; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ColorSpillOperation.h" +#include "BLI_math.h" +#define avg(a,b) ((a+b)/2) + +ColorSpillOperation::ColorSpillOperation(): NodeOperation() { + addInputSocket(COM_DT_COLOR); + addInputSocket(COM_DT_VALUE); + addOutputSocket(COM_DT_COLOR); + + inputImageReader = NULL; + inputFacReader = NULL; + this->spillChannel = 1; // GREEN +} + +void ColorSpillOperation::initExecution() { + this->inputImageReader = this->getInputSocketReader(0); + this->inputFacReader = this->getInputSocketReader(1); + if (spillChannel == 0) { + rmut = -1.0f; + gmut = 1.0f; + bmut = 1.0f; + this->channel2 = 1; + this->channel3 = 2; + if (settings->unspill == 0) { + settings->uspillr = 1.0f; + settings->uspillg = 0.0f; + settings->uspillb = 0.0f; + } + } else if (spillChannel == 1) { + rmut = 1.0f; + gmut = -1.0f; + bmut = 1.0f; + this->channel2 = 0; + this->channel3 = 2; + if (settings->unspill == 0) { + settings->uspillr = 0.0f; + settings->uspillg = 1.0f; + settings->uspillb = 0.0f; + } + } else { + rmut = 1.0f; + gmut = 1.0f; + bmut = -1.0f; + + this->channel2 = 0; + this->channel3 = 1; + if (settings->unspill == 0) { + settings->uspillr = 0.0f; + settings->uspillg = 0.0f; + settings->uspillb = 1.0f; + } + } +} + +void ColorSpillOperation::deinitExecution() { + this->inputImageReader= NULL; + this->inputFacReader = NULL; +} + +void ColorSpillOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float fac[4]; + float input[4]; + float map; + this->inputFacReader->read(fac, x, y, sampler, inputBuffers); + this->inputImageReader->read(input, x, y, sampler, inputBuffers); + float rfac = min(1.0f, fac[0]); + map = calculateMapValue(rfac, input); + if(map>0) { + outputValue[0]=input[0]+rmut*(settings->uspillr*map); + outputValue[1]=input[1]+gmut*(settings->uspillg*map); + outputValue[2]=input[2]+bmut*(settings->uspillb*map); + outputValue[3]=input[3]; + } + else { + outputValue[0]=input[0]; + outputValue[1]=input[1]; + outputValue[2]=input[2]; + outputValue[3]=input[3]; + } +} +float ColorSpillOperation::calculateMapValue(float fac, float *input) { + return fac * (input[this->spillChannel]-(this->settings->limscale*input[settings->limchan])); +} + + +float ColorSpillAverageOperation::calculateMapValue(float fac, float *input) { + return fac * (input[this->spillChannel]-(this->settings->limscale*avg(input[this->channel2], input[this->channel3]))); +} diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h new file mode 100644 index 00000000000..963eaae3076 --- /dev/null +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ColorSpillOperation_h +#define _COM_ColorSpillOperation_h +#include "COM_NodeOperation.h" + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ColorSpillOperation : public NodeOperation { +protected: + NodeColorspill *settings; + SocketReader *inputImageReader; + SocketReader *inputFacReader; + int spillChannel; + int channel2; + int channel3; + float rmut, gmut, bmut; +public: + /** + * Default constructor + */ + ColorSpillOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeColorspill* nodeColorSpill) {this->settings= nodeColorSpill;} + void setSpillChannel(int channel) {this->spillChannel = channel;} + + float calculateMapValue(float fac, float *input); +}; + +class ColorSpillAverageOperation: public ColorSpillOperation { +public: + float calculateMapValue(float fac, float *input); +}; +#endif diff --git a/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp b/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp new file mode 100644 index 00000000000..efeac9db410 --- /dev/null +++ b/source/blender/compositor/operations/COM_CombineChannelsOperation.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_CombineChannelsOperation.h" +#include <stdio.h> + +CombineChannelsOperation::CombineChannelsOperation() : NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputChannel1Operation = NULL; + this->inputChannel2Operation = NULL; + this->inputChannel3Operation = NULL; + this->inputChannel4Operation = NULL; +} +void CombineChannelsOperation::initExecution() { + this->inputChannel1Operation = this->getInputSocketReader(0); + this->inputChannel2Operation = this->getInputSocketReader(1); + this->inputChannel3Operation = this->getInputSocketReader(2); + this->inputChannel4Operation = this->getInputSocketReader(3); +} + +void CombineChannelsOperation::deinitExecution() { + this->inputChannel1Operation = NULL; + this->inputChannel2Operation = NULL; + this->inputChannel3Operation = NULL; + this->inputChannel4Operation = NULL; +} + + +void CombineChannelsOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float input[4]; + /// @todo: remove if statements + if (this->inputChannel1Operation) { + this->inputChannel1Operation->read(input, x, y, sampler, inputBuffers); + color[0] = input[0]; + } + if (this->inputChannel2Operation) { + this->inputChannel2Operation->read(input, x, y, sampler, inputBuffers); + color[1] = input[0]; + } + if (this->inputChannel3Operation) { + this->inputChannel3Operation->read(input, x, y, sampler, inputBuffers); + color[2] = input[0]; + } + if (this->inputChannel4Operation) { + this->inputChannel4Operation->read(input, x, y, sampler, inputBuffers); + color[3] = input[0]; + } +} diff --git a/source/blender/compositor/operations/COM_CombineChannelsOperation.h b/source/blender/compositor/operations/COM_CombineChannelsOperation.h new file mode 100644 index 00000000000..18dd1fd2ec9 --- /dev/null +++ b/source/blender/compositor/operations/COM_CombineChannelsOperation.h @@ -0,0 +1,42 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_CombineChannelsOperation_h_ +#define _COM_CombineChannelsOperation_h_ + +#include "COM_NodeOperation.h" + +class CombineChannelsOperation: public NodeOperation { +private: + SocketReader *inputChannel1Operation; + SocketReader *inputChannel2Operation; + SocketReader *inputChannel3Operation; + SocketReader *inputChannel4Operation; +public: + CombineChannelsOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp new file mode 100644 index 00000000000..7590b4be299 --- /dev/null +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -0,0 +1,122 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_CompositorOperation.h" +#include "COM_SocketConnection.h" +#include "BLI_listbase.h" +#include "DNA_scene_types.h" +#include "BKE_image.h" + +extern "C" { + #include "RE_pipeline.h" + #include "RE_shader_ext.h" + #include "RE_render_ext.h" + #include "MEM_guardedalloc.h" +#include "render_types.h" +} +#include "PIL_time.h" + + +CompositorOperation::CompositorOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + + this->setScene(NULL); + this->outputBuffer = NULL; + this->imageInput = NULL; + this->alphaInput = NULL; +} + +void CompositorOperation::initExecution() { + // When initializing the tree during initial load the width and height can be zero. + this->imageInput = getInputSocketReader(0); + this->alphaInput = getInputSocketReader(1); + if (this->getWidth() * this->getHeight() != 0) { + this->outputBuffer=(float*) MEM_callocN(this->getWidth()*this->getHeight()*4*sizeof(float), "CompositorOperation"); + } + const Scene * scene = this->scene; + Render* re= RE_GetRender(scene->id.name); + RenderResult *rr= RE_AcquireResultWrite(re); + if(rr) { + if(rr->rectf != NULL) { + MEM_freeN(rr->rectf); + } + rr->rectf= outputBuffer; + } + if (re) { + RE_ReleaseResult(re); + re = NULL; + } + +} + +void CompositorOperation::deinitExecution() { + this->outputBuffer = NULL; + this->imageInput = NULL; + this->alphaInput = NULL; +} + + +void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) { + float color[8]; // 7 is enough + float* buffer = this->outputBuffer; + + if (!buffer) return; + int x1 = rect->xmin; + int y1 = rect->ymin; + int x2 = rect->xmax; + int y2 = rect->ymax; + int offset = (y1*this->getWidth() + x1 ) * 4; + int x; + int y; + bool breaked = false; + + for (y = y1 ; y < y2 && (!breaked); y++) { + for (x = x1 ; x < x2 && (!breaked) ; x++) { + imageInput->read(color, x, y, COM_PS_NEAREST, memoryBuffers); + if (alphaInput != NULL) { + alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST, memoryBuffers); + } + buffer[offset] = color[0]; + buffer[offset+1] = color[1]; + buffer[offset+2] = color[2]; + buffer[offset+3] = color[3]; + offset +=4; + if (tree->test_break && tree->test_break(tree->tbh)) { + breaked = true; + } + } + offset += (this->getWidth()-(x2-x1))*4; + } +} + +void CompositorOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + int width = this->scene->r.xsch*this->scene->r.size/100; + int height= this->scene->r.ysch*this->scene->r.size/100; + preferredResolution[0] = width; + preferredResolution[1] = height; + + NodeOperation::determineResolution(resolution, preferredResolution); + + resolution[0] = width; + resolution[1] = height; +} diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h new file mode 100644 index 00000000000..6f71fdff7b4 --- /dev/null +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -0,0 +1,69 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_CompositorOperation_h +#define _COM_CompositorOperation_h +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "BLI_rect.h" + +/** + * @brief Compositor output operation + */ +class CompositorOperation : public NodeOperation { +private: + /** + * @brief local reference to the scene + */ + const Scene* scene; + + /** + * @brief local reference to the node tree + */ + const bNodeTree* tree; + + /** + * @brief reference to the output float buffer + */ + float *outputBuffer; + + /** + * @brief local reference to the input image operation + */ + SocketReader* imageInput; + + /** + * @brief local reference to the input alpha operation + */ + SocketReader* alphaInput; +public: + CompositorOperation(); + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + void setScene(const Scene* scene) {this->scene = scene;} + void setbNodeTree(const bNodeTree* tree) {this->tree= tree;} + bool isOutputOperation(bool rendering) const {return rendering;} + void initExecution(); + void deinitExecution(); + const int getRenderPriority() const {return 7;} + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp new file mode 100644 index 00000000000..3267994feea --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertColorProfileOperation.h" + +extern "C" { + #include "IMB_imbuf.h" +} +ConvertColorProfileOperation::ConvertColorProfileOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; + this->predivided = false; +} + +void ConvertColorProfileOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertColorProfileOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float color[4]; + inputOperation->read(color, x, y, sampler, inputBuffers); + IMB_buffer_float_from_float(outputValue, color, 4, this->toProfile, this->fromProfile, this->predivided, 1, 1, 0, 0); +} + +void ConvertColorProfileOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h new file mode 100644 index 00000000000..9781795b952 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h @@ -0,0 +1,78 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertColorProfileOperation_h +#define _COM_ConvertColorProfileOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertColorProfileOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; + + /** + * @brief color profile where to convert from + */ + int fromProfile; + + /** + * @brief color profile where to convert to + */ + int toProfile; + + /** + * @brief is color predivided + */ + bool predivided; +public: + /** + * Default constructor + */ + ConvertColorProfileOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setFromColorProfile(int colorProfile) {this->fromProfile = colorProfile;} + void setToColorProfile(int colorProfile) {this->toProfile = colorProfile;} + void setPredivided(bool predivided) {this->predivided = predivided;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp new file mode 100644 index 00000000000..8c48c5c0d14 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertColorToBWOperation.h" + +ConvertColorToBWOperation::ConvertColorToBWOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VALUE); + this->inputOperation = NULL; +} + +void ConvertColorToBWOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertColorToBWOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + inputOperation->read(&inputColor[0], x, y, sampler, inputBuffers); + outputValue[0] = (inputColor[0]*0.35f + inputColor[1]*0.45f + inputColor[2]*0.2f)*inputColor[3]; +} + +void ConvertColorToBWOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.h b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.h new file mode 100644 index 00000000000..82d71453e1e --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.h @@ -0,0 +1,60 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertColorToBWOperation_h +#define _COM_ConvertColorToBWOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertColorToBWOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertColorToBWOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp new file mode 100644 index 00000000000..af86f3ea5e8 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertColorToVectorOperation.h" + +ConvertColorToVectorOperation::ConvertColorToVectorOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VECTOR); + this->inputOperation = NULL; +} + +void ConvertColorToVectorOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertColorToVectorOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + inputOperation->read(outputValue, x, y, sampler, inputBuffers); +} + +void ConvertColorToVectorOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h new file mode 100644 index 00000000000..de7315da02f --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertColorToVectorOperation_h +#define _COM_ConvertColorToVectorOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertColorToVectorOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertColorToVectorOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertColourToValueProg.cpp b/source/blender/compositor/operations/COM_ConvertColourToValueProg.cpp new file mode 100644 index 00000000000..caf41419668 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColourToValueProg.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertColourToValueProg.h" + +ConvertColourToValueProg::ConvertColourToValueProg(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VALUE); + this->inputOperation = NULL; +} + +void ConvertColourToValueProg::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertColourToValueProg::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + inputOperation->read(&inputColor[0], x, y, sampler, inputBuffers); + outputValue[0] = ((inputColor[0] + inputColor[1] + inputColor[2])/3.0f)*inputColor[3]; +} + +void ConvertColourToValueProg::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertColourToValueProg.h b/source/blender/compositor/operations/COM_ConvertColourToValueProg.h new file mode 100644 index 00000000000..73e71b5665a --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertColourToValueProg.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertColourToValueProg_h +#define _COM_ConvertColourToValueProg_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertColourToValueProg : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertColourToValueProg(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp new file mode 100644 index 00000000000..345fc37b340 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertDepthToRadiusOperation.h" +#include "BLI_math.h" +#include "DNA_camera_types.h" + +ConvertDepthToRadiusOperation::ConvertDepthToRadiusOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->inputOperation = NULL; + this->fStop = 128.0f; + this->cameraObject = NULL; + this->maxRadius = 32.0f; +} + +float ConvertDepthToRadiusOperation::determineFocalDistance() { + + if (cameraObject == NULL || cameraObject->type != OB_CAMERA) { + return 10.0f; + } else { + Camera *camera= (Camera*)this->cameraObject->data; + cam_lens = camera->lens; + if (camera->dof_ob) { + /* too simple, better to return the distance on the view axis only + * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ + float mat[4][4], imat[4][4], obmat[4][4]; + + copy_m4_m4(obmat, cameraObject->obmat); + normalize_m4(obmat); + invert_m4_m4(imat, obmat); + mult_m4_m4m4(mat, imat, camera->dof_ob->obmat); + return (float)fabs(mat[3][2]); + } + return camera->YF_dofdist; + } +} + +void ConvertDepthToRadiusOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); + float focalDistance = determineFocalDistance(); + if (focalDistance==0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it be be far away */ + inverseFocalDistance = 1.f/focalDistance; + this->aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight()); + this->aperture = 0.5f*(this->cam_lens / (this->aspect*32.f)) / this->fStop; + float minsz = MIN2(getWidth(), getHeight()); + this->dof_sp = (float)minsz / (16.f / cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); +} + +void ConvertDepthToRadiusOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + float z; + float radius; + inputOperation->read(inputValue, x, y, sampler, inputBuffers); + z = inputValue[0]; + if (z!=0.f) { + float iZ = (1.f/z); + + // bug #6656 part 2b, do not rescale + /* + bcrad = 0.5f*fabs(aperture*(dof_sp*(cam_invfdist - iZ) - 1.f)); + // scale crad back to original maximum and blend + crad->rect[px] = bcrad + wts->rect[px]*(scf*crad->rect[px] - bcrad); + */ + radius = 0.5f*fabsf(this->aperture*(dof_sp*(inverseFocalDistance - iZ) - 1.f)); + // 'bug' #6615, limit minimum radius to 1 pixel, not really a solution, but somewhat mitigates the problem + if (radius < 0.5f) radius = 0.5f; + if (radius > maxRadius) { + radius = maxRadius; + } + outputValue[0] = radius; + } + else outputValue[0] = 0.0f; +} + +void ConvertDepthToRadiusOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h new file mode 100644 index 00000000000..80a56122565 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h @@ -0,0 +1,72 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertDepthToRadiusOperation_h +#define _COM_ConvertDepthToRadiusOperation_h +#include "COM_NodeOperation.h" +#include "DNA_object_types.h" + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertDepthToRadiusOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; + float fStop; + float aspect; + float maxRadius; + float inverseFocalDistance; + float aperture; + float cam_lens; + float dof_sp; + Object *cameraObject; +public: + /** + * Default constructor + */ + ConvertDepthToRadiusOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setfStop(float fStop) {this->fStop = fStop;} + void setMaxRadius(float maxRadius) {this->maxRadius = maxRadius;} + void setCameraObject(Object* camera) {this->cameraObject = camera;} + float determineFocalDistance(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp new file mode 100644 index 00000000000..8de98fef28b --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertHSVToRGBOperation.h" +#include "BLI_math_color.h" + +ConvertHSVToRGBOperation::ConvertHSVToRGBOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ConvertHSVToRGBOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertHSVToRGBOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + inputOperation->read(inputColor, x, y, sampler, inputBuffers); + hsv_to_rgb(inputColor[0], inputColor[1], inputColor[2], &outputValue[0], &outputValue[1], &outputValue[2]); + outputValue[3] = inputColor[3]; +} + +void ConvertHSVToRGBOperation::deinitExecution() { + this->inputOperation = NULL; +} + diff --git a/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h new file mode 100644 index 00000000000..f2f61250aad --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertHSVToRGBOperation_h +#define _COM_ConvertHSVToRGBOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertHSVToRGBOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertHSVToRGBOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp new file mode 100644 index 00000000000..509093f4d5f --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ConvertKeyToPremulOperation.h" +#include "BLI_math.h" + +ConvertKeyToPremulOperation::ConvertKeyToPremulOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + + this->inputColor = NULL; +} + +void ConvertKeyToPremulOperation::initExecution() { + this->inputColor = getInputSocketReader(0); +} + +void ConvertKeyToPremulOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + float alpha; + + this->inputColor->read(inputValue, x, y, sampler, inputBuffers); + alpha = inputValue[3]; + + outputValue[0] = inputValue[0] * alpha; + outputValue[1] = inputValue[1] * alpha; + outputValue[2] = inputValue[2] * alpha; + + /* never touches the alpha */ + outputValue[3] = alpha; +} + +void ConvertKeyToPremulOperation::deinitExecution() { + this->inputColor = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h new file mode 100644 index 00000000000..15195b37f49 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h @@ -0,0 +1,49 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ConvertKeyToPremulOperation_h +#define _COM_ConvertKeyToPremulOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertKeyToPremulOperation : public NodeOperation { +private: + SocketReader *inputColor; +public: + /** + * Default constructor + */ + ConvertKeyToPremulOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp new file mode 100644 index 00000000000..6f676b1c404 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ConvertPremulToKeyOperation.h" +#include "BLI_math.h" + +ConvertPremulToKeyOperation::ConvertPremulToKeyOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + + this->inputColor = NULL; +} + +void ConvertPremulToKeyOperation::initExecution() { + this->inputColor = getInputSocketReader(0); +} + +void ConvertPremulToKeyOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + float alpha; + + this->inputColor->read(inputValue, x, y, sampler, inputBuffers); + alpha = inputValue[3]; + + if(fabsf(alpha) < 1e-5f) { + outputValue[0]= 0.f; + outputValue[1]= 0.f; + outputValue[2]= 0.f; + } + else { + outputValue[0] = inputValue[0] / alpha; + outputValue[1] = inputValue[1] / alpha; + outputValue[2] = inputValue[2] / alpha; + } + + /* never touches the alpha */ + outputValue[3] = alpha; +} + +void ConvertPremulToKeyOperation::deinitExecution() { + this->inputColor = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h new file mode 100644 index 00000000000..431dcfe5742 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h @@ -0,0 +1,48 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ConvertPremulToKeyOperation_h +#define _COM_ConvertPremulToKeyOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertPremulToKeyOperation : public NodeOperation { +private: + SocketReader *inputColor; +public: + /** + * Default constructor + */ + ConvertPremulToKeyOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp new file mode 100644 index 00000000000..b8208a864ff --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertRGBToHSVOperation.h" +#include "BLI_math_color.h" + +ConvertRGBToHSVOperation::ConvertRGBToHSVOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ConvertRGBToHSVOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertRGBToHSVOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + inputOperation->read(inputColor, x, y, sampler, inputBuffers); + rgb_to_hsv(inputColor[0], inputColor[1], inputColor[2], &outputValue[0], &outputValue[1], &outputValue[2]); + outputValue[3] = inputColor[3]; +} + +void ConvertRGBToHSVOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h new file mode 100644 index 00000000000..a36092640e8 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h @@ -0,0 +1,60 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertRGBToHSVOperation_h +#define _COM_ConvertRGBToHSVOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertRGBToHSVOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertRGBToHSVOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp new file mode 100644 index 00000000000..623376d532f --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ConvertRGBToYCCOperation.h" +#include "BLI_math_color.h" + +ConvertRGBToYCCOperation::ConvertRGBToYCCOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ConvertRGBToYCCOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertRGBToYCCOperation::setMode(int mode) { + switch(mode) + { + case 1: + this->mode = BLI_YCC_ITU_BT709; + break; + case 2: + this->mode = BLI_YCC_JFIF_0_255; + break; + case 0: + default: + this->mode = BLI_YCC_ITU_BT601; + break; + } +} + +void ConvertRGBToYCCOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + float color[3]; + + inputOperation->read(inputColor, x, y, sampler, inputBuffers); + rgb_to_ycc(inputColor[0], inputColor[1], inputColor[2], &color[0], &color[1], &color[2], this->mode); + + /* divided by 255 to normalize for viewing in */ + outputValue[0] = color[0]/255.f; /* Y */ + outputValue[1] = color[1]/255.f; /* Cb*/ + outputValue[2] = color[2]/255.f; /* Cr*/ + outputValue[3] = inputColor[3]; +} + +void ConvertRGBToYCCOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h new file mode 100644 index 00000000000..76825061c19 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h @@ -0,0 +1,68 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ConvertRGBToYCCOperation_h +#define _COM_ConvertRGBToYCCOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertRGBToYCCOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; + + /** + * YCbCr mode (Jpeg, ITU601, ITU709) + */ + int mode; +public: + /** + * Default constructor + */ + ConvertRGBToYCCOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + /** + * Set the YCC mode + */ + void setMode(int mode); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp new file mode 100644 index 00000000000..c8ab3dd5a4b --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ConvertRGBToYUVOperation.h" +#include "BLI_math_color.h" + +ConvertRGBToYUVOperation::ConvertRGBToYUVOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ConvertRGBToYUVOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertRGBToYUVOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + inputOperation->read(inputColor, x, y, sampler, inputBuffers); + rgb_to_yuv(inputColor[0], inputColor[1], inputColor[2], &outputValue[0], &outputValue[1], &outputValue[2]); + outputValue[3] = inputColor[3]; +} + +void ConvertRGBToYUVOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h new file mode 100644 index 00000000000..aba759b6b97 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ConvertRGBToYUVOperation_h +#define _COM_ConvertRGBToYUVOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertRGBToYUVOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertRGBToYUVOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertValueToColourProg.cpp b/source/blender/compositor/operations/COM_ConvertValueToColourProg.cpp new file mode 100644 index 00000000000..622163739d6 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertValueToColourProg.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertValueToColourProg.h" + +ConvertValueToColourProg::ConvertValueToColourProg(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->inputProgram = NULL; +} +void ConvertValueToColourProg::initExecution() { + this->inputProgram = this->getInputSocketReader(0); +} + +void ConvertValueToColourProg::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + this->inputProgram->read(inputValue, x, y, sampler, inputBuffers); + color[0] = inputValue[0]; + color[1] = inputValue[0]; + color[2] = inputValue[0]; + color[3] = 1.0f; +} + +void ConvertValueToColourProg::deinitExecution() { + this->inputProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertValueToColourProg.h b/source/blender/compositor/operations/COM_ConvertValueToColourProg.h new file mode 100644 index 00000000000..25643a74f35 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertValueToColourProg.h @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertValueToColourProg_h +#define _COM_ConvertValueToColourProg_h +#include "COM_NodeOperation.h" + + +class ConvertValueToColourProg : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader* inputProgram; +public: + ConvertValueToColourProg(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp new file mode 100644 index 00000000000..c675ea16fdb --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertValueToVectorOperation.h" + +ConvertValueToVectorOperation::ConvertValueToVectorOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VECTOR); + this->inputOperation = NULL; +} + +void ConvertValueToVectorOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertValueToVectorOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float input[4]; + inputOperation->read(input, x, y, sampler, inputBuffers); + outputValue[0] = input[0]; + outputValue[1] = input[0]; + outputValue[2] = input[0]; + outputValue[3] = 0.0f; +} + +void ConvertValueToVectorOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h new file mode 100644 index 00000000000..0824bb0e4fe --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertValueToVectorOperation_h +#define _COM_ConvertValueToVectorOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertValueToVectorOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertValueToVectorOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp new file mode 100644 index 00000000000..517fc56e93e --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertVectorToColorOperation.h" + +ConvertVectorToColorOperation::ConvertVectorToColorOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VECTOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ConvertVectorToColorOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertVectorToColorOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + inputOperation->read(outputValue, x, y, sampler, inputBuffers); + outputValue[3] = 1.0f; +} + +void ConvertVectorToColorOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h new file mode 100644 index 00000000000..4ebaf5b9230 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertVectorToColorOperation_h +#define _COM_ConvertVectorToColorOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertVectorToColorOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertVectorToColorOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp new file mode 100644 index 00000000000..a57cd229e1f --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvertVectorToValueOperation.h" + +ConvertVectorToValueOperation::ConvertVectorToValueOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VECTOR); + this->addOutputSocket(COM_DT_VALUE); + this->inputOperation = NULL; +} + +void ConvertVectorToValueOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertVectorToValueOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float input[4]; + inputOperation->read(input, x, y, sampler, inputBuffers); + outputValue[0] = (input[0]+input[1]+input[2])/3.0f; +} + +void ConvertVectorToValueOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h new file mode 100644 index 00000000000..ede7853f57e --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvertVectorToValueOperation_h +#define _COM_ConvertVectorToValueOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertVectorToValueOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertVectorToValueOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp new file mode 100644 index 00000000000..1d8ee944915 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ConvertYCCToRGBOperation.h" +#include "BLI_math_color.h" + +ConvertYCCToRGBOperation::ConvertYCCToRGBOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ConvertYCCToRGBOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertYCCToRGBOperation::setMode(int mode) { + switch(mode) + { + case 1: + this->mode = BLI_YCC_ITU_BT709; + break; + case 2: + this->mode = BLI_YCC_JFIF_0_255; + break; + case 0: + default: + this->mode = BLI_YCC_ITU_BT601; + break; + } +} + +void ConvertYCCToRGBOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + inputOperation->read(inputColor, x, y, sampler, inputBuffers); + + /* need to un-normalize the data */ + inputColor[0] *= 255.f; /* Y */ + inputColor[1] *= 255.f; /* Cb*/ + inputColor[2] *= 255.f; /* Cr*/ + + ycc_to_rgb(inputColor[0], inputColor[1], inputColor[2], &outputValue[0], &outputValue[1], &outputValue[2], this->mode); + outputValue[3] = inputColor[3]; +} + +void ConvertYCCToRGBOperation::deinitExecution() { + this->inputOperation = NULL; +} + diff --git a/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h new file mode 100644 index 00000000000..c3702de3b48 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h @@ -0,0 +1,68 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ConvertYCCToRGBOperation_h +#define _COM_ConvertYCCToRGBOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertYCCToRGBOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; + + /** + * YCbCr mode (Jpeg, ITU601, ITU709) + */ + int mode; +public: + /** + * Default constructor + */ + ConvertYCCToRGBOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + /** + * Set the YCC mode + */ + void setMode(int mode); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp new file mode 100644 index 00000000000..a807030cb8a --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_ConvertYUVToRGBOperation.h" +#include "BLI_math_color.h" + +ConvertYUVToRGBOperation::ConvertYUVToRGBOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void ConvertYUVToRGBOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void ConvertYUVToRGBOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + inputOperation->read(inputColor, x, y, sampler, inputBuffers); + yuv_to_rgb(inputColor[0], inputColor[1], inputColor[2], &outputValue[0], &outputValue[1], &outputValue[2]); + outputValue[3] = inputColor[3]; +} + +void ConvertYUVToRGBOperation::deinitExecution() { + this->inputOperation = NULL; +} + diff --git a/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h new file mode 100644 index 00000000000..6d82d36fe5c --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h @@ -0,0 +1,58 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_ConvertYUVToRGBOperation_h +#define _COM_ConvertYUVToRGBOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ConvertYUVToRGBOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; +public: + /** + * Default constructor + */ + ConvertYUVToRGBOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp new file mode 100644 index 00000000000..6505e1be83e --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvolutionEdgeFilterOperation.h" +#include "BLI_math.h" + +ConvolutionEdgeFilterOperation::ConvolutionEdgeFilterOperation() : ConvolutionFilterOperation() { +} +inline void addFilter(float* result, float*input, float value) { + result[0] += input[0] * value; + result[1] += input[1] * value; + result[2] += input[2] * value; +} + +void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float in1[4],in2[4], res1[4], res2[4]; + + float value[4]; + this->inputValueOperation->read(value, x, y, inputBuffers, NULL); + float mval = 1.0f - value[0]; + + res1[0] = 0.0f; + res1[1] = 0.0f; + res1[2] = 0.0f; + res1[3] = 0.0f; + res2[0] = 0.0f; + res2[1] = 0.0f; + res2[2] = 0.0f; + res2[3] = 0.0f; + + this->inputOperation->read(in1, x-1, y-1, inputBuffers, NULL); + addFilter(res1, in1, this->filter[0]); + addFilter(res2, in1, this->filter[0]); + + this->inputOperation->read(in1, x, y-1, inputBuffers, NULL); + addFilter(res1, in1, this->filter[1]); + addFilter(res2, in1, this->filter[3]); + + this->inputOperation->read(in1, x+1, y-1, inputBuffers, NULL); + addFilter(res1, in1, this->filter[2]); + addFilter(res2, in1, this->filter[6]); + + this->inputOperation->read(in1, x-1, y, inputBuffers, NULL); + addFilter(res1, in1, this->filter[3]); + addFilter(res2, in1, this->filter[1]); + + this->inputOperation->read(in2, x, y, inputBuffers, NULL); + addFilter(res1, in2, this->filter[4]); + addFilter(res2, in2, this->filter[4]); + + this->inputOperation->read(in1, x+1, y, inputBuffers, NULL); + addFilter(res1, in1, this->filter[5]); + addFilter(res2, in1, this->filter[7]); + + this->inputOperation->read(in1, x-1, y+1, inputBuffers, NULL); + addFilter(res1, in1, this->filter[6]); + addFilter(res2, in1, this->filter[2]); + + this->inputOperation->read(in1, x, y+1, inputBuffers, NULL); + addFilter(res1, in1, this->filter[7]); + addFilter(res2, in1, this->filter[5]); + + this->inputOperation->read(in1, x+1, y+1, inputBuffers, NULL); + addFilter(res1, in1, this->filter[8]); + addFilter(res2, in1, this->filter[8]); + + color[0] = sqrt(res1[0]*res1[0]+res2[0]*res2[0]); + color[1] = sqrt(res1[1]*res1[1]+res2[1]*res2[1]); + color[2] = sqrt(res1[2]*res1[2]+res2[2]*res2[2]); + + color[0] = color[0]*value[0] + in2[0] * mval; + color[1] = color[1]*value[0] + in2[1] * mval; + color[2] = color[2]*value[0] + in2[2] * mval; + + color[3] = in2[3]; +} diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h new file mode 100644 index 00000000000..64a52d1a925 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h @@ -0,0 +1,34 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvolutionEdgeFilterOperation_h_ +#define _COM_ConvolutionEdgeFilterOperation_h_ + +#include "COM_ConvolutionFilterOperation.h" + +class ConvolutionEdgeFilterOperation: public ConvolutionFilterOperation { +public: + ConvolutionEdgeFilterOperation(); + void executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void* data); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp new file mode 100644 index 00000000000..1bf53260e23 --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ConvolutionFilterOperation.h" + +ConvolutionFilterOperation::ConvolutionFilterOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputOperation = NULL; + this->filter = NULL; + this->setComplex(true); +} +void ConvolutionFilterOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); + this->inputValueOperation = this->getInputSocketReader(1); +} + +void ConvolutionFilterOperation::set3x3Filter(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9) { + this->filter = new float[9]; + this->filter[0] = f1; + this->filter[1] = f2; + this->filter[2] = f3; + this->filter[3] = f4; + this->filter[4] = f5; + this->filter[5] = f6; + this->filter[6] = f7; + this->filter[7] = f8; + this->filter[8] = f9; + this->filterHeight = 3; + this->filterWidth = 3; +} + +void ConvolutionFilterOperation::deinitExecution() { + this->inputOperation = NULL; + this->inputValueOperation = NULL; + if (this->filter) { + delete this->filter; + this->filter = NULL; + } +} + + +void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void* data) { + color[0] = 0.0; + color[1] = 0.0; + color[2] = 0.0; + color[3] = 0.0; + float in1[4]; + float in2[4]; + float value[4]; + this->inputValueOperation->read(value, x, y, inputBuffers, NULL); + float mval = 1.0f - value[0]; + + this->inputOperation->read(in1, x-1, y-1, inputBuffers, NULL); + color[0] += in1[0] * this->filter[0]; + color[1] += in1[1] * this->filter[0]; + color[2] += in1[2] * this->filter[0]; + color[3] += in1[3] * this->filter[0]; + this->inputOperation->read(in1, x, y-1, inputBuffers, NULL); + color[0] += in1[0] * this->filter[1]; + color[1] += in1[1] * this->filter[1]; + color[2] += in1[2] * this->filter[1]; + color[3] += in1[3] * this->filter[1]; + this->inputOperation->read(in1, x+1, y-1, inputBuffers, NULL); + color[0] += in1[0] * this->filter[2]; + color[1] += in1[1] * this->filter[2]; + color[2] += in1[2] * this->filter[2]; + color[3] += in1[3] * this->filter[2]; + this->inputOperation->read(in1, x-1, y, inputBuffers, NULL); + color[0] += in1[0] * this->filter[3]; + color[1] += in1[1] * this->filter[3]; + color[2] += in1[2] * this->filter[3]; + color[3] += in1[3] * this->filter[3]; + this->inputOperation->read(in2, x, y, inputBuffers, NULL); + color[0] += in2[0] * this->filter[4]; + color[1] += in2[1] * this->filter[4]; + color[2] += in2[2] * this->filter[4]; + color[3] += in2[3] * this->filter[4]; + this->inputOperation->read(in1, x+1, y, inputBuffers, NULL); + color[0] += in1[0] * this->filter[5]; + color[1] += in1[1] * this->filter[5]; + color[2] += in1[2] * this->filter[5]; + color[3] += in1[3] * this->filter[5]; + this->inputOperation->read(in1, x-1, y+1, inputBuffers, NULL); + color[0] += in1[0] * this->filter[6]; + color[1] += in1[1] * this->filter[6]; + color[2] += in1[2] * this->filter[6]; + color[3] += in1[3] * this->filter[6]; + this->inputOperation->read(in1, x, y+1, inputBuffers, NULL); + color[0] += in1[0] * this->filter[7]; + color[1] += in1[1] * this->filter[7]; + color[2] += in1[2] * this->filter[7]; + color[3] += in1[3] * this->filter[7]; + this->inputOperation->read(in1, x+1, y+1, inputBuffers, NULL); + color[0] += in1[0] * this->filter[8]; + color[1] += in1[1] * this->filter[8]; + color[2] += in1[2] * this->filter[8]; + color[3] += in1[3] * this->filter[8]; + + color[0] = color[0]*value[0] + in2[0] * mval; + color[1] = color[1]*value[0] + in2[1] * mval; + color[2] = color[2]*value[0] + in2[2] * mval; +} + +bool ConvolutionFilterOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + int addx = (this->filterWidth-1)/2+1; + int addy = (this->filterHeight-1)/2+1; + newInput.xmax = input->xmax + addx; + newInput.xmin = input->xmin - addx; + newInput.ymax = input->ymax + addy; + newInput.ymin = input->ymin - addy; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h new file mode 100644 index 00000000000..732b3d3699e --- /dev/null +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ConvolutionFilterOperation_h_ +#define _COM_ConvolutionFilterOperation_h_ + +#include "COM_NodeOperation.h" + +class ConvolutionFilterOperation: public NodeOperation { +private: + int filterWidth; + int filterHeight; + +protected: + SocketReader *inputOperation; + SocketReader *inputValueOperation; + float* filter; + +public: + ConvolutionFilterOperation(); + void set3x3Filter(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void* data); + + void initExecution(); + void deinitExecution(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp new file mode 100644 index 00000000000..a763ded7f52 --- /dev/null +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_CropOperation.h" +#include "BLI_math.h" + +CropBaseOperation::CropBaseOperation() :NodeOperation(){ + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; + this->settings = NULL; +} + +void CropBaseOperation::updateArea() { + SocketReader * inputReference = this->getInputSocketReader(0); + float width = inputReference->getWidth(); + float height = inputReference->getHeight(); + if (this->relative){ + settings->x1= width * settings->fac_x1; + settings->x2= width * settings->fac_x2; + settings->y1= height * settings->fac_y1; + settings->y2= height * settings->fac_y2; + } + if (width <= settings->x1 + 1) + settings->x1 = width - 1; + if (height <= settings->y1 + 1) + settings->y1 = height - 1; + if (width <= settings->x2 + 1) + settings->x2 = width - 1; + if (height <= settings->y2 + 1) + settings->y2 = height - 1; + + this->xmax = MAX2(settings->x1, settings->x2) + 1; + this->xmin = MIN2(settings->x1, settings->x2); + this->ymax = MAX2(settings->y1, settings->y2) + 1; + this->ymin = MIN2(settings->y1, settings->y2); +} + +void CropBaseOperation::initExecution(){ + this->inputOperation = this->getInputSocketReader(0); + updateArea(); +} + +void CropBaseOperation::deinitExecution(){ + this->inputOperation = NULL; +} + +CropOperation::CropOperation() :CropBaseOperation(){ +} + +void CropOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]){ + if ((x < this->xmax && x >= xmin) && (y < ymax && y >= ymin)){ + inputOperation->read(color, x, y, sampler, inputBuffers); + } else { + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 0.0f; + } +} + +CropImageOperation::CropImageOperation() :CropBaseOperation(){ +} + +bool CropImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output){ + rcti newInput; + + newInput.xmax = input->xmax + this->xmin; + newInput.xmin = input->xmin + this->xmin; + newInput.ymax = input->ymax + this->ymin; + newInput.ymin = input->ymin + this->ymin; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} + +void CropImageOperation::determineResolution(unsigned int resolution[], unsigned int preferedResolution[]){ + NodeOperation::determineResolution(resolution, preferedResolution); + updateArea(); + resolution[0] = this->xmax - this->xmin; + resolution[1] = this->ymax - this->ymin; +} + +void CropImageOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]){ + this->inputOperation->read(color, (x + this->xmin), (y + this->ymin), sampler, inputBuffers); +} diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h new file mode 100644 index 00000000000..a728212d221 --- /dev/null +++ b/source/blender/compositor/operations/COM_CropOperation.h @@ -0,0 +1,63 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_CropOperation_h_ +#define _COM_CropOperation_h_ + +#include "COM_NodeOperation.h" + +class CropBaseOperation: public NodeOperation { +protected: + SocketReader *inputOperation; + NodeTwoXYs *settings; + bool relative; + int xmax; + int xmin; + int ymax; + int ymin; + + void updateArea(); +public: + CropBaseOperation(); + void initExecution(); + void deinitExecution(); + void setCropSettings(NodeTwoXYs *settings) {this->settings = settings;} + void setRelative(bool rel) {this->relative =rel;} +}; + +class CropOperation: public CropBaseOperation { +private: +public: + CropOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +class CropImageOperation: public CropBaseOperation { +private: +public: + CropImageOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void determineResolution(unsigned int resolution[], unsigned int preferedResolution[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp new file mode 100644 index 00000000000..ddccff01772 --- /dev/null +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_CurveBaseOperation.h" + +#ifdef __cplusplus +extern "C" { +#endif + #include "BKE_colortools.h" +#ifdef __cplusplus +} +#endif + +CurveBaseOperation::CurveBaseOperation(): NodeOperation() { + this->curveMapping = NULL; +} +void CurveBaseOperation::initExecution() { + curvemapping_initialize(this->curveMapping); +} diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.h b/source/blender/compositor/operations/COM_CurveBaseOperation.h new file mode 100644 index 00000000000..bd4ee2ef2ed --- /dev/null +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_CurveBaseOperation_h +#define _COM_CurveBaseOperation_h +#include "COM_NodeOperation.h" +#include "DNA_color_types.h" + +class CurveBaseOperation : public NodeOperation { +protected: + /** + * Cached reference to the inputProgram + */ + CurveMapping *curveMapping; +public: + CurveBaseOperation(); + + /** + * Initialize the execution + */ + void initExecution(); + + void setCurveMapping(CurveMapping* mapping) {this->curveMapping = mapping;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp new file mode 100644 index 00000000000..92d9e29dcec --- /dev/null +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_DifferenceMatteOperation.h" +#include "BLI_math.h" + +DifferenceMatteOperation::DifferenceMatteOperation(): NodeOperation() { + addInputSocket(COM_DT_COLOR); + addInputSocket(COM_DT_COLOR); + addOutputSocket(COM_DT_VALUE); + + inputImage1Program = NULL; + inputImage2Program = NULL; +} + +void DifferenceMatteOperation::initExecution() { + this->inputImage1Program = this->getInputSocketReader(0); + this->inputImage2Program = this->getInputSocketReader(1); +} +void DifferenceMatteOperation::deinitExecution() { + this->inputImage1Program= NULL; + this->inputImage2Program= NULL; +} + +void DifferenceMatteOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inColor1[4]; + float inColor2[4]; + + const float tolerence=this->settings->t1; + const float falloff=this->settings->t2; + float difference; + float alpha; + + this->inputImage1Program->read(inColor1, x, y, sampler, inputBuffers); + this->inputImage2Program->read(inColor2, x, y, sampler, inputBuffers); + + difference= fabs(inColor2[0]-inColor1[0])+ + fabs(inColor2[1]-inColor1[1])+ + fabs(inColor2[2]-inColor1[2]); + + /*average together the distances*/ + difference=difference/3.0; + + /*make 100% transparent*/ + if(difference < tolerence) { + outputValue[0]=0.0; + } + /*in the falloff region, make partially transparent */ + else if(difference < falloff+tolerence) { + difference=difference-tolerence; + alpha=difference/falloff; + /*only change if more transparent than before */ + if(alpha < inColor1[3]) { + outputValue[0]=alpha; + } + else { /* leave as before */ + outputValue[0]=inColor1[3]; + } + } + else { + /*foreground object*/ + outputValue[0]= inColor1[3]; + } +} + diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h new file mode 100644 index 00000000000..2b63bfd7a15 --- /dev/null +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_DifferenceMatteOperation_h +#define _COM_DifferenceMatteOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class DifferenceMatteOperation : public NodeOperation { +private: + NodeChroma* settings; + SocketReader * inputImage1Program; + SocketReader* inputImage2Program; +public: + /** + * Default constructor + */ + DifferenceMatteOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeChroma* nodeChroma) {this->settings= nodeChroma;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp new file mode 100644 index 00000000000..df3bf996c96 --- /dev/null +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -0,0 +1,145 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_DilateErodeOperation.h" +#include "BLI_math.h" + +DilateErodeOperation::DilateErodeOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->setComplex(true); + this->inputProgram = NULL; + this->inset = 0.0f; + this->_switch = 0.5f; + this->distance = 0.0f; +} +void DilateErodeOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); + if (this->distance < 0.0f) { + this->scope = - this->distance + this->inset; + } else { + if (this->inset*2 > this->distance) { + this->scope = max(this->inset*2 - this->distance, this->distance); + } else { + this->scope = distance; + } + } + if (scope < 3) { + scope = 3; + } +} + +void* DilateErodeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + void* buffer = inputProgram->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void DilateErodeOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float inputValue[4]; + const float sw = this->_switch; + const float distance = this->distance; + float pixelvalue; + const float rd = scope * scope; + const float inset = this->inset; + float mindist = rd*2; + + MemoryBuffer* inputBuffer = (MemoryBuffer*)data; + float* buffer = inputBuffer->getBuffer(); + rcti* rect = inputBuffer->getRect(); + const int minx = max(x - scope, rect->xmin); + const int miny = max(y - scope, rect->ymin); + const int maxx = min(x + scope, rect->xmax); + const int maxy = min(y + scope, rect->ymax); + const int bufferWidth = rect->xmax-rect->xmin; + int offset; + + this->inputProgram->read(inputValue, x, y, inputBuffers, NULL); + if (inputValue[0]>sw) { + for (int yi = miny ; yi<maxy;yi++) { + offset = ((yi-rect->ymin)*bufferWidth+(minx-rect->xmin))*4; + for (int xi = minx ; xi<maxx;xi++) { + if (buffer[offset]<sw) { + const float dx = xi-x; + const float dy = yi-y; + const float dis = dx*dx+dy*dy; + mindist = min(mindist, dis); + } + offset +=4; + } + } + pixelvalue = -sqrtf(mindist); + } else { + for (int yi = miny ; yi<maxy;yi++) { + offset = ((yi-rect->ymin)*bufferWidth+(minx-rect->xmin))*4; + for (int xi = minx ; xi<maxx;xi++) { + if (buffer[offset]>sw) { + const float dx = xi-x; + const float dy = yi-y; + const float dis = dx*dx+dy*dy; + mindist = min(mindist, dis); + } + offset +=4; + + } + } + pixelvalue = sqrtf(mindist); + } + + if (distance > 0.0f) { + const float delta = distance - pixelvalue; + if (delta >= 0.0f) { + if (delta >= inset) { + color[0] = 1.0f; + } else { + color[0] = delta/inset; + } + } else { + color[0] = 0.0f; + } + } else { + const float delta = -distance+pixelvalue; + if (delta < 0.0f) { + if (delta < -inset) { + color[0] = 1.0f; + } else { + color[0] = (-delta)/inset; + } + } else { + color[0] = 0.0f; + } + } +} + +void DilateErodeOperation::deinitExecution() { + this->inputProgram = NULL; +} + +bool DilateErodeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + newInput.xmax = input->xmax + scope; + newInput.xmin = input->xmin - scope; + newInput.ymax = input->ymax + scope; + newInput.ymin = input->ymin - scope; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h new file mode 100644 index 00000000000..af554fa0d16 --- /dev/null +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -0,0 +1,70 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_DilateErodeOperation_h +#define _COM_DilateErodeOperation_h +#include "COM_NodeOperation.h" + + +class DilateErodeOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + + float distance; + float _switch; + float inset; + + /** + * determines the area of interest to track pixels + * keep this one as small as possible for speed gain. + */ + int scope; +public: + DilateErodeOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setDistance(float distance) {this->distance = distance;} + void setSwitch(float sw) {this->_switch = sw;} + void setInset(float inset) {this->inset = inset;} + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp new file mode 100644 index 00000000000..5b066d8f16e --- /dev/null +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_DirectionalBlurOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +DirectionalBlurOperation::DirectionalBlurOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + + this->inputProgram = NULL; +} + +void DirectionalBlurOperation::initExecution() { + this->inputProgram = getInputSocketReader(0); + QualityStepHelper::initExecution(COM_QH_INCREASE); + const float angle = this->data->angle; + const float zoom = this->data->zoom; + const float spin = this->data->spin; + const float iterations = this->data->iter; + const float distance = this->data->distance; + const float center_x = this->data->center_x; + const float center_y = this->data->center_y; + const float width = getWidth(); + const float height = getHeight(); + + const float a= angle; + const float itsc= 1.f / pow(2.f, (float)iterations); + float D; + + D= distance * sqrtf(width*width + height*height); + center_x_pix= center_x * width; + center_y_pix= center_y * height; + + tx= itsc * D * cos(a); + ty= -itsc * D * sin(a); + sc= itsc * zoom; + rot= itsc * spin; + +} + +void DirectionalBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + const int iterations = pow(2.f, this->data->iter); + float col[4]= {0,0,0,0}; + float col2[4]= {0,0,0,0}; + this->inputProgram->read(col2, x, y, COM_PS_NEAREST, inputBuffers); + float ltx = tx; + float lty = ty; + float lsc = sc; + float lrot = rot; + /* blur the image */ + for(int i= 0; i < iterations; ++i) { + const float cs= cos(lrot), ss= sin(lrot); + const float isc= 1.f / (1.f + lsc); + + const float v= isc * (y - center_y_pix) + lty; + const float u= isc * (x - center_x_pix) + ltx; + + this->inputProgram->read(col, cs * u + ss * v + center_x_pix, cs * v - ss * u + center_y_pix, COM_PS_NEAREST, inputBuffers); + + col2[0] += col[0]; + col2[1] += col[1]; + col2[2] += col[2]; + col2[3] += col[3]; + + /* double transformations */ + ltx += tx; + lty += ty; + lrot += rot; + lsc += sc; + } + color[0] = col2[0]/iterations; + color[1] = col2[1]/iterations; + color[2] = col2[2]/iterations; + color[3] = col2[3]/iterations; +} + +void DirectionalBlurOperation::deinitExecution() { + this->inputProgram = NULL; +} + +bool DirectionalBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h new file mode 100644 index 00000000000..e82b451c102 --- /dev/null +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BokehDirectionalBlurOperation_h +#define _COM_DirectionalBlurOperation_h +#include "COM_NodeOperation.h" +#include "COM_QualityStepHelper.h" + +class DirectionalBlurOperation : public NodeOperation, public QualityStepHelper { +private: + SocketReader* inputProgram; + NodeDBlurData* data; + + float center_x_pix, center_y_pix; + float tx, ty; + float sc, rot; + +public: + DirectionalBlurOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setData(NodeDBlurData *data) {this->data = data;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp new file mode 100644 index 00000000000..b30ce5ac5b5 --- /dev/null +++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_DisplaceOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +DisplaceOperation::DisplaceOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VECTOR); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + + this->inputColorProgram = NULL; + this->inputVectorProgram = NULL; + this->inputScaleXProgram = NULL; + this->inputScaleYProgram = NULL; +} + +void DisplaceOperation::initExecution() { + this->inputColorProgram = this->getInputSocketReader(0); + this->inputVectorProgram = this->getInputSocketReader(1); + this->inputScaleXProgram = this->getInputSocketReader(2); + this->inputScaleYProgram = this->getInputSocketReader(3); + + width_x4 = this->getWidth() * 4; + height_x4 = this->getHeight() * 4; +} + + +/* minimum distance (in pixels) a pixel has to be displaced + * in order to take effect */ +#define DISPLACE_EPSILON 0.01f + +void DisplaceOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) +{ + float inVector[4]; + float inScale[4]; + + float p_dx, p_dy; /* main displacement in pixel space */ + float d_dx, d_dy; + float dxt, dyt; + float u, v; + + this->inputScaleXProgram->read(inScale, x, y, COM_PS_NEAREST, inputBuffers); + float xs = inScale[0]; + this->inputScaleYProgram->read(inScale, x, y, COM_PS_NEAREST, inputBuffers); + float ys = inScale[0]; + + /* clamp x and y displacement to triple image resolution - + * to prevent hangs from huge values mistakenly plugged in eg. z buffers */ + CLAMP(xs, -width_x4, width_x4); + CLAMP(ys, -height_x4, height_x4); + + this->inputVectorProgram->read(inVector, x, y, COM_PS_NEAREST, inputBuffers); + p_dx = inVector[0] * xs; + p_dy = inVector[1] * ys; + + /* displaced pixel in uv coords, for image sampling */ + u = x - p_dx + 0.5f; + v = y - p_dy + 0.5f; + + /* calc derivatives */ + this->inputVectorProgram->read(inVector, x+1, y, COM_PS_NEAREST, inputBuffers); + d_dx = inVector[0] * xs; + this->inputVectorProgram->read(inVector, x, y+1, COM_PS_NEAREST, inputBuffers); + d_dy = inVector[0] * ys; + + /* clamp derivatives to minimum displacement distance in UV space */ + dxt = p_dx - d_dx; + dyt = p_dy - d_dy; + + dxt = signf(dxt)*maxf(fabsf(dxt), DISPLACE_EPSILON)/this->getWidth(); + dyt = signf(dyt)*maxf(fabsf(dyt), DISPLACE_EPSILON)/this->getHeight(); + + /* EWA filtering */ + this->inputColorProgram->read(color, u, v, dxt, dyt, inputBuffers); +} + +void DisplaceOperation::deinitExecution() { + this->inputColorProgram = NULL; + this->inputVectorProgram = NULL; + this->inputScaleXProgram = NULL; + this->inputScaleYProgram = NULL; +} + +bool DisplaceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti colorInput; + rcti vectorInput; + NodeOperation *operation=NULL; + + /* the vector buffer only needs a 2x2 buffer. The image needs whole buffer */ + /* image */ + operation = getInputOperation(0); + colorInput.xmax = operation->getWidth(); + colorInput.xmin = 0; + colorInput.ymax = operation->getHeight(); + colorInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&colorInput, readOperation, output)) { + return true; + } + + /* vector */ + operation = getInputOperation(1); + vectorInput.xmax = input->xmax + 2; + vectorInput.xmin = input->xmin; + vectorInput.ymax = input->ymax + 2; + vectorInput.ymin = input->ymin; + if (operation->determineDependingAreaOfInterest(&vectorInput, readOperation, output)) { + return true; + } + + /* scale x */ + operation = getInputOperation(2); + if (operation->determineDependingAreaOfInterest(input, readOperation, output) ) { + return true; + } + + /* scale y */ + operation = getInputOperation(3); + if (operation->determineDependingAreaOfInterest(input, readOperation, output) ) { + return true; + } + + return false; +} + diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.h b/source/blender/compositor/operations/COM_DisplaceOperation.h new file mode 100644 index 00000000000..17f65eea20f --- /dev/null +++ b/source/blender/compositor/operations/COM_DisplaceOperation.h @@ -0,0 +1,63 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_DisplaceOperation_h +#define _COM_DisplaceOperation_h +#include "COM_NodeOperation.h" + + +class DisplaceOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader* inputColorProgram; + SocketReader* inputVectorProgram; + SocketReader* inputScaleXProgram; + SocketReader* inputScaleYProgram; + + float width_x4; + float height_x4; + +public: + DisplaceOperation(); + + /** + * we need a 2x2 differential filter for Vector Input and full buffer for the image + */ + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp new file mode 100644 index 00000000000..99d1eb1cd14 --- /dev/null +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp @@ -0,0 +1,127 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_DisplaceSimpleOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +DisplaceSimpleOperation::DisplaceSimpleOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VECTOR); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + + this->inputColorProgram = NULL; + this->inputVectorProgram = NULL; + this->inputScaleXProgram = NULL; + this->inputScaleYProgram = NULL; +} + +void DisplaceSimpleOperation::initExecution() { + this->inputColorProgram = this->getInputSocketReader(0); + this->inputVectorProgram = this->getInputSocketReader(1); + this->inputScaleXProgram = this->getInputSocketReader(2); + this->inputScaleYProgram = this->getInputSocketReader(3); + + width_x4 = this->getWidth() * 4; + height_x4 = this->getHeight() * 4; +} + + +/* minimum distance (in pixels) a pixel has to be displaced + * in order to take effect */ +#define DISPLACE_EPSILON 0.01f + +void DisplaceSimpleOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +{ + float inVector[4]; + float inScale[4]; + + float p_dx, p_dy; /* main displacement in pixel space */ + float u, v; + + this->inputScaleXProgram->read(inScale, x, y, sampler, inputBuffers); + float xs = inScale[0]; + this->inputScaleYProgram->read(inScale, x, y, sampler, inputBuffers); + float ys = inScale[0]; + + /* clamp x and y displacement to triple image resolution - + * to prevent hangs from huge values mistakenly plugged in eg. z buffers */ + CLAMP(xs, -width_x4, width_x4); + CLAMP(ys, -height_x4, height_x4); + + this->inputVectorProgram->read(inVector, x, y, sampler, inputBuffers); + p_dx = inVector[0] * xs; + p_dy = inVector[1] * ys; + + /* displaced pixel in uv coords, for image sampling */ + /* clamp nodes to avoid glitches */ + u = x - p_dx + 0.5f; + v = y - p_dy + 0.5f; + CLAMP(u, 0.f, this->getWidth()-1.f); + CLAMP(v, 0.f, this->getHeight()-1.f); + + this->inputColorProgram->read(color, u, v, sampler, inputBuffers); +} + +void DisplaceSimpleOperation::deinitExecution() { + this->inputColorProgram = NULL; + this->inputVectorProgram = NULL; + this->inputScaleXProgram = NULL; + this->inputScaleYProgram = NULL; +} + +bool DisplaceSimpleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti colorInput; + NodeOperation *operation=NULL; + + /* the vector buffer only needs a 2x2 buffer. The image needs whole buffer */ + /* image */ + operation = getInputOperation(0); + colorInput.xmax = operation->getWidth(); + colorInput.xmin = 0; + colorInput.ymax = operation->getHeight(); + colorInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&colorInput, readOperation, output)) { + return true; + } + + /* vector */ + if (operation->determineDependingAreaOfInterest(input, readOperation, output)) { + return true; + } + + /* scale x */ + operation = getInputOperation(2); + if (operation->determineDependingAreaOfInterest(input, readOperation, output) ) { + return true; + } + + /* scale y */ + operation = getInputOperation(3); + if (operation->determineDependingAreaOfInterest(input, readOperation, output) ) { + return true; + } + + return false; +} + diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h new file mode 100644 index 00000000000..88569954305 --- /dev/null +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h @@ -0,0 +1,63 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_DisplaceSimpleOperation_h +#define _COM_DisplaceSimpleOperation_h +#include "COM_NodeOperation.h" + + +class DisplaceSimpleOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader* inputColorProgram; + SocketReader* inputVectorProgram; + SocketReader* inputScaleXProgram; + SocketReader* inputScaleYProgram; + + float width_x4; + float height_x4; + +public: + DisplaceSimpleOperation(); + + /** + * we need a full buffer for the image + */ + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp new file mode 100644 index 00000000000..bef470ca9de --- /dev/null +++ b/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp @@ -0,0 +1,86 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_DistanceMatteOperation.h" +#include "BLI_math.h" + +DistanceMatteOperation::DistanceMatteOperation(): NodeOperation() { + addInputSocket(COM_DT_COLOR); + addInputSocket(COM_DT_COLOR); + addOutputSocket(COM_DT_VALUE); + + inputImageProgram = NULL; + inputKeyProgram = NULL; +} + +void DistanceMatteOperation::initExecution() { + this->inputImageProgram = this->getInputSocketReader(0); + this->inputKeyProgram = this->getInputSocketReader(1); +} + +void DistanceMatteOperation::deinitExecution() { + this->inputImageProgram= NULL; + this->inputKeyProgram= NULL; +} + +void DistanceMatteOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inKey[4]; + float inImage[4]; + + const float tolerence=this->settings->t1; + const float falloff=this->settings->t2; + + float distance; + float alpha; + + this->inputKeyProgram->read(inKey, x, y, sampler, inputBuffers); + this->inputImageProgram->read(inImage, x, y, sampler, inputBuffers); + + distance = sqrt(pow((inKey[0]-inImage[0]),2)+ + pow((inKey[1]-inImage[1]),2)+ + pow((inKey[2]-inImage[2]),2)); + + /* store matte(alpha) value in [0] to go with + * COM_SetAlphaOperation and the Value output + */ + + /*make 100% transparent */ + if(distance < tolerence) { + outputValue[0]=0.f; + } + /*in the falloff region, make partially transparent */ + else if(distance < falloff+tolerence){ + distance=distance-tolerence; + alpha=distance/falloff; + /*only change if more transparent than before */ + if(alpha < inImage[3]) { + outputValue[0]=alpha; + } + else { /* leave as before */ + outputValue[0]=inImage[3]; + } + } + else { + /* leave as before */ + outputValue[0]=inImage[3]; + } +} + diff --git a/source/blender/compositor/operations/COM_DistanceMatteOperation.h b/source/blender/compositor/operations/COM_DistanceMatteOperation.h new file mode 100644 index 00000000000..efa735445fa --- /dev/null +++ b/source/blender/compositor/operations/COM_DistanceMatteOperation.h @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_DistanceMatteOperation_h +#define _COM_DistanceMatteOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class DistanceMatteOperation : public NodeOperation { +private: + NodeChroma *settings; + SocketReader *inputImageProgram; + SocketReader *inputKeyProgram; +public: + /** + * Default constructor + */ + DistanceMatteOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeChroma* nodeChroma) {this->settings= nodeChroma;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_DotproductOperation.cpp b/source/blender/compositor/operations/COM_DotproductOperation.cpp new file mode 100644 index 00000000000..284fb0ddca4 --- /dev/null +++ b/source/blender/compositor/operations/COM_DotproductOperation.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_DotproductOperation.h" + +DotproductOperation::DotproductOperation() : NodeOperation() { + this->addInputSocket(COM_DT_VECTOR); + this->addInputSocket(COM_DT_VECTOR); + this->addOutputSocket(COM_DT_VALUE); + this->setResolutionInputSocketIndex(0); + this->input1Operation = NULL; + this->input2Operation = NULL; +} +void DotproductOperation::initExecution() { + this->input1Operation = this->getInputSocketReader(0); + this->input2Operation = this->getInputSocketReader(1); +} + +void DotproductOperation::deinitExecution() { + this->input1Operation = NULL; + this->input2Operation = NULL; +} + +/** @todo: current implementation is the inverse of a dotproduct. not 'logically' correct + */ +void DotproductOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float input1[4]; + float input2[4]; + this->input1Operation->read(input1, x, y, sampler, inputBuffers); + this->input2Operation->read(input2, x, y, sampler, inputBuffers); + color[0] = -(input1[0]*input2[0]+input1[1]*input2[1]+input1[2]*input2[2]); +} diff --git a/source/blender/compositor/operations/COM_DotproductOperation.h b/source/blender/compositor/operations/COM_DotproductOperation.h new file mode 100644 index 00000000000..0244fffa110 --- /dev/null +++ b/source/blender/compositor/operations/COM_DotproductOperation.h @@ -0,0 +1,41 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_DotproductOperation_h_ +#define _COM_DotproductOperation_h_ + +#include "COM_NodeOperation.h" + +class DotproductOperation: public NodeOperation { +private: + SocketReader *input1Operation; + SocketReader *input2Operation; +public: + DotproductOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp new file mode 100644 index 00000000000..cb6b27b9da1 --- /dev/null +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -0,0 +1,1195 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_DoubleEdgeMaskOperation.h" +#include "BLI_math.h" +#include "DNA_node_types.h" + +// this part has been copied from the double edge mask +// Contributor(s): Peter Larabell. +static void do_adjacentKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the right, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the right, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_adjacentBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if pixel underneath, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty above or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if pixel above, or to the left, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the left, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel to the left, or to the right, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if pixel underneath, or above, are empty in the inner mask, + // but filled in the outer mask + if((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_allKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the right + if(!limask[x-rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the left + if(!limask[x-rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the right + if(!limask[x+rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the left + if(!limask[x+rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_allBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize){ + int x; + unsigned int isz=0; // inner edge size + unsigned int osz=0; // outer edge size + unsigned int gsz=0; // gradient fill area size + /* Test the four corners */ + /* upper left corner */ + x=t-rw+1; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the right + if(!limask[x-rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* upper right corner */ + x=t; + // test if inner mask is filled + if(limask[x]){ + // test if the inner mask is empty underneath or to the left + if(!limask[x-rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower left corner */ + x=0; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the right + if(!limask[x+rw] || !limask[x+1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* lower right corner */ + x=rw-1; + // test if inner mask is filled + if(limask[x]){ + // test if inner mask is empty above or to the left + if(!limask[x+rw] || !limask[x-1]){ + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]){ // inner mask was empty, test if outer mask is filled + if(!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + /* Test the TOP row of pixels in buffer, except corners */ + for(x= t-1; x>=(t-rw)+2; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the BOTTOM row of pixels in buffer, except corners */ + for(x= rw-2; x; x--) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty to the left or to the right + if(!limask[x-1] || !limask[x+1]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + /* Test the LEFT edge of pixels in buffer, except corners */ + for(x= t-(rw<<1)+1; x>=rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + /* Test the RIGHT edge of pixels in buffer, except corners */ + for(x= t-rw; x>rw; x-=rw) { + // test if inner mask is filled + if(limask[x]) { + // test if inner mask is empty underneath or above + if(!limask[x-rw] || !limask[x+rw]) { + isz++; // increment inner edge size + lres[x]=4; // flag pixel as inner edge + } else { + res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge + } + } else if(lomask[x]) { // inner mask was empty, test if outer mask is filled + if(!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above + osz++; // increment outer edge size + lres[x]=3; // flag pixel as outer edge + } else { + gsz++; // increment the gradient pixel count + lres[x]=2; // flag pixel as gradient + } + } + } + + rsize[0]=isz; // fill in our return sizes for edges + fill + rsize[1]=osz; + rsize[2]=gsz; +} + +static void do_allEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz){ + int x; // x = pixel loop counter + int a; // a = pixel loop counter + int dx; // dx = delta x + int pix_prevRow; // pix_prevRow = pixel one row behind the one we are testing in a loop + int pix_nextRow; // pix_nextRow = pixel one row in front of the one we are testing in a loop + int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop + int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop + /* Test all rows between the FIRST and LAST rows, excluding left and right edges */ + for(x= (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw,dx-=rw) { + a=x-2; + pix_prevRow=a+rw; + pix_nextRow=a-rw; + pix_prevCol=a+1; + pix_nextCol=a-1; + while(a>dx-2) { + if(!limask[a]) { // if the inner mask is empty + if(lomask[a]) { // if the outer mask is full + /* + Next we test all 4 directions around the current pixel: next/prev/up/down + The test ensures that the outer mask is empty and that the inner mask + is also empty. If both conditions are true for any one of the 4 adjacent pixels + then the current pixel is counted as being a true outer edge pixel. + */ + if((!lomask[pix_nextCol] && !limask[pix_nextCol]) || + (!lomask[pix_prevCol] && !limask[pix_prevCol]) || + (!lomask[pix_nextRow] && !limask[pix_nextRow]) || + (!lomask[pix_prevRow] && !limask[pix_prevRow])) + { + in_osz++; // increment the outer boundary pixel count + lres[a]=3; // flag pixel as part of outer edge + } else { // it's not a boundary pixel, but it is a gradient pixel + in_gsz++; // increment the gradient pixel count + lres[a]=2; // flag pixel as gradient + } + } + + } else { + if(!limask[pix_nextCol] || !limask[pix_prevCol] || !limask[pix_nextRow] || !limask[pix_prevRow]) { + in_isz++; // increment the inner boundary pixel count + lres[a]=4; // flag pixel as part of inner edge + } else { + res[a]=1.0f; // pixel is part of inner mask, but not at an edge + } + } + a--; + pix_prevRow--; + pix_nextRow--; + pix_prevCol--; + pix_nextCol--; + } + } + + rsize[0]=in_isz; // fill in our return sizes for edges + fill + rsize[1]=in_osz; + rsize[2]=in_gsz; +} + +static void do_adjacentEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz){ + int x; // x = pixel loop counter + int a; // a = pixel loop counter + int dx; // dx = delta x + int pix_prevRow; // pix_prevRow = pixel one row behind the one we are testing in a loop + int pix_nextRow; // pix_nextRow = pixel one row in front of the one we are testing in a loop + int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop + int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop + /* Test all rows between the FIRST and LAST rows, excluding left and right edges */ + for(x= (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw,dx-=rw) { + a=x-2; + pix_prevRow=a+rw; + pix_nextRow=a-rw; + pix_prevCol=a+1; + pix_nextCol=a-1; + while(a>dx-2) { + if(!limask[a]) { // if the inner mask is empty + if(lomask[a]) { // if the outer mask is full + /* + Next we test all 4 directions around the current pixel: next/prev/up/down + The test ensures that the outer mask is empty and that the inner mask + is also empty. If both conditions are true for any one of the 4 adjacent pixels + then the current pixel is counted as being a true outer edge pixel. + */ + if((!lomask[pix_nextCol] && !limask[pix_nextCol]) || + (!lomask[pix_prevCol] && !limask[pix_prevCol]) || + (!lomask[pix_nextRow] && !limask[pix_nextRow]) || + (!lomask[pix_prevRow] && !limask[pix_prevRow])) + { + in_osz++; // increment the outer boundary pixel count + lres[a]=3; // flag pixel as part of outer edge + } else { // it's not a boundary pixel, but it is a gradient pixel + in_gsz++; // increment the gradient pixel count + lres[a]=2; // flag pixel as gradient + } + } + + } else { + if((!limask[pix_nextCol] && lomask[pix_nextCol]) || + (!limask[pix_prevCol] && lomask[pix_prevCol]) || + (!limask[pix_nextRow] && lomask[pix_nextRow]) || + (!limask[pix_prevRow] && lomask[pix_prevRow])) + { + in_isz++; // increment the inner boundary pixel count + lres[a]=4; // flag pixel as part of inner edge + } else { + res[a]=1.0f; // pixel is part of inner mask, but not at an edge + } + } + a--; + pix_prevRow--; // advance all four "surrounding" pixel pointers + pix_nextRow--; + pix_prevCol--; + pix_nextCol--; + } + } + + rsize[0]=in_isz; // fill in our return sizes for edges + fill + rsize[1]=in_osz; + rsize[2]=in_gsz; +} + +static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigned int *lres, float *res, unsigned short *gbuf, unsigned int *innerEdgeOffset, unsigned int *outerEdgeOffset, unsigned int isz, unsigned int gsz){ + int x; // x = pixel loop counter + int a; // a = temporary pixel index buffer loop counter + unsigned int ud; // ud = unscaled edge distance + unsigned int dmin; // dmin = minimun edge distance + + unsigned int rsl; // long used for finding fast 1.0/sqrt + unsigned int gradientFillOffset; + unsigned int innerAccum=0; // for looping inner edge pixel indexes, represents current position from offset + unsigned int outerAccum=0; // for looping outer edge pixel indexes, represents current position from offset + unsigned int gradientAccum=0; // for looping gradient pixel indexes, represents current position from offset + /* + Here we compute the size of buffer needed to hold (row,col) coordinates + for each pixel previously determined to be either gradient, inner edge, + or outer edge. + + Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even + though gbuf[] is declared as unsigned short* (2 bytes) because we don't + store the pixel indexes, we only store x,y location of pixel in buffer. + + This does make the assumption that x and y can fit in 16 unsigned bits + so if Blender starts doing renders greater than 65536 in either direction + this will need to allocate gbuf[] as unsigned int* and allocate 8 bytes + per flagged pixel. + + In general, the buffer on-screen: + + Example: 9 by 9 pixel block + + . = pixel non-white in both outer and inner mask + o = pixel white in outer, but not inner mask, adjacent to "." pixel + g = pixel white in outer, but not inner mask, not adjacent to "." pixel + i = pixel white in inner mask, adjacent to "g" or "." pixel + F = pixel white in inner mask, only adjacent to other pixels white in the inner mask + + + ......... <----- pixel #80 + ..oooo... + .oggggo.. + .oggiggo. + .ogiFigo. + .oggiggo. + .oggggo.. + ..oooo... + pixel #00 -----> ......... + + gsz = 18 (18 "g" pixels above) + isz = 4 (4 "i" pixels above) + osz = 18 (18 "o" pixels above) + + + The memory in gbuf[] after filling will look like this: + + gradientFillOffset (0 pixels) innerEdgeOffset (18 pixels) outerEdgeOffset (22 pixels) + / / / + / / / + |X Y X Y X Y X Y > <X Y X Y > <X Y X Y X Y > <X Y X Y | <- (x,y) + +--------------------------------> <----------------> <------------------------> <----------------+ + |0 2 4 6 8 10 12 14 > ... <68 70 72 74 > ... <80 82 84 86 88 90 > ... <152 154 156 158 | <- bytes + +--------------------------------> <----------------> <------------------------> <----------------+ + |g0 g0 g1 g1 g2 g2 g3 g3 > <g17 g17 i0 i0 > <i2 i2 i3 i3 o0 o0 > <o16 o16 o17 o17 | <- pixel + / / / + / / / + / / / + +---------- gradientAccum (18) ---------+ +--- innerAccum (22) ---+ +--- outerAccum (40) ---+ + + + Ultimately we do need the pixel's memory buffer index to set the output + pixel color, but it's faster to reconstruct the memory buffer location + each iteration of the final gradient calculation than it is to deconstruct + a memory location into x,y pairs each round. +*/ + + + gradientFillOffset=0; // since there are likely "more" of these, put it first. :) + *innerEdgeOffset=gradientFillOffset+gsz; // set start of inner edge indexes + *outerEdgeOffset=(*innerEdgeOffset)+isz; // set start of outer edge indexes + /* set the accumulators to correct positions */ // set up some accumulator variables for loops + gradientAccum = gradientFillOffset; // each accumulator variable starts at its respective + innerAccum = *innerEdgeOffset; // section's offset so when we start filling, each + outerAccum = *outerEdgeOffset; // section fills up it's allocated space in gbuf + //uses dmin=row, rsl=col + for(x=0,dmin=0; x<t; x+=rw,dmin++) { + for(rsl=0; rsl<rw; rsl++) { + a=x+rsl; + if(lres[a]==2) { // it is a gradient pixel flagged by 2 + ud=gradientAccum<<1; // double the index to reach correct unsigned short location + gbuf[ud]=dmin; // insert pixel's row into gradient pixel location buffer + gbuf[ud+1]=rsl; // insert pixel's column into gradient pixel location buffer + gradientAccum++; // increment gradient index buffer pointer + } else if(lres[a]==3) { // it is an outer edge pixel flagged by 3 + ud=outerAccum<<1; // double the index to reach correct unsigned short location + gbuf[ud]=dmin; // insert pixel's row into outer edge pixel location buffer + gbuf[ud+1]=rsl; // insert pixel's column into outer edge pixel location buffer + outerAccum++; // increment outer edge index buffer pointer + res[a]=0.0f; // set output pixel intensity now since it won't change later + } else if(lres[a]==4) { // it is an inner edge pixel flagged by 4 + ud=innerAccum<<1; // double int index to reach correct unsigned short location + gbuf[ud]=dmin; // insert pixel's row into inner edge pixel location buffer + gbuf[ud+1]=rsl; // insert pixel's column into inner edge pixel location buffer + innerAccum++; // increment inner edge index buffer pointer + res[a]=1.0f; // set output pixel intensity now since it won't change later + } + } + } + +} + +static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *gbuf, unsigned int isz, unsigned int osz, unsigned int gsz, unsigned int innerEdgeOffset, unsigned int outerEdgeOffset){ + int x; // x = pixel loop counter + int a; // a = temporary pixel index buffer loop counter + int fsz; // size of the frame + unsigned int rsl; // long used for finding fast 1.0/sqrt + float rsf; // float used for finding fast 1.0/sqrt + const float rsopf = 1.5f; // constant float used for finding fast 1.0/sqrt + + unsigned int gradientFillOffset; + unsigned int t; + unsigned int ud; // ud = unscaled edge distance + unsigned int dmin; // dmin = minimun edge distance + float odist; // odist = current outer edge distance + float idist; // idist = current inner edge distance + int dx; // dx = X-delta (used for distance proportion calculation) + int dy; // dy = Y-delta (used for distance proportion calculation) + + /* + The general algorithm used to color each gradient pixel is: + + 1.) Loop through all gradient pixels. + A.) For each gradient pixel: + a.) Loop though all outside edge pixels, looking for closest one + to the gradient pixel we are in. + b.) Loop through all inside edge pixels, looking for closest one + to the gradient pixel we are in. + c.) Find proportion of distance from gradient pixel to inside edge + pixel compared to sum of distance to inside edge and distance to + outside edge. + + In an image where: + . = blank (black) pixels, not covered by inner mask or outer mask + + = desired gradient pixels, covered only by outer mask + * = white full mask pixels, covered by at least inner mask + + ............................... + ...............+++++++++++..... + ...+O++++++..++++++++++++++.... + ..+++\++++++++++++++++++++..... + .+++++G+++++++++*******+++..... + .+++++|+++++++*********+++..... + .++***I****************+++..... + .++*******************+++...... + .+++*****************+++....... + ..+++***************+++........ + ....+++**********+++........... + ......++++++++++++............. + ............................... + + O = outside edge pixel + \ + G = gradient pixel + | + I = inside edge pixel + + __ + *note that IO does not need to be a straight line, in fact + many cases can arise where straight lines do not work + correctly. + + __ __ __ + d.) Pixel color is assigned as |GO| / ( |GI| + |GO| ) + + The implementation does not compute distance, but the reciprocal of the + distance. This is done to avoid having to compute a square root, as a + reciprocal square root can be computed faster. Therefore, the code computes + pixel color as |GI| / (|GI| + |GO|). Since these are reciprocals, GI serves the + purpose of GO for the proportion calculation. + + For the purposes of the minimun distance comparisons, we only check + the sums-of-squares against eachother, since they are in the same + mathematical sort-order as if we did go ahead and take square roots + + Loop through all gradient pixels. + */ + + for(x= gsz-1; x>=0; x--) { + gradientFillOffset=x<<1; + t=gbuf[gradientFillOffset]; // calculate column of pixel indexed by gbuf[x] + fsz=gbuf[gradientFillOffset+1]; // calculate row of pixel indexed by gbuf[x] + dmin=0xffffffff; // reset min distance to edge pixel + for(a=outerEdgeOffset+osz-1; a>=outerEdgeOffset; a--) { // loop through all outer edge buffer pixels + ud=a<<1; + dy=t-gbuf[ud]; // set dx to gradient pixel column - outer edge pixel row + dx=fsz-gbuf[ud+1]; // set dy to gradient pixel row - outer edge pixel column + ud=dx*dx+dy*dy; // compute sum of squares + if(ud<dmin) { // if our new sum of squares is less than the current minimum + dmin=ud; // set a new minimum equal to the new lower value + } + } + odist=(float)(dmin); // cast outer min to a float + rsf=odist*0.5f; // + rsl=*(unsigned int*)&odist; // use some peculiar properties of the way bits are stored + rsl=0x5f3759df-(rsl>>1); // in floats vs. unsigned ints to compute an approximate + odist=*(float*)&rsl; // reciprocal square root + odist=odist*(rsopf-(rsf*odist*odist)); // -- ** this line can be iterated for more accuracy ** -- + dmin=0xffffffff; // reset min distance to edge pixel + for(a= innerEdgeOffset+isz-1; a>=innerEdgeOffset; a--) { // loop through all inside edge pixels + ud=a<<1; + dy=t-gbuf[ud]; // compute delta in Y from gradient pixel to inside edge pixel + dx=fsz-gbuf[ud+1]; // compute delta in X from gradient pixel to inside edge pixel + ud=dx*dx+dy*dy; // compute sum of squares + if(ud<dmin) { // if our new sum of squares is less than the current minimum we've found + dmin=ud; // set a new minimum equal to the new lower value + } + } + idist=(float)(dmin); // cast inner min to a float + rsf=idist*0.5f; // + rsl=*(unsigned int*)&idist; // + rsl=0x5f3759df-(rsl>>1); // see notes above + idist=*(float*)&rsl; // + idist=idist*(rsopf-(rsf*idist*idist)); // + /* + Note once again that since we are using reciprocals of distance values our + proportion is already the correct intensity, and does not need to be + subracted from 1.0 like it would have if we used real distances. + */ + + /* + Here we reconstruct the pixel's memory location in the CompBuf by + Pixel Index = Pixel Column + ( Pixel Row * Row Width ) + */ + res[gbuf[gradientFillOffset+1]+(gbuf[gradientFillOffset]*rw)]=(idist/(idist+odist)); //set intensity + } + +} + +// end of copy + +void DoubleEdgeMaskOperation::doDoubleEdgeMask(float* imask, float *omask, float *res) { + + unsigned int *lres; // lres = unsigned int pointer to output pixel buffer (for bit operations) + unsigned int *limask; // limask = unsigned int pointer to inner mask (for bit operations) + unsigned int *lomask; // lomask = unsigned int pointer to outer mask (for bit operations) + + int rw; // rw = pixel row width + int t; // t = total number of pixels in buffer - 1 (used for loop starts) + int fsz; // size of the frame + + unsigned int isz=0; // size (in pixels) of inside edge pixel index buffer + unsigned int osz=0; // size (in pixels) of outside edge pixel index buffer + unsigned int gsz=0; // size (in pixels) of gradient pixel index buffer + unsigned int rsize[3]; // size storage to pass to helper functions + unsigned int innerEdgeOffset=0; // offset into final buffer where inner edge pixel indexes start + unsigned int outerEdgeOffset=0; // offset into final buffer where outer edge pixel indexes start + + unsigned short *gbuf; // gradient/inner/outer pixel location index buffer + + if(true) { // if both input sockets have some data coming in... + + t=(this->getWidth()*this->getHeight())-1; // determine size of the frame + + lres= (unsigned int*)res; // unsigned int pointer to output buffer (for bit level ops) + limask=(unsigned int*)imask; // unsigned int pointer to input mask (for bit level ops) + lomask=(unsigned int*)omask; // unsigned int pointer to output mask (for bit level ops) + rw= this->getWidth(); // width of a row of pixels + + + /* + The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the + LEFT and RIGHT edges (excluding the corner pixels), and all OTHER rows. + This allows for quick computation of outer edge pixels where + a screen edge pixel is marked to be gradient. + + The pixel type (gradient vs inner-edge vs outer-edge) tests change + depending on the user selected "Inner Edge Mode" and the user selected + "Buffer Edge Mode" on the node's GUI. There are 4 sets of basically the + same algorithm: + + 1.) Inner Edge -> Adjacent Only + Buffer Edge -> Keep Inside + + 2.) Inner Edge -> Adjacent Only + Buffer Edge -> Bleed Out + + 3.) Inner Edge -> All + Buffer Edge -> Keep Inside + + 4.) Inner Edge -> All + Buffer Edge -> Bleed Out + + Each version has slightly different criteria for detecting an edge pixel. + */ + if(this->adjecentOnly) { // if "adjacent only" inner edge mode is turned on + if(this->keepInside) { // if "keep inside" buffer edge mode is turned on + do_adjacentKeepBorders(t,rw,limask,lomask,lres,res,rsize); + }else{ // "bleed out" buffer edge mode is turned on + do_adjacentBleedBorders(t,rw,limask,lomask,lres,res,rsize); + } + isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass + osz=rsize[1]; + gsz=rsize[2]; + // detect edges in all non-border pixels in the buffer + do_adjacentEdgeDetection(t,rw,limask,lomask,lres,res,rsize,isz,osz,gsz); + }else{ // "all" inner edge mode is turned on + if(this->keepInside) { // if "keep inside" buffer edge mode is turned on + do_allKeepBorders(t,rw,limask,lomask,lres,res,rsize); + }else{ // "bleed out" buffer edge mode is turned on + do_allBleedBorders(t,rw,limask,lomask,lres,res,rsize); + } + isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass + osz=rsize[1]; + gsz=rsize[2]; + // detect edges in all non-border pixels in the buffer + do_allEdgeDetection(t,rw,limask,lomask,lres,res,rsize,isz,osz,gsz); + } + + isz=rsize[0]; // set edge and gradient buffer sizes once again... + osz=rsize[1]; // the sizes in rsize[] may have been modified + gsz=rsize[2]; // by the do_*EdgeDetection() function. + + fsz=gsz+isz+osz; // calculate size of pixel index buffer needed + gbuf= new unsigned short[fsz*2]; // allocate edge/gradient pixel index buffer + + do_createEdgeLocationBuffer(t,rw,lres,res,gbuf,&innerEdgeOffset,&outerEdgeOffset,isz,gsz); + do_fillGradientBuffer(rw,res,gbuf,isz,osz,gsz,innerEdgeOffset,outerEdgeOffset); + + delete gbuf; // free the gradient index buffer + } +} + +DoubleEdgeMaskOperation::DoubleEdgeMaskOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->inputInnerMask = NULL; + this->inputOuterMask = NULL; + this->adjecentOnly = false; + this->keepInside = false; + this->setComplex(true); +} + +bool DoubleEdgeMaskOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + if (this->cachedInstance == NULL) { + rcti newInput; + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } else { + return false; + } +} + +void DoubleEdgeMaskOperation::initExecution() { + this->inputInnerMask = this->getInputSocketReader(0); + this->inputOuterMask = this->getInputSocketReader(1); + initMutex(); + this->cachedInstance = NULL; +} + +void* DoubleEdgeMaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + if (this->cachedInstance) return this->cachedInstance; + + BLI_mutex_lock(getMutex()); + if (this->cachedInstance == NULL) { + MemoryBuffer* innerMask = (MemoryBuffer*)inputInnerMask->initializeTileData(rect, memoryBuffers); + MemoryBuffer* outerMask= (MemoryBuffer*)inputOuterMask->initializeTileData(rect, memoryBuffers); + float* data = new float[this->getWidth()*this->getHeight()]; + float* imask = innerMask->convertToValueBuffer(); + float* omask = outerMask->convertToValueBuffer(); + doDoubleEdgeMask(imask, omask, data); + delete imask; + delete omask; + this->cachedInstance = data; + } + BLI_mutex_unlock(getMutex()); + return this->cachedInstance; +} +void DoubleEdgeMaskOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float* buffer = (float*) data; + int index = (y*this->getWidth() + x); + color[0] = buffer[index]; + color[1] = buffer[index+1]; + color[2] = buffer[index+2]; + color[3] = buffer[index+3]; +} + +void DoubleEdgeMaskOperation::deinitExecution() { + this->inputInnerMask = NULL; + this->inputOuterMask = NULL; + deinitMutex(); + if (this->cachedInstance) { + delete cachedInstance; + this->cachedInstance = NULL; + } +} + diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h new file mode 100644 index 00000000000..f233570800a --- /dev/null +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_DoubleEdgeMaskOperation_h +#define _COM_DoubleEdgeMaskOperation_h +#include "COM_NodeOperation.h" + + +class DoubleEdgeMaskOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOuterMask; + SocketReader * inputInnerMask; + bool adjecentOnly; + bool keepInside; + float* cachedInstance; +public: + DoubleEdgeMaskOperation(); + + void doDoubleEdgeMask(float* inner, float *outer, float *res); + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setAdjecentOnly(bool adjecentOnly) {this->adjecentOnly = adjecentOnly;} + void setKeepInside(bool keepInside) {this->keepInside = keepInside;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp new file mode 100644 index 00000000000..033cb4da84d --- /dev/null +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp @@ -0,0 +1,114 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_EllipseMaskOperation.h" +#include "BLI_math.h" +#include "DNA_node_types.h" + +EllipseMaskOperation::EllipseMaskOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->inputMask = NULL; + this->inputValue = NULL; + this->cosine = 0.0f; + this->sine = 0.0f; +} +void EllipseMaskOperation::initExecution() { + this->inputMask = this->getInputSocketReader(0); + this->inputValue = this->getInputSocketReader(1); + const double rad = DEG2RAD(this->data->rotation); + this->cosine = cos(rad); + this->sine = sin(rad); + this->aspectRatio = ((float)this->getWidth())/this->getHeight(); +} + +void EllipseMaskOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputMask[4]; + float inputValue[4]; + + float rx = x/this->getWidth(); + float ry = y/this->getHeight(); + + const float dy = (ry - this->data->y)/this->aspectRatio; + const float dx = rx - this->data->x; + rx = this->data->x+(this->cosine*dx + this->sine*dy); + ry = this->data->y+(-this->sine*dx + this->cosine*dy); + + this->inputMask->read(inputMask, x, y, sampler, inputBuffers); + this->inputValue->read(inputValue, x, y, sampler, inputBuffers); + + const float halfHeight = (this->data->height)/2.0f; + const float halfWidth = this->data->width/2.0f; + float sx = rx-this->data->x; + sx *= sx; + const float tx = halfWidth * halfWidth; + float sy = ry-this->data->y; + sy *= sy; + const float ty = halfHeight * halfHeight; + + bool inside = ((sx/tx)+(sy/ty))<1.0f; + + switch (this->maskType) { + case CMP_NODE_MASKTYPE_ADD: + if (inside) { + color[0] = max(inputMask[0],inputValue[0]); + } else { + color[0] = inputMask[0]; + } + break; + case CMP_NODE_MASKTYPE_SUBTRACT: + if (inside) { + color[0] = inputMask[0]-inputValue[0]; + CLAMP(color[0], 0, 1); + } else { + color[0] = inputMask[0]; + } + break; + case CMP_NODE_MASKTYPE_MULTIPLY: + if (inside) { + color[0] = inputMask[0]*inputValue[0]; + } else { + color[0] = 0; + } + break; + case CMP_NODE_MASKTYPE_NOT: + if (inside) { + if (inputMask[0]>0.0f) { + color[0] = 0; + } else { + color[0] = inputValue[0]; + } + } else { + color[0] = inputMask[0]; + } + break; + } + + +} + +void EllipseMaskOperation::deinitExecution() { + this->inputMask = NULL; + this->inputValue = NULL; +} + diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h new file mode 100644 index 00000000000..969013782e6 --- /dev/null +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.h @@ -0,0 +1,65 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_EllipseMaskOperation_h +#define _COM_EllipseMaskOperation_h +#include "COM_NodeOperation.h" + + +class EllipseMaskOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputMask; + SocketReader * inputValue; + + float sine; + float cosine; + float aspectRatio; + int maskType; + + NodeEllipseMask *data; +public: + EllipseMaskOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setData(NodeEllipseMask *data) {this->data = data;} + + void setMaskType(int maskType) {this->maskType = maskType;} + +}; +#endif diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp new file mode 100644 index 00000000000..aae39694220 --- /dev/null +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_FastGaussianBlurOperation.h" +#include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" + +FastGaussianBlurOperation::FastGaussianBlurOperation(): BlurBaseOperation(){ + this->iirgaus = false; +} + +void FastGaussianBlurOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) { + MemoryBuffer *newData = (MemoryBuffer*)data; + + newData->read(color, x, y); +} + +bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output){ + rcti newInput; + rcti sizeInput; + sizeInput.xmin = 0; + sizeInput.ymin = 0; + sizeInput.xmax = 5; + sizeInput.ymax = 5; + + NodeOperation * operation = this->getInputOperation(1); + if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { + return true; + }else { + if(this->iirgaus){ + newInput.xmax = input->xmax + (sx); + newInput.xmin = input->xmin - (sx); + newInput.ymax = input->ymax + (sy); + newInput.ymin = input->ymin - (sy); + }else { + newInput.xmin = 0; + newInput.ymin = 0; + newInput.xmax = this->getWidth(); + newInput.ymax = this->getHeight(); + } + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} + +void* FastGaussianBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers){ + MemoryBuffer *newBuf = (MemoryBuffer*)this->inputProgram->initializeTileData(rect, memoryBuffers); + MemoryBuffer *copy = newBuf->duplicate(); + updateSize(memoryBuffers); + + int c; + sx = data->sizex * this->size/2.0f; + sy = data->sizey * this->size/2.0f; + this->iirgaus = true; + + if ((sx == sy) && (sx > 0.f)) { + for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(copy, sx, c, 3); + } + else { + if (sx > 0.f) { + for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(copy, sx, c, 1); + } + if (sy > 0.f) { + for (c=0; c<COM_NUMBER_OF_CHANNELS; ++c) + IIR_gauss(copy, sy, c, 2); + } + } + return copy; +} + +void FastGaussianBlurOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data){ + MemoryBuffer *newData = (MemoryBuffer*)data; + delete newData; +} + +void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, int chan, int xy) { + double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3]; + double *X, *Y, *W; + int i, x, y, sz; + float *buffer = src->getBuffer(); + + // <0.5 not valid, though can have a possibly useful sort of sharpening effect + if (sigma < 0.5f) return; + + if ((xy < 1) || (xy > 3)) xy = 3; + + // XXX The YVV macro defined below explicitly expects sources of at least 3x3 pixels, + // so just skiping blur along faulty direction if src's def is below that limit! + if (src->getWidth() < 3) xy &= ~(int) 1; + if (src->getHeight() < 3) xy &= ~(int) 2; + if (xy < 1) return; + + // see "Recursive Gabor Filtering" by Young/VanVliet + // all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200 + if (sigma >= 3.556f) + q = 0.9804f*(sigma - 3.556f) + 2.5091f; + else // sigma >= 0.5 + q = (0.0561f*sigma + 0.5784f)*sigma - 0.2568f; + q2 = q*q; + sc = (1.1668 + q)*(3.203729649 + (2.21566 + q)*q); + // no gabor filtering here, so no complex multiplies, just the regular coefs. + // all negated here, so as not to have to recalc Triggs/Sdika matrix + cf[1] = q*(5.788961737 + (6.76492 + 3.0*q)*q)/ sc; + cf[2] = -q2*(3.38246 + 3.0*q)/sc; + // 0 & 3 unchanged + cf[3] = q2*q/sc; + cf[0] = 1.0 - cf[1] - cf[2] - cf[3]; + + // Triggs/Sdika border corrections, + // it seems to work, not entirely sure if it is actually totally correct, + // Besides J.M.Geusebroek's anigauss.c (see http://www.science.uva.nl/~mark), + // found one other implementation by Cristoph Lampert, + // but neither seem to be quite the same, result seems to be ok so far anyway. + // Extra scale factor here to not have to do it in filter, + // though maybe this had something to with the precision errors + sc = cf[0]/((1.0 + cf[1] - cf[2] + cf[3])*(1.0 - cf[1] - cf[2] - cf[3])*(1.0 + cf[2] + (cf[1] - cf[3])*cf[3])); + tsM[0] = sc*(-cf[3]*cf[1] + 1.0 - cf[3]*cf[3] - cf[2]); + tsM[1] = sc*((cf[3] + cf[1])*(cf[2] + cf[3]*cf[1])); + tsM[2] = sc*(cf[3]*(cf[1] + cf[3]*cf[2])); + tsM[3] = sc*(cf[1] + cf[3]*cf[2]); + tsM[4] = sc*(-(cf[2] - 1.0)*(cf[2] + cf[3]*cf[1])); + tsM[5] = sc*(-(cf[3]*cf[1] + cf[3]*cf[3] + cf[2] - 1.0)*cf[3]); + tsM[6] = sc*(cf[3]*cf[1] + cf[2] + cf[1]*cf[1] - cf[2]*cf[2]); + tsM[7] = sc*(cf[1]*cf[2] + cf[3]*cf[2]*cf[2] - cf[1]*cf[3]*cf[3] - cf[3]*cf[3]*cf[3] - cf[3]*cf[2] + cf[3]); + tsM[8] = sc*(cf[3]*(cf[1] + cf[3]*cf[2])); + +#define YVV(L) \ +{ \ +W[0] = cf[0]*X[0] + cf[1]*X[0] + cf[2]*X[0] + cf[3]*X[0]; \ +W[1] = cf[0]*X[1] + cf[1]*W[0] + cf[2]*X[0] + cf[3]*X[0]; \ +W[2] = cf[0]*X[2] + cf[1]*W[1] + cf[2]*W[0] + cf[3]*X[0]; \ +for (i=3; i<L; i++) \ +W[i] = cf[0]*X[i] + cf[1]*W[i-1] + cf[2]*W[i-2] + cf[3]*W[i-3]; \ +tsu[0] = W[L-1] - X[L-1]; \ +tsu[1] = W[L-2] - X[L-1]; \ +tsu[2] = W[L-3] - X[L-1]; \ +tsv[0] = tsM[0]*tsu[0] + tsM[1]*tsu[1] + tsM[2]*tsu[2] + X[L-1]; \ +tsv[1] = tsM[3]*tsu[0] + tsM[4]*tsu[1] + tsM[5]*tsu[2] + X[L-1]; \ +tsv[2] = tsM[6]*tsu[0] + tsM[7]*tsu[1] + tsM[8]*tsu[2] + X[L-1]; \ +Y[L-1] = cf[0]*W[L-1] + cf[1]*tsv[0] + cf[2]*tsv[1] + cf[3]*tsv[2]; \ +Y[L-2] = cf[0]*W[L-2] + cf[1]*Y[L-1] + cf[2]*tsv[0] + cf[3]*tsv[1]; \ +Y[L-3] = cf[0]*W[L-3] + cf[1]*Y[L-2] + cf[2]*Y[L-1] + cf[3]*tsv[0]; \ +for (i=L-4; i>=0; i--) \ +Y[i] = cf[0]*W[i] + cf[1]*Y[i+1] + cf[2]*Y[i+2] + cf[3]*Y[i+3]; \ +} + + // intermediate buffers + sz = MAX2(src->getWidth(), src->getHeight()); + X = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss X buf"); + Y = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss Y buf"); + W = (double*)MEM_callocN(sz*sizeof(double), "IIR_gauss W buf"); + if (xy & 1) { // H + for (y=0; y<src->getHeight(); ++y) { + const int yx = y*src->getWidth(); + for (x=0; x<src->getWidth(); ++x) + X[x] = buffer[(x + yx)*COM_NUMBER_OF_CHANNELS + chan]; + YVV(src->getWidth()); + for (x=0; x<src->getWidth(); ++x) + buffer[(x + yx)*COM_NUMBER_OF_CHANNELS + chan] = Y[x]; + } + } + if (xy & 2) { // V + for (x=0; x<src->getWidth(); ++x) { + for (y=0; y<src->getHeight(); ++y) + X[y] = buffer[(x + y*src->getWidth())*COM_NUMBER_OF_CHANNELS + chan]; + YVV(src->getHeight()); + for (y=0; y<src->getHeight(); ++y) + buffer[(x + y*src->getWidth())*COM_NUMBER_OF_CHANNELS + chan] = Y[y]; + } + } + + MEM_freeN(X); + MEM_freeN(W); + MEM_freeN(Y); +#undef YVV + +} diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h new file mode 100644 index 00000000000..3e1d5416ca7 --- /dev/null +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_FastGaussianBlurOperation_h +#define _COM_FastGaussianBlurOperation_h + +#include "COM_BlurBaseOperation.h" +#include "DNA_node_types.h" + +class FastGaussianBlurOperation: public BlurBaseOperation { +private: + float sx; + float sy; + bool iirgaus; +public: + FastGaussianBlurOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + + void IIR_gauss(MemoryBuffer *src, float sigma, int channel, int xy); + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); + +}; +#endif + diff --git a/source/blender/compositor/operations/COM_FlipOperation.cpp b/source/blender/compositor/operations/COM_FlipOperation.cpp new file mode 100644 index 00000000000..afe3173ab0f --- /dev/null +++ b/source/blender/compositor/operations/COM_FlipOperation.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_FlipOperation.h" + +FlipOperation::FlipOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputOperation = NULL; + this->flipX = true; + this->flipY = false; +} +void FlipOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void FlipOperation::deinitExecution() { + this->inputOperation = NULL; +} + + +void FlipOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float nx = this->flipX?this->getWidth()-1-x:x; + float ny = this->flipY?this->getHeight()-1-y:y; + + this->inputOperation->read(color, nx, ny, sampler, inputBuffers); +} + +bool FlipOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + if (this->flipX) { + newInput.xmax = (this->getWidth()- 1 - input->xmin)+1; + newInput.xmin = (this->getWidth()- 1 - input->xmax)-1; + } else { + newInput.xmin = input->xmin; + newInput.xmax = input->xmax; + } + if (this->flipY) { + newInput.ymax = (this->getHeight()- 1 - input->ymin)+1; + newInput.ymin = (this->getHeight()- 1 - input->ymax)-1; + } else { + newInput.ymin = input->ymin; + newInput.ymax = input->ymax; + } + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_FlipOperation.h b/source/blender/compositor/operations/COM_FlipOperation.h new file mode 100644 index 00000000000..9774cfd7bcd --- /dev/null +++ b/source/blender/compositor/operations/COM_FlipOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_FlipOperation_h_ +#define _COM_FlipOperation_h_ + +#include "COM_NodeOperation.h" + +class FlipOperation: public NodeOperation { +private: + SocketReader *inputOperation; + bool flipX; + bool flipY; +public: + FlipOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + void setFlipX(bool flipX) {this->flipX = flipX;} + void setFlipY(bool flipY) {this->flipY = flipY;} +}; + +#endif diff --git a/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp b/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp new file mode 100644 index 00000000000..a81597322a0 --- /dev/null +++ b/source/blender/compositor/operations/COM_FogGlowImageOperation.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_FogGlowImageOperation.h" +#include "BLI_math.h" + +FogGlowImageOperation::FogGlowImageOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_COLOR); +} +void FogGlowImageOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f; + + float u, v, w, d, r; + + v = 2.f*(y / (float)512) - 1.f; + u = 2.f*(x / (float)512) - 1.f; + r = (u*u + v*v)*256; + d = -sqrtf(sqrtf(sqrtf(r))); + w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI)); + color[0] = expf(d*cs_r) * w; + color[1] = expf(d*cs_g) * w; + color[2] = expf(d*cs_b) * w; + color[3] = 1.0f; +} + +void FogGlowImageOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + resolution[0] = 512; + resolution[1] = 512; +} diff --git a/source/blender/compositor/operations/COM_FogGlowImageOperation.h b/source/blender/compositor/operations/COM_FogGlowImageOperation.h new file mode 100644 index 00000000000..f68346eeb8d --- /dev/null +++ b/source/blender/compositor/operations/COM_FogGlowImageOperation.h @@ -0,0 +1,39 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_FogGlowOperation_h +#define _COM_FogGlowOperation_h +#include "COM_NodeOperation.h" +#include "DNA_lamp_types.h" + +class FogGlowImageOperation : public NodeOperation { +public: + FogGlowImageOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp new file mode 100644 index 00000000000..c83c5d0ecb6 --- /dev/null +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp @@ -0,0 +1,98 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GammaCorrectOperation.h" +#include "BLI_math.h" + +GammaCorrectOperation::GammaCorrectOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputProgram = NULL; +} +void GammaCorrectOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); +} + +void GammaCorrectOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + this->inputProgram->read(inputColor, x, y, sampler, inputBuffers); + if (inputColor[3] > 0.0f) { + inputColor[0] /= inputColor[3]; + inputColor[1] /= inputColor[3]; + inputColor[2] /= inputColor[3]; + } + + /* check for negative to avoid nan's */ + color[0] = inputColor[0]>0.0f?inputColor[0]*inputColor[0] :0.0f; + color[1] = inputColor[1]>0.0f?inputColor[1]*inputColor[1] :0.0f; + color[2] = inputColor[2]>0.0f?inputColor[2]*inputColor[2] :0.0f; + + inputColor[0] *= inputColor[3]; + inputColor[1] *= inputColor[3]; + inputColor[2] *= inputColor[3]; + + color[0] = inputColor[0]; + color[1] = inputColor[1]; + color[2] = inputColor[2]; + color[3] = inputColor[3]; +} + +void GammaCorrectOperation::deinitExecution() { + this->inputProgram = NULL; +} + +GammaUncorrectOperation::GammaUncorrectOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputProgram = NULL; +} +void GammaUncorrectOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); +} + +void GammaUncorrectOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor[4]; + this->inputProgram->read(inputColor, x, y, sampler, inputBuffers); + + if (inputColor[3] > 0.0f) { + inputColor[0] /= inputColor[3]; + inputColor[1] /= inputColor[3]; + inputColor[2] /= inputColor[3]; + } + + color[0] = inputColor[0]>0.0f?sqrtf(inputColor[0]) :0.0f; + color[1] = inputColor[1]>0.0f?sqrtf(inputColor[1]) :0.0f; + color[2] = inputColor[2]>0.0f?sqrtf(inputColor[2]) :0.0f; + + inputColor[0] *= inputColor[3]; + inputColor[1] *= inputColor[3]; + inputColor[2] *= inputColor[3]; + + color[0] = inputColor[0]; + color[1] = inputColor[1]; + color[2] = inputColor[2]; + color[3] = inputColor[3]; +} + +void GammaUncorrectOperation::deinitExecution() { + this->inputProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.h b/source/blender/compositor/operations/COM_GammaCorrectOperation.h new file mode 100644 index 00000000000..bcf78f4508a --- /dev/null +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.h @@ -0,0 +1,80 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GammaCorrectOperation_h +#define _COM_GammaCorrectOperation_h +#include "COM_NodeOperation.h" + + +class GammaCorrectOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + +public: + GammaCorrectOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; + +class GammaUncorrectOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + +public: + GammaUncorrectOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_GammaOperation.cpp b/source/blender/compositor/operations/COM_GammaOperation.cpp new file mode 100644 index 00000000000..eaa56c2f31a --- /dev/null +++ b/source/blender/compositor/operations/COM_GammaOperation.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GammaOperation.h" +#include "BLI_math.h" + +GammaOperation::GammaOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->inputProgram = NULL; + this->inputGammaProgram = NULL; +} +void GammaOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); + this->inputGammaProgram = this->getInputSocketReader(1); +} + +void GammaOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + float inputGamma[4]; + + this->inputProgram->read(inputValue, x, y, sampler, inputBuffers); + this->inputGammaProgram->read(inputGamma, x, y, sampler, inputBuffers); + const float gamma = inputGamma[0]; + /* check for negative to avoid nan's */ + color[0] = inputValue[0]>0.0f?pow(inputValue[0], gamma):inputValue[0]; + color[1] = inputValue[1]>0.0f?pow(inputValue[1], gamma):inputValue[1]; + color[2] = inputValue[2]>0.0f?pow(inputValue[2], gamma):inputValue[2]; + + color[3] = inputValue[3]; +} + +void GammaOperation::deinitExecution() { + this->inputProgram = NULL; + this->inputGammaProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h new file mode 100644 index 00000000000..0fbbf58bad6 --- /dev/null +++ b/source/blender/compositor/operations/COM_GammaOperation.h @@ -0,0 +1,54 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GammaOperation_h +#define _COM_GammaOperation_h +#include "COM_NodeOperation.h" + + +class GammaOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + SocketReader* inputGammaProgram; + +public: + GammaOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp new file mode 100644 index 00000000000..9b7df61143e --- /dev/null +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -0,0 +1,174 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GaussianBokehBlurOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +GaussianBokehBlurOperation::GaussianBokehBlurOperation(): BlurBaseOperation() { + this->gausstab = NULL; +} + +void* GaussianBokehBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + updateGauss(memoryBuffers); + void* buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void GaussianBokehBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { + if (this->gausstab == NULL) { + float radxf; + float radyf; + int n; + float* dgauss; + float* ddgauss; + float val; + int j, i; + const float width = this->getWidth(); + const float height = this->getHeight(); + updateSize(memoryBuffers); + + radxf = size*(float)this->data->sizex; + if(radxf>width/2.0f) + radxf= width/2.0f; + else if(radxf<1.0f) + radxf= 1.0f; + + /* vertical */ + radyf = size*(float)this->data->sizey; + if(radyf>height/2.0f) + radyf= height/2.0f; + else if(radyf<1.0f) + radyf= 1.0f; + + radx= ceil(radxf); + rady= ceil(radyf); + + n = (2*radx+1)*(2*rady+1); + + /* create a full filter image */ + ddgauss= new float[n]; + dgauss= ddgauss; + val= 0.0f; + for(j=-rady; j<=rady; j++) { + for(i=-radx; i<=radx; i++, dgauss++) { + float fj= (float)j/radyf; + float fi= (float)i/radxf; + float dist= sqrt(fj*fj + fi*fi); + *dgauss= RE_filter_value(this->data->filtertype, dist); + + val+= *dgauss; + } + } + if(val!=0.0f) { + val= 1.0f/val; + for(j= n -1; j>=0; j--) + ddgauss[j]*= val; + } + else ddgauss[4]= 1.0f; + + gausstab = ddgauss; + } +} + +void GaussianBokehBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float tempColor[4]; + tempColor[0] = 0; + tempColor[1] = 0; + tempColor[2] = 0; + tempColor[3] = 0; + float overallmultiplyer = 0; + MemoryBuffer* inputBuffer = (MemoryBuffer*)data; + float* buffer = inputBuffer->getBuffer(); + int bufferwidth = inputBuffer->getWidth(); + int bufferstartx = inputBuffer->getRect()->xmin; + int bufferstarty = inputBuffer->getRect()->ymin; + + int miny = y - this->rady; + int maxy = y + this->rady; + int minx = x - this->radx; + int maxx = x + this->radx; + miny = max(miny, inputBuffer->getRect()->ymin); + minx = max(minx, inputBuffer->getRect()->xmin); + maxy = min(maxy, inputBuffer->getRect()->ymax); + maxx = min(maxx, inputBuffer->getRect()->xmax); + + int index = 0; + int step = QualityStepHelper::getStep(); + int offsetadd = QualityStepHelper::getOffsetAdd(); + for (int ny = miny ; ny < maxy ; ny +=step) { + int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); + for (int nx = minx ; nx < maxx ; nx +=step) { + float multiplyer = gausstab[index]; + tempColor[0] += multiplyer * buffer[bufferindex]; + tempColor[1] += multiplyer * buffer[bufferindex+1]; + tempColor[2] += multiplyer * buffer[bufferindex+2]; + tempColor[3] += multiplyer * buffer[bufferindex+3]; + overallmultiplyer += multiplyer; + index += step; + bufferindex +=offsetadd; + } + } + float divider = 1.0/overallmultiplyer; + color[0] = tempColor[0]*divider; + color[1] = tempColor[1]*divider; + color[2] = tempColor[2]*divider; + color[3] = tempColor[3]*divider; +} + +void GaussianBokehBlurOperation::deinitExecution() { + BlurBaseOperation::deinitExecution(); + delete this->gausstab; + this->gausstab = NULL; +} + +bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + rcti sizeInput; + sizeInput.xmin = 0; + sizeInput.ymin = 0; + sizeInput.xmax = 5; + sizeInput.ymax = 5; + NodeOperation * operation = this->getInputOperation(1); + + if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { + return true; + } else { + if (this->gausstab) { + int addx = radx; + int addy = rady; + newInput.xmax = input->xmax + addx; + newInput.xmin = input->xmin - addx; + newInput.ymax = input->ymax + addy; + newInput.ymin = input->ymin - addy; + } else { + newInput.xmin = 0; + newInput.ymin = 0; + newInput.xmax = this->getWidth(); + newInput.ymax = this->getHeight(); + } + return BlurBaseOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h new file mode 100644 index 00000000000..806f77fd375 --- /dev/null +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BokehGaussianBokehBlurOperation_h +#define _COM_GaussianBokehBlurOperation_h +#include "COM_NodeOperation.h" +#include "COM_BlurBaseOperation.h" +#include "COM_QualityStepHelper.h" + +class GaussianBokehBlurOperation : public BlurBaseOperation { +private: + float* gausstab; + int radx, rady; + void updateGauss(MemoryBuffer **memoryBuffers); + +public: + GaussianBokehBlurOperation(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +}; +#endif diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp new file mode 100644 index 00000000000..a93c0e44d18 --- /dev/null +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GaussianXBlurOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +GaussianXBlurOperation::GaussianXBlurOperation(): BlurBaseOperation() { + this->gausstab = NULL; + this->rad = 0; + +} + +void* GaussianXBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + updateGauss(memoryBuffers); + void* buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void GaussianXBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { + if (this->gausstab == NULL) { + updateSize(memoryBuffers); + float rad = size*this->data->sizex; + if(rad<1) + rad= 1; + + this->rad = rad; + this->gausstab = BlurBaseOperation::make_gausstab(rad); + } +} + +void GaussianXBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { + + float tempColor[4]; + tempColor[0] = 0; + tempColor[1] = 0; + tempColor[2] = 0; + tempColor[3] = 0; + float overallmultiplyer = 0; + MemoryBuffer* inputBuffer = (MemoryBuffer*)data; + float* buffer = inputBuffer->getBuffer(); + int bufferwidth = inputBuffer->getWidth(); + int bufferstartx = inputBuffer->getRect()->xmin; + int bufferstarty = inputBuffer->getRect()->ymin; + + int miny = y; + int maxy = y; + int minx = x - this->rad; + int maxx = x + this->rad; + miny = max(miny, inputBuffer->getRect()->ymin); + minx = max(minx, inputBuffer->getRect()->xmin); + maxy = min(maxy, inputBuffer->getRect()->ymax); + maxx = min(maxx, inputBuffer->getRect()->xmax); + + int index = 0; + int step = getStep(); + int offsetadd = getOffsetAdd(); + int bufferindex = ((minx - bufferstartx)*4)+((miny-bufferstarty)*4*bufferwidth); + for (int nx = minx ; nx < maxx ; nx +=step) { + float multiplyer = gausstab[index++]; + tempColor[0] += multiplyer * buffer[bufferindex]; + tempColor[1] += multiplyer * buffer[bufferindex+1]; + tempColor[2] += multiplyer * buffer[bufferindex+2]; + tempColor[3] += multiplyer * buffer[bufferindex+3]; + overallmultiplyer += multiplyer; + bufferindex +=offsetadd; + } + float divider = 1.0/overallmultiplyer; + color[0] = tempColor[0]*divider; + color[1] = tempColor[1]*divider; + color[2] = tempColor[2]*divider; + color[3] = tempColor[3]*divider; +} + +void GaussianXBlurOperation::deinitExecution() { + BlurBaseOperation::deinitExecution(); + delete this->gausstab; + this->gausstab = NULL; +} + +bool GaussianXBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + rcti sizeInput; + sizeInput.xmin = 0; + sizeInput.ymin = 0; + sizeInput.xmax = 5; + sizeInput.ymax = 5; + + NodeOperation * operation = this->getInputOperation(1); + if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { + return true; + }else { + if (this->gausstab == NULL) { + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + }else{ + newInput.xmax = input->xmax + rad; + newInput.xmin = input->xmin - rad; + newInput.ymax = input->ymax; + newInput.ymin = input->ymin; + } + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h new file mode 100644 index 00000000000..6b6eb4d80f9 --- /dev/null +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -0,0 +1,49 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GaussianXBlurOperation_h +#define _COM_GaussianXBlurOperation_h +#include "COM_NodeOperation.h" +#include "COM_BlurBaseOperation.h" + +class GaussianXBlurOperation : public BlurBaseOperation { +private: + float* gausstab; + int rad; + void updateGauss(MemoryBuffer **memoryBuffers); +public: + GaussianXBlurOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +}; +#endif diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp new file mode 100644 index 00000000000..86f9dbf5c40 --- /dev/null +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -0,0 +1,125 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GaussianYBlurOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +GaussianYBlurOperation::GaussianYBlurOperation(): BlurBaseOperation() { + this->gausstab = NULL; + this->rad = 0; +} + +void* GaussianYBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + updateGauss(memoryBuffers); + void* buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void GaussianYBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { + if (this->gausstab == NULL) { + updateSize(memoryBuffers); + float rad = size*this->data->sizey; + if(rad<1) + rad= 1; + + this->rad = rad; + this->gausstab = BlurBaseOperation::make_gausstab(rad); + } +} + +void GaussianYBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void *data) { + + float tempColor[4]; + tempColor[0] = 0; + tempColor[1] = 0; + tempColor[2] = 0; + tempColor[3] = 0; + float overallmultiplyer = 0; + MemoryBuffer* inputBuffer = (MemoryBuffer*)data; + float* buffer = inputBuffer->getBuffer(); + int bufferwidth = inputBuffer->getWidth(); + int bufferstartx = inputBuffer->getRect()->xmin; + int bufferstarty = inputBuffer->getRect()->ymin; + + int miny = y - this->rad; + int maxy = y + this->rad; + int minx = x; + int maxx = x; + miny = max(miny, inputBuffer->getRect()->ymin); + minx = max(minx, inputBuffer->getRect()->xmin); + maxy = min(maxy, inputBuffer->getRect()->ymax); + maxx = min(maxx, inputBuffer->getRect()->xmax); + + int step = getStep(); + int index = 0; + for (int ny = miny ; ny < maxy ; ny +=step) { + int bufferindex = ((minx - bufferstartx)*4)+((ny-bufferstarty)*4*bufferwidth); + float multiplyer = gausstab[index++]; + tempColor[0] += multiplyer * buffer[bufferindex]; + tempColor[1] += multiplyer * buffer[bufferindex+1]; + tempColor[2] += multiplyer * buffer[bufferindex+2]; + tempColor[3] += multiplyer * buffer[bufferindex+3]; + overallmultiplyer += multiplyer; + } + float divider = 1.0/overallmultiplyer; + color[0] = tempColor[0]*divider; + color[1] = tempColor[1]*divider; + color[2] = tempColor[2]*divider; + color[3] = tempColor[3]*divider; +} + +void GaussianYBlurOperation::deinitExecution() { + BlurBaseOperation::deinitExecution(); + delete this->gausstab; + this->gausstab = NULL; +} + +bool GaussianYBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + rcti sizeInput; + sizeInput.xmin = 0; + sizeInput.ymin = 0; + sizeInput.xmax = 5; + sizeInput.ymax = 5; + + NodeOperation * operation = this->getInputOperation(1); + if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) { + return true; + }else { + if (this->gausstab == NULL) { + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + } else { + newInput.xmax = input->xmax; + newInput.xmin = input->xmin; + newInput.ymax = input->ymax + rad; + newInput.ymin = input->ymin - rad; + } + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h new file mode 100644 index 00000000000..5c116e80a71 --- /dev/null +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h @@ -0,0 +1,49 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GaussianYBlurOperation_h +#define _COM_GaussianYBlurOperation_h +#include "COM_NodeOperation.h" +#include "COM_BlurBaseOperation.h" + +class GaussianYBlurOperation : public BlurBaseOperation { +private: + float* gausstab; + int rad; + void updateGauss(MemoryBuffer **memoryBuffers); +public: + GaussianYBlurOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +}; +#endif diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp new file mode 100644 index 00000000000..b86c61ea9da --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GlareBaseOperation.h" +#include "BLI_math.h" + +GlareBaseOperation::GlareBaseOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->settings = NULL; + this->cachedInstance = NULL; + setComplex(true); +} +void GlareBaseOperation::initExecution() { + initMutex(); + this->inputProgram = getInputSocketReader(0); + this->cachedInstance = NULL; +} + +void GlareBaseOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float* buffer = (float*) data; + int index = (y*this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; + color[0] = buffer[index]; + color[1] = buffer[index+1]; + color[2] = buffer[index+2]; + color[3] = buffer[index+3]; +} + +void GlareBaseOperation::deinitExecution() { + deinitMutex(); + this->inputProgram = NULL; + if (this->cachedInstance) { + delete cachedInstance; + this->cachedInstance = NULL; + } +} +void* GlareBaseOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + BLI_mutex_lock(getMutex()); + if (this->cachedInstance == NULL) { + MemoryBuffer* tile = (MemoryBuffer*)inputProgram->initializeTileData(rect, memoryBuffers); + float* data = new float[this->getWidth()*this->getHeight()*COM_NUMBER_OF_CHANNELS]; + this->generateGlare(data, tile, this->settings); + this->cachedInstance = data; + } + BLI_mutex_unlock(getMutex()); + return this->cachedInstance; +} + +bool GlareBaseOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h new file mode 100644 index 00000000000..4233e6150a2 --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -0,0 +1,70 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GlareBaseOperation_h +#define _COM_GlareBaseOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" + +class GlareBaseOperation : public NodeOperation { +private: + /** + * @brief Cached reference to the inputProgram + */ + SocketReader * inputProgram; + + /** + * @brief settings of the glare node. + */ + NodeGlare * settings; + + float* cachedInstance; + +public: + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setGlareSettings(NodeGlare * settings) {this->settings = settings;} + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +protected: + GlareBaseOperation(); + + virtual void generateGlare(float* data, MemoryBuffer* inputTile, NodeGlare* settings) = 0; + + +}; +#endif diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp new file mode 100644 index 00000000000..ce3fd82acf0 --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GlareSimpleStarOperation.h" + +void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) { + int i, x, y, ym, yp, xm, xp; + float c[4] = {0,0,0,0}, tc[4] = {0,0,0,0}; + const float f1 = 1.f - settings->fade, f2 = (1.f - f1)*0.5f; + + + MemoryBuffer* tbuf1 = inputTile->duplicate(); + MemoryBuffer* tbuf2 = inputTile->duplicate(); + + for (i=0; i<settings->iter; i++) { +// // (x || x-1, y-1) to (x || x+1, y+1) +// // F + for (y=0; y<this->getHeight(); y++) { + ym = y - i; + yp = y + i; + for (x=0; x<this->getWidth(); x++) { + xm = x - i; + xp = x + i; + tbuf1->read(c, x, y); + c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + tbuf1->read(tc, (settings->angle ? xm : x), ym); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + tbuf1->read(tc, (settings->angle ? xp : x), yp); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + c[3] = 1.0f; + tbuf1->writePixel(x, y, c); + + tbuf2->read(c, x, y); + c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + tbuf2->read(tc, xm, (settings->angle ? yp : y)); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + tbuf2->read(tc, xp, (settings->angle ? ym : y)); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + c[3] = 1.0f; + tbuf2->writePixel(x, y, c); + + } + } +// // B + for (y=tbuf1->getHeight()-1; y>=0; y--) { + ym = y - i; + yp = y + i; + for (x=tbuf1->getWidth()-1; x>=0; x--) { + xm = x - i; + xp = x + i; + tbuf1->read(c, x, y); + c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + tbuf1->read(tc, (settings->angle ? xm : x), ym); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + tbuf1->read(tc, (settings->angle ? xp : x), yp); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + c[3] = 1.0f; + tbuf1->writePixel(x, y, c); + + tbuf2->read(c, x, y); + c[0]*=f1; c[1]*=f1 ; c[2] *=f1; + tbuf2->read(tc, xm, (settings->angle ? yp : y)); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + tbuf2->read(tc, xp, (settings->angle ? ym : y)); + c[0]+=tc[0]*f2; + c[1]+=tc[1]*f2; + c[2]+=tc[2]*f2; + c[3] = 1.0f; + tbuf2->writePixel(x, y, c); + } + } + } + + for (i = 0 ; i < this->getWidth()*this->getHeight()*4 ; i++) { + data[i] = tbuf1->getBuffer()[i] + tbuf2->getBuffer()[i]; + } + + delete tbuf1; + delete tbuf2; +} diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h new file mode 100644 index 00000000000..22040da9bc5 --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h @@ -0,0 +1,35 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GlareSimpleStarOperation_h +#define _COM_GlareSimpleStarOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" +#include "COM_GlareBaseOperation.h" + +class GlareSimpleStarOperation : public GlareBaseOperation { +public: + GlareSimpleStarOperation() : GlareBaseOperation() {} +protected: + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); +}; +#endif diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp new file mode 100644 index 00000000000..177bb6e0730 --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GlareStreaksOperation.h" +#include "BLI_math.h" + +void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) { + int x, y, n; + unsigned int nump=0; + float c1[4], c2[4], c3[4], c4[4]; + float a, ang = DEG2RADF(360.0f)/(float)settings->angle; + + int size = inputTile->getWidth()*inputTile->getHeight(); + int size4 = size*4; + + + MemoryBuffer* tsrc = inputTile->duplicate(); + MemoryBuffer* tdst = new MemoryBuffer(NULL, inputTile->getRect()); + tdst->clear(); + memset(data, 0, size4*sizeof(float)); + + for (a=0.f; a<DEG2RADF(360.0f); a+=ang) { + const float an = a + settings->angle_ofs; + const float vx = cos((double)an), vy = sin((double)an); + for (n=0; n<settings->iter; ++n) { + const float p4 = pow(4.0, (double)n); + const float vxp = vx*p4, vyp = vy*p4; + const float wt = pow((double)settings->fade, (double)p4); + const float cmo = 1.f - (float)pow((double)settings->colmod, (double)n+1); // colormodulation amount relative to current pass + float* tdstcol = tdst->getBuffer(); + for (y=0; y<tsrc->getHeight(); ++y) { + for (x=0; x<tsrc->getWidth(); ++x, tdstcol+=4) { + // first pass no offset, always same for every pass, exact copy, + // otherwise results in uneven brightness, only need once + if (n==0) tsrc->read(c1, x, y); else c1[0]=c1[1]=c1[2]=0; + tsrc->readCubic(c2, x + vxp, y + vyp); + tsrc->readCubic(c3, x + vxp*2.f, y + vyp*2.f); + tsrc->readCubic(c4, x + vxp*3.f, y + vyp*3.f); + // modulate color to look vaguely similar to a color spectrum + c2[1] *= cmo; + c2[2] *= cmo; + + c3[0] *= cmo; + c3[1] *= cmo; + + c4[0] *= cmo; + c4[2] *= cmo; + + tdstcol[0] = 0.5f*(tdstcol[0] + c1[0] + wt*(c2[0] + wt*(c3[0] + wt*c4[0]))); + tdstcol[1] = 0.5f*(tdstcol[1] + c1[1] + wt*(c2[1] + wt*(c3[1] + wt*c4[1]))); + tdstcol[2] = 0.5f*(tdstcol[2] + c1[2] + wt*(c2[2] + wt*(c3[2] + wt*c4[2]))); + tdstcol[3] = 1.0f; + } + } + memcpy(tsrc->getBuffer(), tdst->getBuffer(), sizeof(float)*size4); + } + +// addImage(sbuf, tsrc, 1.f/(float)(6 - ndg->iter)); // add result to data @todo + float* sourcebuffer = tsrc->getBuffer(); + float factor = 1.f/(float)(6 - settings->iter); + for (int i = 0 ; i < size4; i ++) { + data[i] += sourcebuffer[i] * factor; + } + for (int i = 0 ; i < size; i ++) { + data[i*4+3] = 1.0f; + } + + tdst->clear(); + memcpy(tsrc->getBuffer(), inputTile->getBuffer(), sizeof(float)*size4); + nump++; + } + + delete tsrc; + delete tdst; +} diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.h b/source/blender/compositor/operations/COM_GlareStreaksOperation.h new file mode 100644 index 00000000000..07155a4713a --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.h @@ -0,0 +1,35 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GlareStreaksOperation_h +#define _COM_GlareStreaksOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" +#include "COM_GlareBaseOperation.h" + +class GlareStreaksOperation : public GlareBaseOperation { +public: + GlareStreaksOperation() : GlareBaseOperation() {} +protected: + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); +}; +#endif diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp new file mode 100644 index 00000000000..cc8bda2730e --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GlareThresholdOperation.h" +#include "BLI_math.h" + +GlareThresholdOperation::GlareThresholdOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputProgram = NULL; +} +void GlareThresholdOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); +} + +void GlareThresholdOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + this->inputProgram->read(color, x, y, sampler, inputBuffers); + if ((0.212671f*color[0] + 0.71516f*color[1] + 0.072169f*color[2]) >= threshold) { + color[0] -= threshold, color[1] -= threshold, color[2] -= threshold; + color[0] = MAX2(color[0], 0.f); + color[1] = MAX2(color[1], 0.f); + color[2] = MAX2(color[2], 0.f); + } + else color[0] = color[1] = color[2] = 0.f; +} + +void GlareThresholdOperation::deinitExecution() { + this->inputProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h new file mode 100644 index 00000000000..3d68181ae47 --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_GlareScaleOperation_h +#define _COM_GlareScaleOperation_h +#include "COM_NodeOperation.h" +#include "DNA_lamp_types.h" + +class GlareThresholdOperation : public NodeOperation { +private: + /** + * @brief Cached reference to the inputProgram + */ + SocketReader * inputProgram; + + float threshold; + +public: + GlareThresholdOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setThreshold(float threshold) {this->threshold = threshold;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp new file mode 100644 index 00000000000..d5d577e91a9 --- /dev/null +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_HueSaturationValueCorrectOperation.h" + +#include "BLI_math.h" + +#ifdef __cplusplus +extern "C" { +#endif + #include "BKE_colortools.h" +#ifdef __cplusplus +} +#endif + +HueSaturationValueCorrectOperation::HueSaturationValueCorrectOperation(): CurveBaseOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + + this->inputProgram = NULL; +} +void HueSaturationValueCorrectOperation::initExecution() { + CurveBaseOperation::initExecution(); + this->inputProgram = this->getInputSocketReader(0); +} + +void HueSaturationValueCorrectOperation::executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float hsv[4], f; + + this->inputProgram->read(hsv, x, y, sampler, inputBuffers); + + /* adjust hue, scaling returned default 0.5 up to 1 */ + f = curvemapping_evaluateF(this->curveMapping, 0, hsv[0]); + hsv[0] += f-0.5f; + + /* adjust saturation, scaling returned default 0.5 up to 1 */ + f = curvemapping_evaluateF(this->curveMapping, 1, hsv[0]); + hsv[1] *= (f * 2.f); + + /* adjust value, scaling returned default 0.5 up to 1 */ + f = curvemapping_evaluateF(this->curveMapping, 2, hsv[0]); + hsv[2] *= (f * 2.f); + + hsv[0] = hsv[0] - floor(hsv[0]); /* mod 1.0 */ + CLAMP(hsv[1], 0.f, 1.f); + + output[0]= hsv[0]; + output[1]= hsv[1]; + output[2]= hsv[2]; + output[3]= hsv[3]; +} + +void HueSaturationValueCorrectOperation::deinitExecution() { + this->inputProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h new file mode 100644 index 00000000000..472a85f5531 --- /dev/null +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_HueSaturationValueCorrectOperation_h +#define _COM_HueSaturationValueCorrectOperation_h +#include "COM_NodeOperation.h" +#include "COM_CurveBaseOperation.h" + +class HueSaturationValueCorrectOperation : public CurveBaseOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; +public: + HueSaturationValueCorrectOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* Vector, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.cpp b/source/blender/compositor/operations/COM_IDMaskOperation.cpp new file mode 100644 index 00000000000..198248e35a3 --- /dev/null +++ b/source/blender/compositor/operations/COM_IDMaskOperation.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_IDMaskOperation.h" + +IDMaskOperation::IDMaskOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->inputProgram = NULL; +} +void IDMaskOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); +} + +void IDMaskOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + + this->inputProgram->read(inputValue, x, y, sampler, inputBuffers); + const float a = (inputValue[0] == this->objectIndex)?1.0f:0.0f; + color[0] = a; +} + +void IDMaskOperation::deinitExecution() { + this->inputProgram = NULL; +} + diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h new file mode 100644 index 00000000000..3b22be16d8a --- /dev/null +++ b/source/blender/compositor/operations/COM_IDMaskOperation.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_IDMaskOperation_h +#define _COM_IDMaskOperation_h +#include "COM_NodeOperation.h" + + +class IDMaskOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader* inputProgram; + + float objectIndex; +public: + IDMaskOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setObjectIndex(float objectIndex) {this->objectIndex = objectIndex;} + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp new file mode 100644 index 00000000000..52c2e44f7d4 --- /dev/null +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -0,0 +1,149 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ImageOperation.h" + +#include "BLI_listbase.h" +#include "DNA_scene_types.h" +#include "DNA_image_types.h" +#include "BKE_image.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" + #include "RE_shader_ext.h" + #include "RE_render_ext.h" + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + +BaseImageOperation::BaseImageOperation(): NodeOperation() { + this->image = NULL; + this->buffer = NULL; + this->imageBuffer = NULL; + this->imageUser = NULL; + this->imagewidth = 0; + this->imageheight = 0; + this->framenumber = 0; + this->depthBuffer = NULL; + this->numberOfChannels = 0; +} +ImageOperation::ImageOperation(): BaseImageOperation() { + this->addOutputSocket(COM_DT_COLOR); +} +ImageAlphaOperation::ImageAlphaOperation(): BaseImageOperation() { + this->addOutputSocket(COM_DT_VALUE); +} +ImageDepthOperation::ImageDepthOperation(): BaseImageOperation() { + this->addOutputSocket(COM_DT_VALUE); +} + +ImBuf* BaseImageOperation::getImBuf() { + ImBuf *ibuf; + + ibuf= BKE_image_get_ibuf(this->image, this->imageUser); + if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { + return NULL; + } + + if (ibuf->rect_float == NULL) { + IMB_float_from_rect(ibuf); + } + return ibuf; +} + + +void BaseImageOperation::initExecution() { + ImBuf *stackbuf= getImBuf(); + this->buffer = stackbuf; + if (stackbuf) { + this->imageBuffer = stackbuf->rect_float; + this->depthBuffer = stackbuf->zbuf_float; + this->imagewidth = stackbuf->x; + this->imageheight = stackbuf->y; + this->numberOfChannels = stackbuf->channels; + } +} + +void BaseImageOperation::deinitExecution() { + this->imageBuffer= NULL; +} + +void BaseImageOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + ImBuf *stackbuf= getImBuf(); + if (stackbuf) { + resolution[0] = stackbuf->x; + resolution[1] = stackbuf->y; + } +} + +void ImageOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + if (this->imageBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 0.0f; + } else { + switch (sampler) { + case COM_PS_NEAREST: + neareast_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->buffer, NULL, color, x, y); + break; + } + } +} + +void ImageAlphaOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float tempcolor[4]; + + if (this->imageBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { + color[0] = 0.0f; + } else { + tempcolor[3] = 1.0f; + switch (sampler) { + case COM_PS_NEAREST: + neareast_interpolation_color(this->buffer, NULL, tempcolor, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->buffer, NULL, tempcolor, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->buffer, NULL, tempcolor, x, y); + break; + } + color[0] = tempcolor[3]; + } +} + +void ImageDepthOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + if (this->depthBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { + color[0] = 0.0f; + } else { + int offset = y * width + x; + color[0] = this->depthBuffer[offset]; + } +} diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h new file mode 100644 index 00000000000..a5e2c753b59 --- /dev/null +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -0,0 +1,94 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + + +#ifndef _COM_ImageOperation_h +#define _COM_ImageOperation_h + +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "BLI_listbase.h" +#include "BKE_image.h" +extern "C" { + #include "RE_pipeline.h" + #include "RE_shader_ext.h" + #include "RE_render_ext.h" + #include "MEM_guardedalloc.h" +} + +/** + * @brief Base class for all image operations + */ +class BaseImageOperation : public NodeOperation { +protected: + ImBuf* buffer; + Image* image; + ImageUser* imageUser; + float *imageBuffer; + float *depthBuffer; + int imageheight; + int imagewidth; + int framenumber; + int numberOfChannels; + + BaseImageOperation(); + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + virtual ImBuf* getImBuf(); + +public: + + void initExecution(); + void deinitExecution(); + void setImage(Image* image) {this->image = image;} + void setImageUser(ImageUser* imageuser) {this->imageUser = imageuser;} + + void setFramenumber(int framenumber) {this->framenumber = framenumber;} +}; +class ImageOperation: public BaseImageOperation { +public: + /** + * Constructor + */ + ImageOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class ImageAlphaOperation: public BaseImageOperation { +public: + /** + * Constructor + */ + ImageAlphaOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class ImageDepthOperation: public BaseImageOperation { +public: + /** + * Constructor + */ + ImageDepthOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_InvertOperation.cpp b/source/blender/compositor/operations/COM_InvertOperation.cpp new file mode 100644 index 00000000000..a90c7b6b8d2 --- /dev/null +++ b/source/blender/compositor/operations/COM_InvertOperation.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_InvertOperation.h" + +InvertOperation::InvertOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputValueProgram = NULL; + this->inputColorProgram = NULL; + this->color = true; + this->alpha = false; + setResolutionInputSocketIndex(1); +} +void InvertOperation::initExecution() { + this->inputValueProgram = this->getInputSocketReader(0); + this->inputColorProgram = this->getInputSocketReader(1); +} + +void InvertOperation::executePixel(float* out, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue[4]; + float inputColor[4]; + this->inputValueProgram->read(inputValue, x, y, sampler, inputBuffers); + this->inputColorProgram->read(inputColor, x, y, sampler, inputBuffers); + + const float value = inputValue[0]; + const float invertedValue = 1.0f - value; + + if(color) { + out[0] = (1.0f - inputColor[0])*value + inputColor[0]*invertedValue; + out[1] = (1.0f - inputColor[1])*value + inputColor[1]*invertedValue; + out[2] = (1.0f - inputColor[2])*value + inputColor[2]*invertedValue; + } else { + out[0] = inputColor[0]; + out[1] = inputColor[1]; + out[2] = inputColor[2]; + } + + if(alpha) + out[3] = (1.0f - inputColor[3])*value + inputColor[3]*invertedValue; + else + out[3] = inputColor[3]; + +} + +void InvertOperation::deinitExecution() { + this->inputValueProgram = NULL; + this->inputColorProgram = NULL; +} + diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h new file mode 100644 index 00000000000..6baa10a3d62 --- /dev/null +++ b/source/blender/compositor/operations/COM_InvertOperation.h @@ -0,0 +1,60 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_InvertOperation_h +#define _COM_InvertOperation_h +#include "COM_NodeOperation.h" + + +class InvertOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputValueProgram; + SocketReader * inputColorProgram; + + bool alpha; + bool color; + +public: + InvertOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setColor(bool color) {this->color = color;} + void setAlpha(bool alpha) {this->alpha = alpha;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_LensGhostOperation.cpp b/source/blender/compositor/operations/COM_LensGhostOperation.cpp new file mode 100644 index 00000000000..eb957ca4756 --- /dev/null +++ b/source/blender/compositor/operations/COM_LensGhostOperation.cpp @@ -0,0 +1,792 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_LensGhostOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#define MAX_STEP 256 +class Ray { +public: + float position[3]; + float direction[3]; + float uv[2]; + double wavelength; + float intensity; + bool valid; + void copyFrom(Ray* other) { + copy_v3_v3(position, other->position); + copy_v3_v3(direction, other->direction); + copy_v2_v2(uv, other->uv); + wavelength = other->wavelength; + intensity = other->intensity; + this->valid = other->valid; + } +}; + +class Intersection { +public: + float position[3]; + float normal[3]; + double theta; + bool hit; + bool inverted; +}; + +class LensInterface { +public: + float position[3]; + float radius; + float nominalRadius; + double refraction1; + double refraction2; + double refraction3; + float thicknessCoathing; + virtual bool isFlat() = 0; + virtual void intersect(Intersection* result, Ray* ray) = 0; +}; + +class FlatInterface: public LensInterface { +public: + bool isFlat() {return true;} + FlatInterface(float positionX, float positionY, float positionZ, float radius) { + this->position[0] = positionX; + this->position[1] = positionY; + this->position[2] = positionZ; + this->radius = radius; + this->nominalRadius = radius; + this->refraction1 = 1.0f; + this->refraction2 = 1.0f; + this->refraction3 = 1.0f; + this->thicknessCoathing = 0.0f; + + } + void intersect(Intersection* result, Ray* ray) { + const float dz = this->position[2]-ray->position[2]; + result->position[0] = ray->position[0] + ray->direction[0]*(dz)/ray->direction[2]; + result->position[1] = ray->position[1] + ray->direction[1]*(dz)/ray->direction[2]; + result->position[2] = ray->position[2] + ray->direction[2]*(dz)/ray->direction[2]; + result->normal[0] = 0.0f; + result->normal[1] = 0.0f; + result->normal[2] = ray->direction[2]>0?-1.0f:1.0f; + result->theta = 0.0f; +// result->hit = this->nominalRadius>maxf(fabs(result->position[0]), fabs(result->position[1])); + result->hit = true; + result->inverted = false; + } +}; + +class SphereInterface: public LensInterface { +public: + SphereInterface(float positionX, float positionY, float positionZ, float radius, float nominalRadius, float n0, float n2, float coatingPhase) { + this->position[0] = positionX; + this->position[1] = positionY; + this->position[2] = positionZ; + this->radius = radius; + this->nominalRadius = nominalRadius; + this->refraction1 = n0; + this->refraction3 = n2; + this->refraction2 = maxf(sqrtf(n0*n2), 1.38); + + this->thicknessCoathing = coatingPhase/4/this->refraction2; + } + bool isFlat() {return false;} + void intersect(Intersection* result, Ray* ray) { + float delta[3] ={ray->position[0] - this->position[0], + ray->position[1] - this->position[1], + ray->position[2] - this->position[2]}; + float b = dot_v3v3(delta, ray->direction); + float c = dot_v3v3(delta, delta) - this->radius*this->radius; + float b2c = b*b-c; + if (b2c < 0) { + result->hit = false; + } else { + float sgn = (this->radius*ray->direction[2])>0?1.0f:-1.0f; + float t = sqrtf(b2c)*sgn-b; + result->position[0] = ray->direction[0]*t+ray->position[0]; + result->position[1] = ray->direction[1]*t+ray->position[1]; + result->position[2] = ray->direction[2]*t+ray->position[2]; + + float p[3] = { + result->position[0] - this->position[0], + result->position[1] - this->position[1], + result->position[2] - this->position[2] + }; + normalize_v3(p); + + if (dot_v3v3(p, ray->direction)> 0) { + result->normal[0] = -p[0]; + result->normal[1] = -p[1]; + result->normal[2] = -p[2]; + } else { + result->normal[0] = p[0]; + result->normal[1] = p[1]; + result->normal[2] = p[2]; + } + + float inverse[3] ={ + -ray->direction[0], + -ray->direction[1], + -ray->direction[2]}; + + result->theta = acosf(dot_v3v3(inverse, result->normal)); + result->hit = this->nominalRadius>sqrt(result->position[0]*result->position[0]+result->position[1]*result->position[1]); +// result->hit = this->nominalRadius>maxf(fabs(result->position[0]), fabs(result->position[1])); +// result->hit = true; + result->inverted = t < 0; + } + } +}; +class RayResult { +public: + float x; + float y; + float intensity[3]; + float u; + float v; + float screenX; + float screenY; + bool valid; + bool hasIntensity; +}; +class Bounce{ +public: + LensInterface *interface1; + LensInterface *interface2; + RayResult *raster; + int length; // number of interfaces to travel + int rasterLength; + Bounce(LensInterface *interface1, LensInterface *interface2, int length, int rasterStep) { + this->interface1 = interface1; + this->interface2 = interface2; + this->length = length; + this->rasterLength = rasterStep; + this->raster = new RayResult[rasterLength*rasterLength]; + for (int i = 0 ; i < rasterLength*rasterLength ; i++) { + RayResult * res = &this->raster[i]; + res->intensity[0] = 0.0f; + res->intensity[1] = 0.0f; + res->intensity[2] = 0.0f; + res->x = 0.0f; + res->y = 0.0f; + res->u = 0.0f; + res->v = 0.0f; + res->valid = false; + } + } + ~Bounce() { + delete raster; + + } + + RayResult* getRayResult(int x, int y) { + return &(raster[x+y*rasterLength]); + } +}; +class LensSystem { +public: + vector<LensInterface*> interfaces; + vector<Bounce*> bounces; + int bokehIndex; + int lensIndex; + + ~LensSystem() { + for (int index = 0 ; index <bounces.size();index++) {delete bounces[index];} + for (int index = 0 ; index <interfaces.size();index++) {delete interfaces[index];} + } + + void updateBounces(int step) { + for (int i = 0; i < interfaces.size()-1 ; i ++) { + if (!interfaces[i]->isFlat()) { + for (int j = i+1; j < interfaces.size()-1 ; j ++) { + if (!interfaces[j]->isFlat()) { + int length = interfaces.size()+2*(j-i); + Bounce* bounce = new Bounce(interfaces[j], interfaces[i], length, step); + bounces.push_back(bounce); + } + } + } + } + + } + + void addInterface(LensInterface* interface) { + this->interfaces.push_back(interface); + this->lensIndex = this->interfaces.size()-1; + } + + static int refraction(float *refract, float *n, float *view, double index) + { + + return 1; + +// float dot, fac; + +// VECCOPY(refract, view); + +// dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2]; + +// if(dot>0.0f) { +// index = 1.0f/index; +// fac= 1.0f - (1.0f - dot*dot)*index*index; +// if(fac<= 0.0f) return 0; +// fac= -dot*index + sqrt(fac); +// } +// else { +// fac= 1.0f - (1.0f - dot*dot)*index*index; +// if(fac<= 0.0f) return 0; +// fac= -dot*index - sqrt(fac); +// } + +// refract[0]= index*view[0] + fac*n[0]; +// refract[1]= index*view[1] + fac*n[1]; +// refract[2]= index*view[2] + fac*n[2]; + +// normalize_v3(refract); +// return 1; + //--- +// const double cosI = dot_v3v3(n, view); +// const double sinT2 = index * index * (1.0 - cosI * cosI); +// if (sinT2 >= 1.0f) +// { +// return 0; +// } +// refract[0] = index*view[0] - (index + sqrt(1.0-sinT2))*n[0]; +// refract[1] = index*view[1] - (index + sqrt(1.0-sinT2))*n[1]; +// refract[2] = index*view[2] - (index + sqrt(1.0-sinT2))*n[2]; +// normalize_v3(refract); +// return 1; + //--- + +// double ni = -dot_v3v3(view, n); +// double test = 1.0f - index*index*(1.0f-ni*ni); +// if (test < 0) { +// return 0; +// } else { +// double mul = index*ni + sqrt(test); +// refract[0] = index * view[0] - mul*n[0]; +// refract[1] = index * view[1] - mul*n[1]; +// refract[2] = index * view[2] - mul*n[2]; +// normalize_v3(refract); +// return 1; +// } + } + + /* orn = original face normal */ + static void reflection(float *ref, float *n, float *view) + { + float f1; + + f1= -2.0f*dot_v3v3(n, view); + + ref[0]= (view[0]+f1*n[0]); + ref[1]= (view[1]+f1*n[1]); + ref[2]= (view[2]+f1*n[2]); + normalize_v3(ref); + } + + static float fresnelAR(float theta0, float lambda, float d1, float n0, float n1, float n2) { + // refractionangles in coating and the 2nd medium + float theta1 = asin(sin(theta0)*n0/n1); + float theta2 = asin(sin(theta0)*n0/n2); + + float rs01 = -sin(theta0-theta1)/sin(theta0+theta1); + float rp01 = tan( theta0-theta1)/tan(theta0+theta1); + float ts01 = 2 * sin ( theta1 ) * cos ( theta0 ) / sin ( theta0+theta1 ) ; + float tp01 = ts01*cos(theta0-theta1); + // amplitude for inner reflection + float rs12 = -sin ( theta1-theta2 ) / sin ( theta1+theta2 ) ; + float rp12 = +tan ( theta1-theta2 ) / tan ( theta1+theta2 ) ; + // after passing through first surface twice : + // 2 transmissions and 1 reflection + float ris = ts01 * ts01 * rs12 ; + float rip = tp01 * tp01 * rp12 ; + // phase difference between outer and inner reflections + float dy = d1 * n1 ; + float dx = tan ( theta1 ) * dy ; + float delay = sqrt ( dx * dx+dy * dy ) ; + float relPhase = 4 * M_PI / lambda * ( delay-dx * sin ( theta0 ) ) ; + // Add up sines of different phase and amplitude + float out_s2 = rs01 * rs01 + ris * ris + 2 * rs01 * ris * cos ( relPhase ) ; + float out_p2 = rp01 * rp01 + rip * rip + 2 * rp01 * rip * cos ( relPhase ) ; + return ( out_s2+out_p2 ) / 2 ; + } + + void detectHit(Ray* result, Ray* inputRay, Bounce *bounce) { + int phase = 0; + int delta = 1; + int t = 1; + int k; + result->copyFrom(inputRay); + result->valid = false; + LensInterface* next = bounce->interface1; + LensInterface* f = NULL; + Intersection intersection; + for (k = 0 ; k < bounce->length-1;k++, t+=delta) { + f = this->interfaces[t]; + bool breflect = next == f; + if (breflect) { + delta = -delta; + if (phase == 0) { + next = bounce->interface2; + } else { + next = NULL; + } + phase ++; + } + + f->intersect(&intersection, result); + if (!intersection.hit) { + break; + } + if (f->isFlat()) { + if (t == this->bokehIndex) { + result->uv[0] = intersection.position[0]/f->nominalRadius; + result->uv[1] = intersection.position[1]/f->nominalRadius; + } + } + + float p[3] = { + intersection.position[0]-result->position[0], + intersection.position[1]-result->position[1], + intersection.position[2]-result->position[2] + }; + + float nfac = sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]); + + if (intersection.inverted) { + nfac *= -1; + } + + result->direction[0] = p[0]/nfac; + result->direction[1] = p[1]/nfac; + result->direction[2] = p[2]/nfac; + result->position[0] = intersection.position[0]; + result->position[1] = intersection.position[1]; + result->position[2] = intersection.position[2]; + + if (!f->isFlat()) { + // do refraction and reflection + double n0 = result->direction[2]<0?f->refraction1:f->refraction3; + double n1 = f->refraction2; + double n2 = result->direction[2]<0?f->refraction3:f->refraction1; + if (!breflect) { + float view[3] ={ + result->direction[0], + result->direction[1], + result->direction[2] + }; + int ref = this->refraction(result->direction, intersection.normal, view, n0/n1); + if (ref == 0) { + break; + } + } else { + this->reflection(result->direction, intersection.normal, result->direction); + float fresnelMultiplyer = fresnelAR(intersection.theta, result->wavelength, f->thicknessCoathing, n0, n1, n2); + if (isnan(fresnelMultiplyer)) { + fresnelMultiplyer = 0.0f; + } + result->intensity *= fresnelMultiplyer; + } + } + + } + if (k < bounce->length-1) { + result->intensity = 0; + } else { + result->valid = true; + } + } +}; + +typedef struct LensFace { + RayResult* v1; + RayResult* v2; + RayResult* v3; +} LensFace; + +LensGhostProjectionOperation::LensGhostProjectionOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); + this->addOutputSocket(COM_DT_COLOR); + this->lampObject = NULL; + this->cameraObject = NULL; + this->system = NULL; + this->quality = COM_QUALITY_HIGH; + this->setComplex(false); +} + +LensGhostOperation::LensGhostOperation(): LensGhostProjectionOperation() { + this->setComplex(true); + +} + +void LensGhostProjectionOperation::initExecution() { + if (this->cameraObject != NULL && this->lampObject != NULL) { + if (lampObject == NULL || cameraObject == NULL) { + visualLampPosition[0] = 0; + visualLampPosition[1] = 0; + visualLampPosition[2] = 0; + } else { + /* too simple, better to return the distance on the view axis only + * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ + float matt[4][4], imat[4][4], obmat[4][4]; + + copy_m4_m4(obmat, cameraObject->obmat); + normalize_m4(obmat); + invert_m4_m4(imat, obmat); + mult_m4_m4m4(matt, imat, lampObject->obmat); + + visualLampPosition[0] = (float)(matt[3][0]); + visualLampPosition[1] = (float)(matt[3][1]); + visualLampPosition[2] = (float)fabs(matt[3][2]); + } + } + this->lamp = (Lamp*)lampObject->data; + + this->step = this->quality==COM_QUALITY_LOW?64:this->quality==COM_QUALITY_MEDIUM?128:256; + this->bokehReader = this->getInputSocketReader(1); + +#define MM *0.001f +#define CM *0.01f +#define NM *0.000000001 +#define RED 650 NM +#define GREEN 510 NM +#define BLUE 475 NM +#define AIR 1.000293f +#define GLASS 1.5200f +#define TEST 0.000002f + // determine interfaces + LensSystem *system = new LensSystem(); + system->addInterface(new FlatInterface(0.0f,0.0f, 6.5 CM, 30 MM)); //ENTRANCE + system->addInterface(new SphereInterface(0.0f,0.0f, -3 CM, 8 CM, 3 CM, AIR, GLASS , 0.f)); + system->addInterface(new SphereInterface(0.0f,0.0f, -4 CM, 8 CM, 3 CM, GLASS, AIR, GREEN)); + system->addInterface(new FlatInterface(0.0f,0.0f, 3.0 CM, 15 MM)); // BOKEH + system->addInterface(new SphereInterface(0.0f,0.0f, 6 CM, 3 CM, 2 CM, AIR, GLASS, 0.0f)); + system->addInterface(new SphereInterface(0.0f,0.0f, 5.5 CM, 3 CM, 2 CM, GLASS, AIR, 0.f)); + system->addInterface(new FlatInterface(0.0f,0.0f,0 CM, 30 MM)); // SENSOR + system->bokehIndex =3; + + // determine interfaces +// LensSystem *system = new LensSystem(); +// system->addInterface(new FlatInterface(0.0f,0.0f, 6.5 CM, 30 MM)); //ENTRANCE +// system->addInterface(new SphereInterface(0.0f,0.0f, 14 CM, 8 CM, 6 CM, AIR, GLASS , 0.0f)); +// system->addInterface(new SphereInterface(0.0f,0.0f, 12 CM, 8 CM, 6 CM, GLASS, AIR, GREEN)); +// system->addInterface(new FlatInterface(0.0f,0.0f, 3.0 CM, 30 MM)); // BOKEH +// system->addInterface(new SphereInterface(0.0f,0.0f, 1 CM, 3 CM, 2 CM, AIR, GLASS, GREEN)); +// system->addInterface(new SphereInterface(0.0f,0.0f, -2 CM, 3 CM, 2 CM, GLASS, AIR, RED)); +// system->addInterface(new FlatInterface(0.0f,0.0f,0 CM, 20 MM)); // SENSOR +// system->bokehIndex = 3; +#undef CM +#undef MM + // determine bounces + system->updateBounces(step); + this->system = system; +} + +void LensGhostOperation::initExecution() { + LensGhostProjectionOperation::initExecution(); + LensSystem *system = (LensSystem*)this->system; + LensInterface *interface1 = system->interfaces[0]; + + // for every herz + float HERZ[3]={650 NM,510 NM,475 NM}; /// @todo use 7 for high quality? + for (int iw = 0 ; iw < 3 ; iw ++) { + float wavelength = HERZ[iw]; + // for every bounce + for (int ib = 0 ; ib < system->bounces.size() ; ib++) { + Bounce* bounce = system->bounces[ib]; + // based on quality setting the number of iteration will be different (128^2, 64^2, 32^2) + for (int xi = 0 ; xi < step ; xi ++) { + float x = -interface1->radius+xi*(interface1->radius*2/step); + for (int yi = 0 ; yi < step ; yi ++) { + float y = -interface1->radius+yi*(interface1->radius*2/step); + Ray r; + Ray result; + r.wavelength = wavelength; + r.intensity = this->lamp->energy; + r.uv[0] = 0.0f; + r.uv[1] = 0.0f; + r.position[0] = visualLampPosition[0]; + r.position[1] = visualLampPosition[1]; + r.position[2] = visualLampPosition[2]; + r.direction[0] = interface1->position[0]+x - r.position[0]; + r.direction[1] = interface1->position[1]+y - r.position[1]; + r.direction[2] = interface1->position[2] - r.position[2]; + normalize_v3(r.direction); + system->detectHit(&result, &r, bounce); + RayResult *res = bounce->getRayResult(xi, yi); + if (iw == 0) { + res->x = result.position[0]; + res->y = result.position[1]; + res->u = result.uv[0]; + res->v = result.uv[1]; + } + res->intensity[iw] = result.intensity; + if (result.valid) { + res->valid = true; + } + } + } + } + } +#undef NM + const int width = this->getWidth(); + const int height = this->getHeight(); + const float width2 = width/2.0f; + const float height2 = height/2.0f; + float *data = new float[width*height*4]; + for (int i = 0 ; i < width*height ; i ++) { + data[i*4+0] = 0.0f; + data[i*4+1] = 0.0f; + data[i*4+2] = 0.0f; + data[i*4+3] = 1.0f; + } + /// @todo every bounce creates own image. these images are added together at the end +// LensSystem *system = (LensSystem*)this->system; + LensInterface * lens = system->interfaces[system->lensIndex]; + for (int i = 0 ; i < system->bounces.size() ; i ++) { + Bounce* bounce = system->bounces[i]; + for (int r = 0 ; r < bounce->rasterLength*bounce->rasterLength ; r ++) { + RayResult *result = &bounce->raster[r]; +// if (result->valid) { + float ru= result->x/lens->nominalRadius*width2+width2; + float rv = result->y/lens->nominalRadius*height2+height2; + result->screenX = ru; + result->screenY = rv; + result->hasIntensity = result->intensity[0]>0.0f &&result->intensity[1]>0.0f&& result->intensity[2]>0.0f; +// } + } + } +} + +void* LensGhostOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + vector<LensFace*>* result = new vector<LensFace*>(); + LensSystem *system = (LensSystem*)this->system; + const float minx = rect->xmin; + const float miny = rect->ymin; + const float maxx = rect->xmax; + const float maxy = rect->ymax; + for (int i = 0 ; i < system->bounces.size() ; i ++) { + Bounce* bounce = system->bounces[i]; + int faceX, faceY; + for (faceX = 0 ; faceX < bounce->rasterLength-1 ; faceX++) { + for (faceY = 0 ; faceY < bounce->rasterLength-1 ; faceY++) { + RayResult* vertex1 = bounce->getRayResult(faceX, faceY); + RayResult* vertex2 = bounce->getRayResult(faceX+1, faceY); + RayResult* vertex3 = bounce->getRayResult(faceX+1, faceY+1); + RayResult* vertex4 = bounce->getRayResult(faceX, faceY+1); + // early hit test + if (!((vertex1->screenX < minx && vertex2->screenX < minx && vertex3->screenX < minx && vertex4->screenX < minx) || + (vertex1->screenX > maxx && vertex2->screenX > maxx && vertex3->screenX > maxx && vertex4->screenX > maxx) || + (vertex1->screenY < miny && vertex2->screenY < miny && vertex3->screenY < miny && vertex4->screenY < miny) || + (vertex1->screenY > maxy && vertex2->screenY > maxy && vertex3->screenY > maxy && vertex4->screenY > maxy))) { + int number = vertex1->hasIntensity +vertex2->hasIntensity +vertex3->hasIntensity +vertex4->hasIntensity; + if (number == 4) { + LensFace* face = new LensFace(); + face->v1 = vertex1; + face->v2 = vertex2; + face->v3 = vertex3; + result->push_back(face); + face = new LensFace(); + face->v1 = vertex3; + face->v2 = vertex4; + face->v3 = vertex1; + result->push_back(face); + } else if (number == 3) { + LensFace *face = new LensFace(); + if (!vertex1->hasIntensity) { + face->v1 = vertex2; + face->v2 = vertex3; + face->v3 = vertex4; + } else if (!vertex2->hasIntensity) { + face->v1 = vertex1; + face->v2 = vertex3; + face->v3 = vertex4; + } else if (!vertex3->hasIntensity) { + face->v1 = vertex1; + face->v2 = vertex2; + face->v3 = vertex4; + } else { + face->v1 = vertex1; + face->v2 = vertex2; + face->v3 = vertex3; + } + result->push_back(face); + } + } + } + } + } + + return result; +} + +void LensGhostOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) { + if (data) { + vector<LensFace*>* faces = (vector<LensFace*>*)data; + while (faces->size() != 0) { + LensFace *face = faces->back(); + faces->pop_back(); + delete face; + } + delete faces; + } +} + + +void LensGhostProjectionOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float bokeh[4]; + LensSystem *system = (LensSystem*)this->system; + LensInterface *interface1 = system->interfaces[0]; + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 0.0f; + const float width = this->getWidth(); + const float height = this->getHeight(); + const float size = min(height, width); + const float width2 = width/2; + const float height2 = height/2; + const float size2 = size/2; + +#define NM *0.000000001 + float HERZ[3]={650 NM,510 NM,475 NM}; /// @todo use 7 for high quality? + float rx = ((x-width2)/size2) * interface1->radius; + float ry = ((y-height2)/size2) * interface1->radius; + + for (int iw = 0 ; iw < 3 ; iw ++) { + float intensity = 0.0f; + float wavelength = HERZ[iw]; + float colorcomponent = 0.0f; + if (iw ==0 ) colorcomponent = lamp->r; + if (iw ==1 ) colorcomponent = lamp->g; + if (iw ==2 ) colorcomponent = lamp->b; + + + // for every bounce + for (int ib = 0 ; ib < system->bounces.size() ; ib++) { + Bounce* bounce = system->bounces[ib]; + // based on quality setting the number of iteration will be different (128^2, 64^2, 32^2) + + Ray r; + Ray result; + r.wavelength = wavelength; + r.intensity = this->lamp->energy; + r.uv[0] = 0.0f; + r.uv[1] = 0.0f; + r.position[0] = visualLampPosition[0]; + r.position[1] = visualLampPosition[1]; + r.position[2] = visualLampPosition[2]; + r.direction[0] = interface1->position[0]+rx - r.position[0]; + r.direction[1] = interface1->position[1]+ry - r.position[1]; + r.direction[2] = interface1->position[2] - r.position[2]; + normalize_v3(r.direction); + system->detectHit(&result, &r, bounce); + if (result.valid) { + float u = ((result.uv[0]+1.0f)/2)*bokehReader->getWidth(); + float v = ((result.uv[1]+1.0f)/2)*bokehReader->getHeight(); + + bokehReader->read(bokeh, u, v, sampler, inputBuffers); + + intensity += result.intensity *bokeh[iw]; + } + } + intensity = maxf(0.0f, intensity); + color[iw] = intensity*colorcomponent; + } + color[3] = 1.0f; +#undef NM + +} + + + +void LensGhostOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + vector<LensFace*>* faces = (vector<LensFace*>*)data; + const float bokehWidth = bokehReader->getWidth(); + const float bokehHeight = bokehReader->getHeight(); + float bokeh[4]; + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 1.0f; + + unsigned int index; + for (index = 0 ; index < faces->size() ; index ++) { + LensFace * face = faces->operator [](index); + RayResult* vertex1 = face->v1; + RayResult* vertex2 = face->v2; + RayResult* vertex3 = face->v3; + if (!((vertex1->screenX < x && vertex2->screenX < x && vertex3->screenX < x) || + (vertex1->screenX > x && vertex2->screenX > x && vertex3->screenX > x) || + (vertex1->screenY < y && vertex2->screenY < y && vertex3->screenY < y) || + (vertex1->screenY > y && vertex2->screenY > y && vertex3->screenY > y))) { + + const float v1[2] = {vertex1->screenX, vertex1->screenY}; + const float v2[2] = {vertex2->screenX, vertex2->screenY}; + const float v3[2] = {vertex3->screenX, vertex3->screenY}; + const float co[2] = {x, y}; + float weights[3]; + + barycentric_weights_v2(v1, v2, v3, co, weights); + if (weights[0]>=0.0f && weights[0]<=1.0f && + weights[1]>=0.0f && weights[1]<=1.0f && + weights[2]>=0.0f && weights[2]<=1.0f) { +// const float u = (vertex1->u*weights[0]+vertex2->u*weights[1]+vertex3->u*weights[2]); +// const float v = (vertex1->v*weights[0]+vertex2->v*weights[1]+vertex3->v*weights[2]); +// const float tu = ((u+1.0f)/2.0f)*bokehWidth; +// const float tv = ((v+1.0f)/2.0f)*bokehHeight; +// bokehReader->read(bokeh, tu, tv, inputBuffers); + +// color[0] = max(color[0], bokeh[0]*(vertex1->intensity[0]*weights[0]+vertex2->intensity[0]*weights[1]+vertex3->intensity[0]*weights[2])); +// color[1] = max(color[1], bokeh[1]*(vertex1->intensity[1]*weights[0]+vertex2->intensity[1]*weights[1]+vertex3->intensity[1]*weights[2])); +// color[2] = max(color[2], bokeh[2]*(vertex1->intensity[2]*weights[0]+vertex2->intensity[2]*weights[1]+vertex3->intensity[2]*weights[2])); + color[0] = max(color[0], (vertex1->intensity[0]*weights[0]+vertex2->intensity[0]*weights[1]+vertex3->intensity[0]*weights[2])); + color[1] = max(color[1], (vertex1->intensity[1]*weights[0]+vertex2->intensity[1]*weights[1]+vertex3->intensity[1]*weights[2])); + color[2] = max(color[2], (vertex1->intensity[2]*weights[0]+vertex2->intensity[2]*weights[1]+vertex3->intensity[2]*weights[2])); + } + } + } +} + + +void LensGhostProjectionOperation::deinitExecution() { + if (this->system) delete (LensSystem*)this->system; + this->system = NULL; + this->bokehReader = NULL; +} + +bool LensGhostProjectionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti bokehInput; + + NodeOperation *operation = this->getInputOperation(1); + bokehInput.xmax = operation->getWidth(); + bokehInput.xmin = 0; + bokehInput.ymax = operation->getHeight(); + bokehInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&bokehInput, readOperation, output) ) { + return true; + } + + return NodeOperation::determineDependingAreaOfInterest(input, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_LensGhostOperation.h b/source/blender/compositor/operations/COM_LensGhostOperation.h new file mode 100644 index 00000000000..396f681e797 --- /dev/null +++ b/source/blender/compositor/operations/COM_LensGhostOperation.h @@ -0,0 +1,82 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_LensGhostOperation_h +#define _COM_LensGhostOperation_h +#include "COM_NodeOperation.h" +#include "DNA_lamp_types.h" +#include "DNA_object_types.h" +#include "DNA_camera_types.h" + +class LensGhostProjectionOperation : public NodeOperation { +protected: + Object* lampObject; + Lamp* lamp; + Object* cameraObject; + + void* system; + float visualLampPosition[3]; + CompositorQuality quality; + int step; + SocketReader * bokehReader; + +public: + LensGhostProjectionOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setLampObject(Object* lampObject) {this->lampObject = lampObject;} + void setCameraObject(Object* cameraObject) {this->cameraObject = cameraObject;} + + void setQuality(CompositorQuality quality) {this->quality = quality;} +}; + +class LensGhostOperation : public LensGhostProjectionOperation { +public: + LensGhostOperation(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + /** + * Initialize the execution + */ + void initExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_LensGlowImageOperation.cpp b/source/blender/compositor/operations/COM_LensGlowImageOperation.cpp new file mode 100644 index 00000000000..935844a84f1 --- /dev/null +++ b/source/blender/compositor/operations/COM_LensGlowImageOperation.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_LensGlowImageOperation.h" +#include "BLI_math.h" + +LensGlowImageOperation::LensGlowImageOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_COLOR); +} +void LensGlowImageOperation::initExecution() { + this->scale = 1/20000.0f; +} +void LensGlowImageOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f; + const float v = 2.f*(y / (float)512.0f) - 1.f; + const float u = 2.f*(x / (float)512.0f) - 1.f; + const float r = (u*u + v*v)*scale; + const float d = -sqrtf(sqrtf(sqrtf(r)))*9.f; + const float w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI)); + color[0] = expf(d*cs_r) * w; + color[1] = expf(d*cs_g) * w; + color[2] = expf(d*cs_b) * w; + color[3] = 1.0f; +} + +void LensGlowImageOperation::deinitExecution() { +} + +void LensGlowImageOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + resolution[0] = 512; + resolution[1] = 512; +} diff --git a/source/blender/compositor/operations/COM_LensGlowImageOperation.h b/source/blender/compositor/operations/COM_LensGlowImageOperation.h new file mode 100644 index 00000000000..2943f8957a6 --- /dev/null +++ b/source/blender/compositor/operations/COM_LensGlowImageOperation.h @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_LensGlowImageOperation_h +#define _COM_LensGlowImageOperation_h +#include "COM_NodeOperation.h" + + +class LensGlowImageOperation : public NodeOperation { +private: + float scale; + +public: + LensGlowImageOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_LensGlowOperation.cpp b/source/blender/compositor/operations/COM_LensGlowOperation.cpp new file mode 100644 index 00000000000..ecaef52d8e1 --- /dev/null +++ b/source/blender/compositor/operations/COM_LensGlowOperation.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_LensGlowOperation.h" +#include "BLI_math.h" + +LensGlowOperation::LensGlowOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputProgram = NULL; + this->lamp = NULL; +} +void LensGlowOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); +} + +void LensGlowOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { +// const float emit100 = this->lamp->energy*100; +// const float emit200 = emit100*2; +// const float deltaX = 160-x; +// const float deltaY = 100-y; +// const float distance = deltaX * deltaX + deltaY*deltaY; + +// float glow = (emit100-(distance))/(emit200); +// if (glow<0) glow=0; + +// color[0] = glow*lamp->r; +// color[1] = glow*lamp->g; +// color[2] = glow*lamp->b; +// color[3] = 1.0f; +} + +void LensGlowOperation::deinitExecution() { + this->inputProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_LensGlowOperation.h b/source/blender/compositor/operations/COM_LensGlowOperation.h new file mode 100644 index 00000000000..9a18f605cda --- /dev/null +++ b/source/blender/compositor/operations/COM_LensGlowOperation.h @@ -0,0 +1,56 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_LensGlowOperation_h +#define _COM_LensGlowOperation_h +#include "COM_NodeOperation.h" +#include "DNA_lamp_types.h" + +class LensGlowOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + Lamp* lamp; + +public: + LensGlowOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setLamp(Lamp* lamp) {this->lamp = lamp;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp new file mode 100644 index 00000000000..7850a631212 --- /dev/null +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_LuminanceMatteOperation.h" +#include "BLI_math.h" + +LuminanceMatteOperation::LuminanceMatteOperation(): NodeOperation() { + addInputSocket(COM_DT_COLOR); + addOutputSocket(COM_DT_VALUE); + + inputImageProgram = NULL; +} + +void LuminanceMatteOperation::initExecution() { + this->inputImageProgram = this->getInputSocketReader(0); +} + +void LuminanceMatteOperation::deinitExecution() { + this->inputImageProgram= NULL; +} + +void LuminanceMatteOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inColor[4]; + + const float high=this->settings->t1; + const float low=this->settings->t2; + + float alpha; + + this->inputImageProgram->read(inColor, x, y, sampler, inputBuffers); + + /* one line thread-friend algorithm: + outputValue[0] = max(inputValue[3], min(high, max(low, ((inColor[0]-low)/(high-low)))) + */ + + /* test range*/ + if(inColor[0] > high) { + alpha=1.f; + } + else if(inColor[0] < low){ + alpha=0.f; + } + else {/*blend */ + alpha=(inColor[0]-low)/(high-low); + } + + + /* store matte(alpha) value in [0] to go with + * COM_SetAlphaOperation and the Value output + */ + + /* don't make something that was more transparent less transparent */ + if (alpha<inColor[3]) { + outputValue[0]=alpha; + } + else { + /* leave now it was before */ + outputValue[0]=inColor[3]; + } +} + diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h new file mode 100644 index 00000000000..3c33cee71e9 --- /dev/null +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_LuminanceMatteOperation_h +#define _COM_LuminanceMatteOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class LuminanceMatteOperation : public NodeOperation { +private: + NodeChroma *settings; + SocketReader *inputImageProgram; +public: + /** + * Default constructor + */ + LuminanceMatteOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeChroma* nodeChroma) {this->settings= nodeChroma;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp new file mode 100644 index 00000000000..ef0c9004a7d --- /dev/null +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -0,0 +1,153 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_MapUVOperation.h" +#include "BLI_math.h" + +MapUVOperation::MapUVOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VECTOR); + this->addOutputSocket(COM_DT_COLOR); + this->alpha = 0.f; + this->setComplex(true); + + this->inputUVProgram = NULL; + this->inputColorProgram = NULL; +} + +void MapUVOperation::initExecution() { + this->inputColorProgram = this->getInputSocketReader(0); + this->inputUVProgram = this->getInputSocketReader(1); +} + +void MapUVOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputUV[4]; + float uv_a[4], uv_b[4]; + float u,v; + + float dx, dy; + float uv_l, uv_r; + float uv_u, uv_d; + + this->inputUVProgram->read(inputUV, x, y, sampler, inputBuffers); + if (inputUV[2] == 0.f) { + color[0] = 0.f; + color[1] = 0.f; + color[2] = 0.f; + color[3] = 0.f; + return; + } + /* adaptive sampling, red (U) channel */ + this->inputUVProgram->read(uv_a, x-1, y, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x+1, y, COM_PS_NEAREST, inputBuffers); + uv_l= uv_a[2]!=0.f? fabs(inputUV[0] - uv_a[0]) : 0.f; + uv_r= uv_b[2]!=0.f? fabs(inputUV[0] - uv_b[0]) : 0.f; + + dx= 0.5f * (uv_l + uv_r); + + /* adaptive sampling, green (V) channel */ + this->inputUVProgram->read(uv_a, x, y-1, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x, y+1, COM_PS_NEAREST, inputBuffers); + uv_u= uv_a[2]!=0.f? fabs(inputUV[1] - uv_a[1]) : 0.f; + uv_d= uv_b[2]!=0.f? fabs(inputUV[1] - uv_b[1]) : 0.f; + + dy= 0.5f * (uv_u + uv_d); + + /* more adaptive sampling, red and green (UV) channels */ + this->inputUVProgram->read(uv_a, x-1, y-1, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x-1, y+1, COM_PS_NEAREST, inputBuffers); + uv_l= uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f; + uv_r= uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f; + uv_u= uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f; + uv_d= uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f; + + dx+= 0.25f * (uv_l + uv_r); + dy+= 0.25f * (uv_u + uv_d); + + this->inputUVProgram->read(uv_a, x+1, y-1, COM_PS_NEAREST, inputBuffers); + this->inputUVProgram->read(uv_b, x+1, y+1, COM_PS_NEAREST, inputBuffers); + uv_l= uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f; + uv_r= uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f; + uv_u= uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f; + uv_d= uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f; + + dx+= 0.25f * (uv_l + uv_r); + dy+= 0.25f * (uv_u + uv_d); + + /* UV to alpha threshold */ + const float threshold = this->alpha * 0.05f; + float alpha = 1.0f - threshold * (dx + dy); + if (alpha < 0.f) alpha= 0.f; + else alpha *= inputUV[2]; + + /* should use mipmap */ + dx= min(dx, 0.2f); + dy= min(dy, 0.2f); + + + /* EWA filtering */ + u = inputUV[0] * inputColorProgram->getWidth(); + v = inputUV[1] * inputColorProgram->getHeight(); + + this->inputColorProgram->read(color, u, v, dx, dy, inputBuffers); + + /* "premul" */ + if(alpha < 1.0f) { + color[0]*= alpha; + color[1]*= alpha; + color[2]*= alpha; + color[3]*= alpha; + } +} + +void MapUVOperation::deinitExecution() { + this->inputUVProgram = NULL; + this->inputColorProgram = NULL; +} + +bool MapUVOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti colorInput; + rcti uvInput; + NodeOperation *operation=NULL; + + /* the uv buffer only needs a 3x3 buffer. The image needs whole buffer */ + + operation = getInputOperation(0); + colorInput.xmax = operation->getWidth(); + colorInput.xmin = 0; + colorInput.ymax = operation->getHeight(); + colorInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&colorInput, readOperation, output)) { + return true; + } + + operation = getInputOperation(1); + uvInput.xmax = input->xmax + 1; + uvInput.xmin = input->xmin - 1; + uvInput.ymax = input->ymax + 1; + uvInput.ymin = input->ymin - 1; + if (operation->determineDependingAreaOfInterest(&uvInput, readOperation, output)) { + return true; + } + + return false; +} + diff --git a/source/blender/compositor/operations/COM_MapUVOperation.h b/source/blender/compositor/operations/COM_MapUVOperation.h new file mode 100644 index 00000000000..58c962eb17c --- /dev/null +++ b/source/blender/compositor/operations/COM_MapUVOperation.h @@ -0,0 +1,62 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_MapUVOperation_h +#define _COM_MapUVOperation_h +#include "COM_NodeOperation.h" + + +class MapUVOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader* inputUVProgram; + SocketReader* inputColorProgram; + + float alpha; + +public: + MapUVOperation(); + + /** + * we need a 3x3 differential filter for UV Input and full buffer for the image + */ + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setAlpha(float alpha){this->alpha = alpha;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_MapValueOperation.cpp b/source/blender/compositor/operations/COM_MapValueOperation.cpp new file mode 100644 index 00000000000..33d38b8475d --- /dev/null +++ b/source/blender/compositor/operations/COM_MapValueOperation.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MapValueOperation.h" + +MapValueOperation::MapValueOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->inputOperation = NULL; +} + +void MapValueOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void MapValueOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float src[4]; + inputOperation->read(src, x, y, sampler, inputBuffers); + TexMapping *texmap= this->settings; + float value = (src[0] + texmap->loc[0])*texmap->size[0]; + if(texmap->flag & TEXMAP_CLIP_MIN) + if(value<texmap->min[0]) + value= texmap->min[0]; + if(texmap->flag & TEXMAP_CLIP_MAX) + if(value>texmap->max[0]) + value= texmap->max[0]; + + outputValue[0] = value; +} + +void MapValueOperation::deinitExecution() { + this->inputOperation = NULL; +} diff --git a/source/blender/compositor/operations/COM_MapValueOperation.h b/source/blender/compositor/operations/COM_MapValueOperation.h new file mode 100644 index 00000000000..93274a12493 --- /dev/null +++ b/source/blender/compositor/operations/COM_MapValueOperation.h @@ -0,0 +1,66 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MapValueOperation_h +#define _COM_MapValueOperation_h +#include "COM_NodeOperation.h" +#include "DNA_texture_types.h" + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MapValueOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputOperation; + TexMapping * settings; +public: + /** + * Default constructor + */ + MapValueOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + /** + * @brief set the TexMapping settings + */ + void setSettings(TexMapping* settings) {this->settings = settings;} + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp new file mode 100644 index 00000000000..55880566bf2 --- /dev/null +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -0,0 +1,239 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MathBaseOperation.h" +extern "C" { +#include "BLI_math.h" +} + +MathBaseOperation::MathBaseOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->inputValue1Operation = NULL; + this->inputValue2Operation = NULL; +} + +void MathBaseOperation::initExecution() { + this->inputValue1Operation = this->getInputSocketReader(0); + this->inputValue2Operation = this->getInputSocketReader(1); +} + + +void MathBaseOperation::deinitExecution() { + this->inputValue1Operation = NULL; + this->inputValue2Operation = NULL; +} + +void MathAddOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = inputValue1[0] + inputValue2[0]; +} + +void MathSubtractOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = inputValue1[0] - inputValue2[0]; +} + +void MathMultiplyOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = inputValue1[0] * inputValue2[0]; +} + +void MathDivideOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + if(inputValue2[0]==0) /* We don't want to divide by zero. */ + outputValue[0]= 0.0; + else + outputValue[0]= inputValue1[0] / inputValue2[0]; +} + +void MathSineOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = sin(inputValue1[0]); +} + +void MathCosineOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = cos(inputValue1[0]); +} + +void MathTangentOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = tan(inputValue1[0]); +} + +void MathArcSineOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + if(inputValue1[0] <= 1 && inputValue1[0] >= -1 ) + outputValue[0]= asin(inputValue1[0]); + else + outputValue[0]= 0.0; +} + +void MathArcCosineOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + if(inputValue1[0] <= 1 && inputValue1[0] >= -1 ) + outputValue[0]= acos(inputValue1[0]); + else + outputValue[0]= 0.0; +} + +void MathArcTangentOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = atan(inputValue1[0]); +} + +void MathPowerOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + if( inputValue1[0] >= 0 ) { + outputValue[0]= pow(inputValue1[0], inputValue2[0]); + } else { + float y_mod_1 = fmod(inputValue2[0], 1); + /* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */ + if (y_mod_1 > 0.999 || y_mod_1 < 0.001) { + outputValue[0]= pow(inputValue1[0], (float)floor(inputValue2[0] + 0.5)); + } else { + outputValue[0] = 0.0; + } + } +} + +void MathLogarithmOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + if( inputValue1[0] > 0 && inputValue2[0] > 0 ) + outputValue[0]= log(inputValue1[0]) / log(inputValue2[0]); + else + outputValue[0]= 0.0; +} + +void MathMinimumOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = min(inputValue1[0], inputValue2[0]); +} + +void MathMaximumOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = max(inputValue1[0], inputValue2[0]); +} + +void MathRoundOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = round(inputValue1[0]); +} + +void MathLessThanOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = inputValue1[0]<inputValue2[0]?1.0f:0.0f; +} + +void MathGreaterThanOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputValue1[4]; + float inputValue2[4]; + + inputValue1Operation->read(&inputValue1[0], x, y, sampler, inputBuffers); + inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers); + + outputValue[0] = inputValue1[0]>inputValue2[0]?1.0f:0.0f; +} + + diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h new file mode 100644 index 00000000000..728d989e1e9 --- /dev/null +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -0,0 +1,150 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MathBaseOperation_h +#define _COM_MathBaseOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MathBaseOperation : public NodeOperation { +protected: + /** + * Prefetched reference to the inputProgram + */ + SocketReader * inputValue1Operation; + SocketReader * inputValue2Operation; + +protected: + /** + * Default constructor + */ + MathBaseOperation(); +public: + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) = 0; + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + +}; + +class MathAddOperation: public MathBaseOperation { +public: + MathAddOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathSubtractOperation: public MathBaseOperation { +public: + MathSubtractOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathMultiplyOperation: public MathBaseOperation { +public: + MathMultiplyOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathDivideOperation: public MathBaseOperation { +public: + MathDivideOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathSineOperation: public MathBaseOperation { +public: + MathSineOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathCosineOperation: public MathBaseOperation { +public: + MathCosineOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathTangentOperation: public MathBaseOperation { +public: + MathTangentOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +class MathArcSineOperation: public MathBaseOperation { +public: + MathArcSineOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathArcCosineOperation: public MathBaseOperation { +public: + MathArcCosineOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathArcTangentOperation: public MathBaseOperation { +public: + MathArcTangentOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathPowerOperation: public MathBaseOperation { +public: + MathPowerOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathLogarithmOperation: public MathBaseOperation { +public: + MathLogarithmOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathMinimumOperation: public MathBaseOperation { +public: + MathMinimumOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathMaximumOperation: public MathBaseOperation { +public: + MathMaximumOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathRoundOperation: public MathBaseOperation { +public: + MathRoundOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathLessThanOperation: public MathBaseOperation { +public: + MathLessThanOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +class MathGreaterThanOperation: public MathBaseOperation { +public: + MathGreaterThanOperation() : MathBaseOperation() {} + void executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_MixAddOperation.cpp b/source/blender/compositor/operations/COM_MixAddOperation.cpp new file mode 100644 index 00000000000..d428ca52b49 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixAddOperation.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixAddOperation.h" + +MixAddOperation::MixAddOperation(): MixBaseOperation() { +} + +void MixAddOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float inputValue[4]; + + inputValueOperation->read(inputValue, x, y, sampler, inputBuffers); + inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); + inputColor2Operation->read(inputColor2, x, y, sampler, inputBuffers); + + + float value = inputValue[0]; + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + outputValue[0] = inputColor1[0]+value*inputColor2[0]; + outputValue[1] = inputColor1[1]+value*inputColor2[1]; + outputValue[2] = inputColor1[2]+value*inputColor2[2]; + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixAddOperation.h b/source/blender/compositor/operations/COM_MixAddOperation.h new file mode 100644 index 00000000000..0a76083be73 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixAddOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixAddOperation_h +#define _COM_MixAddOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixAddOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixAddOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.cpp b/source/blender/compositor/operations/COM_MixBaseOperation.cpp new file mode 100644 index 00000000000..9f8378defe9 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixBaseOperation.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixBaseOperation.h" + +MixBaseOperation::MixBaseOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->inputValueOperation = NULL; + this->inputColor1Operation = NULL; + this->inputColor2Operation = NULL; + this->setUseValueAlphaMultiply(false); +} + +void MixBaseOperation::initExecution() { + this->inputValueOperation = this->getInputSocketReader(0); + this->inputColor1Operation = this->getInputSocketReader(1); + this->inputColor2Operation = this->getInputSocketReader(2); +} + +void MixBaseOperation::executePixel(float* outputColor, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + outputColor[0] = valuem*(inputColor1[0])+value*(inputColor2[0]); + outputColor[1] = valuem*(inputColor1[1])+value*(inputColor2[1]); + outputColor[2] = valuem*(inputColor1[2])+value*(inputColor2[2]); + outputColor[3] = inputColor1[3]; +} + +void MixBaseOperation::deinitExecution() { + this->inputValueOperation = NULL; + this->inputColor1Operation = NULL; + this->inputColor2Operation = NULL; +} + +void MixBaseOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]){ + InputSocket* socket; + unsigned int tempPreferredResolution[] = {0,0}; + unsigned int tempResolution[2]; + + socket = this->getInputSocket(1); + socket->determineResolution(tempResolution, tempPreferredResolution); + if((tempResolution[0] != 0) && (tempResolution[1] != 0)){ + this->setResolutionInputSocketIndex(1); + }else { + socket = this->getInputSocket(2); + tempPreferredResolution[0] = 0; + tempPreferredResolution[1] = 0; + socket->determineResolution(tempResolution, tempPreferredResolution); + if((tempResolution[0] != 0) && (tempResolution[1] != 0)){ + this->setResolutionInputSocketIndex(2); + }else { + this->setResolutionInputSocketIndex(0); + } + } + NodeOperation::determineResolution(resolution, preferredResolution); +} + diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.h b/source/blender/compositor/operations/COM_MixBaseOperation.h new file mode 100644 index 00000000000..171cde080eb --- /dev/null +++ b/source/blender/compositor/operations/COM_MixBaseOperation.h @@ -0,0 +1,67 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixBaseOperation_h +#define _COM_MixBaseOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixBaseOperation : public NodeOperation { +protected: + /** + * Prefetched reference to the inputProgram + */ + SocketReader * inputValueOperation; + SocketReader* inputColor1Operation; + SocketReader* inputColor2Operation; + bool valueAlphaMultiply; +public: + /** + * Default constructor + */ + MixBaseOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + void setUseValueAlphaMultiply(const bool value) {this->valueAlphaMultiply = value;} + bool useValueAlphaMultiply() {return this->valueAlphaMultiply;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixBlendOperation.cpp b/source/blender/compositor/operations/COM_MixBlendOperation.cpp new file mode 100644 index 00000000000..7b12393bb20 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixBlendOperation.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixBlendOperation.h" + +MixBlendOperation::MixBlendOperation(): MixBaseOperation() { +} + +void MixBlendOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float inputValue[4]; + float value; + + inputValueOperation->read(inputValue, x, y, sampler, inputBuffers); + inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); + inputColor2Operation->read(inputColor2, x, y, sampler, inputBuffers); + value = inputValue[0]; + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + outputValue[0] = valuem*(inputColor1[0])+value*(inputColor2[0]); + outputValue[1] = valuem*(inputColor1[1])+value*(inputColor2[1]); + outputValue[2] = valuem*(inputColor1[2])+value*(inputColor2[2]); + outputValue[3] = inputColor1[3]; +} diff --git a/source/blender/compositor/operations/COM_MixBlendOperation.h b/source/blender/compositor/operations/COM_MixBlendOperation.h new file mode 100644 index 00000000000..5cf31ee9151 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixBlendOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixBlendOperation_h +#define _COM_MixBlendOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixBlendOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixBlendOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixBurnOperation.cpp b/source/blender/compositor/operations/COM_MixBurnOperation.cpp new file mode 100644 index 00000000000..28b86be5e1e --- /dev/null +++ b/source/blender/compositor/operations/COM_MixBurnOperation.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixBurnOperation.h" + +MixBurnOperation::MixBurnOperation(): MixBaseOperation() { +} + +void MixBurnOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + float tmp; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + + tmp = valuem + value*inputColor2[0]; + if (tmp <= 0.0f) + outputValue[0] = 0.0f; + else { + tmp = 1.0f - (1.0f - inputColor1[0]) / tmp; + if (tmp < 0.0f) + outputValue[0] = 0.0f; + else if (tmp > 1.0f) + outputValue[0] = 1.0f; + else + outputValue[0] = tmp; + } + + tmp = valuem + value*inputColor2[1]; + if (tmp <= 0.0f) + outputValue[1] = 0.0f; + else { + tmp = 1.0f - (1.0f - inputColor1[1]) / tmp; + if (tmp < 0.0f) + outputValue[1] = 0.0f; + else if (tmp > 1.0f) + outputValue[1] = 1.0f; + else + outputValue[1] = tmp; + } + + tmp = valuem + value*inputColor2[2]; + if (tmp <= 0.0f) + outputValue[2] = 0.0f; + else { + tmp = 1.0f - (1.0f - inputColor1[2]) / tmp; + if (tmp < 0.0f) + outputValue[2] = 0.0f; + else if (tmp > 1.0f) + outputValue[2] = 1.0f; + else + outputValue[2] = tmp; + } + + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixBurnOperation.h b/source/blender/compositor/operations/COM_MixBurnOperation.h new file mode 100644 index 00000000000..132db3d25e7 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixBurnOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixBurnOperation_h +#define _COM_MixBurnOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixBurnOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixBurnOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixColorOperation.cpp b/source/blender/compositor/operations/COM_MixColorOperation.cpp new file mode 100644 index 00000000000..ebcb7056570 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixColorOperation.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixColorOperation.h" + +extern "C" { + #include "BLI_math.h" +} + +MixColorOperation::MixColorOperation(): MixBaseOperation() { +} + +void MixColorOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + + float colH,colS,colV; + rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); + if(colS!=0.0f){ + float rH,rS,rV; + float tmpr,tmpg,tmpb; + rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); + hsv_to_rgb(colH , colS, rV, &tmpr, &tmpg, &tmpb); + outputValue[0] = valuem*(inputColor1[0]) + value*tmpr; + outputValue[1] = valuem*(inputColor1[1]) + value*tmpg; + outputValue[2] = valuem*(inputColor1[2]) + value*tmpb; + } + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixColorOperation.h b/source/blender/compositor/operations/COM_MixColorOperation.h new file mode 100644 index 00000000000..dfbdcfc0368 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixColorOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixColorOperation_h +#define _COM_MixColorOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixColorOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixColorOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp new file mode 100644 index 00000000000..773a51e92cb --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixDarkenOperation.h" + +MixDarkenOperation::MixDarkenOperation(): MixBaseOperation() { +} + +void MixDarkenOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem = 1.0f-value; + float tmp; + tmp=inputColor2[0]+((1.0f-inputColor2[0])*valuem); + if(tmp < inputColor1[0]) outputValue[0]= tmp; + else outputValue[0] = inputColor1[0]; + tmp=inputColor2[1]+((1.0f-inputColor2[1])*valuem); + if(tmp < inputColor1[1]) outputValue[1]= tmp; + else outputValue[1] = inputColor1[1]; + tmp=inputColor2[2]+((1.0f-inputColor2[2])*valuem); + if(tmp < inputColor1[2]) outputValue[2]= tmp; + else outputValue[2] = inputColor1[2]; + + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixDarkenOperation.h b/source/blender/compositor/operations/COM_MixDarkenOperation.h new file mode 100644 index 00000000000..7ead435212d --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDarkenOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixDarkenOperation_h +#define _COM_MixDarkenOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixDarkenOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixDarkenOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp new file mode 100644 index 00000000000..4ea1428b387 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixDifferenceOperation.h" +#include "BLI_math.h" + +MixDifferenceOperation::MixDifferenceOperation(): MixBaseOperation() { +} + +void MixDifferenceOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + outputValue[0] = valuem*inputColor1[0] + value*fabsf(inputColor1[0]-inputColor2[0]); + outputValue[1] = valuem*inputColor1[1] + value*fabsf(inputColor1[1]-inputColor2[1]); + outputValue[2] = valuem*inputColor1[2] + value*fabsf(inputColor1[2]-inputColor2[2]); + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixDifferenceOperation.h b/source/blender/compositor/operations/COM_MixDifferenceOperation.h new file mode 100644 index 00000000000..9b95d5a91ad --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDifferenceOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixDifferenceOperation_h +#define _COM_MixDifferenceOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixDifferenceOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixDifferenceOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixDivideOperation.cpp b/source/blender/compositor/operations/COM_MixDivideOperation.cpp new file mode 100644 index 00000000000..c2579c6a89c --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDivideOperation.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixDivideOperation.h" + +MixDivideOperation::MixDivideOperation(): MixBaseOperation() { +} + +void MixDivideOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + + if(inputColor2[0]!=0.0f) + outputValue[0] = valuem*(inputColor1[0]) + value*(inputColor1[0])/inputColor2[0]; + else + outputValue[0] = 0.0f; + if(inputColor2[1]!=0.0f) + outputValue[1] = valuem*(inputColor1[1]) + value*(inputColor1[1])/inputColor2[1]; + else + outputValue[1] = 0.0f; + if(inputColor2[2]!=0.0f) + outputValue[2] = valuem*(inputColor1[2]) + value*(inputColor1[2])/inputColor2[2]; + else + outputValue[2] = 0.0f; + + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixDivideOperation.h b/source/blender/compositor/operations/COM_MixDivideOperation.h new file mode 100644 index 00000000000..d43ddb49c91 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDivideOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixDivideOperation_h +#define _COM_MixDivideOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixDivideOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixDivideOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp new file mode 100644 index 00000000000..7e6ddeee5e6 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixDodgeOperation.h" + +MixDodgeOperation::MixDodgeOperation(): MixBaseOperation() { +} + +void MixDodgeOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + float tmp; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + + if (inputColor1[0] != 0.0f) { + tmp = 1.0f - value*inputColor2[0]; + if (tmp <= 0.0f) + outputValue[0] = 1.0f; + else { + tmp = inputColor1[0] / tmp; + if (tmp > 1.0f) + outputValue[0] = 1.0f; + else + outputValue[0] = tmp; + } + } + else + outputValue[0] = 0.0f; + + if (inputColor1[1] != 0.0f) { + tmp = 1.0f - value*inputColor2[1]; + if (tmp <= 0.0f) + outputValue[1] = 1.0f; + else { + tmp = inputColor1[1] / tmp; + if (tmp > 1.0f) + outputValue[1] = 1.0f; + else + outputValue[1] = tmp; + } + } + else + outputValue[1] = 0.0f; + + if (inputColor1[2] != 0.0f) { + tmp = 1.0f - value*inputColor2[2]; + if (tmp <= 0.0f) + outputValue[2] = 1.0f; + else { + tmp = inputColor1[2] / tmp; + if (tmp > 1.0f) + outputValue[2] = 1.0f; + else + outputValue[2] = tmp; + } + } + else + outputValue[2] = 0.0f; + + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixDodgeOperation.h b/source/blender/compositor/operations/COM_MixDodgeOperation.h new file mode 100644 index 00000000000..0a910c167ba --- /dev/null +++ b/source/blender/compositor/operations/COM_MixDodgeOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixDodgeOperation_h +#define _COM_MixDodgeOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixDodgeOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixDodgeOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixHueOperation.cpp b/source/blender/compositor/operations/COM_MixHueOperation.cpp new file mode 100644 index 00000000000..386bd02ba2a --- /dev/null +++ b/source/blender/compositor/operations/COM_MixHueOperation.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixHueOperation.h" + +extern "C" { + #include "BLI_math.h" +} + +MixHueOperation::MixHueOperation(): MixBaseOperation() { +} + +void MixHueOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + + float colH,colS,colV; + rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); + if(colS!=0.0f){ + float rH,rS,rV; + float tmpr,tmpg,tmpb; + rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); + hsv_to_rgb(colH , rS, rV, &tmpr, &tmpg, &tmpb); + outputValue[0] = valuem*(inputColor1[0]) + value*tmpr; + outputValue[1] = valuem*(inputColor1[1]) + value*tmpg; + outputValue[2] = valuem*(inputColor1[2]) + value*tmpb; + } + outputValue[3] = inputColor1[3]; +} diff --git a/source/blender/compositor/operations/COM_MixHueOperation.h b/source/blender/compositor/operations/COM_MixHueOperation.h new file mode 100644 index 00000000000..5e46b625385 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixHueOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixHueOperation_h +#define _COM_MixHueOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixHueOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixHueOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixLightenOperation.cpp b/source/blender/compositor/operations/COM_MixLightenOperation.cpp new file mode 100644 index 00000000000..32d28b785b7 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixLightenOperation.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixLightenOperation.h" + +MixLightenOperation::MixLightenOperation(): MixBaseOperation() { +} + +void MixLightenOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float tmp; + tmp=value * inputColor2[0]; + if(tmp > inputColor1[0]) outputValue[0]= tmp; + else outputValue[0] = inputColor1[0]; + tmp=value * inputColor2[1]; + if(tmp > inputColor1[1]) outputValue[1]= tmp; + else outputValue[1] = inputColor1[1]; + tmp=value * inputColor2[2]; + if(tmp > inputColor1[2]) outputValue[2]= tmp; + else outputValue[2] = inputColor1[2]; + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixLightenOperation.h b/source/blender/compositor/operations/COM_MixLightenOperation.h new file mode 100644 index 00000000000..64b1bf9bbc9 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixLightenOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixLightenOperation_h +#define _COM_MixLightenOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixLightenOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixLightenOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp new file mode 100644 index 00000000000..413b09d7242 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixLinearLightOperation.h" + +MixLinearLightOperation::MixLinearLightOperation(): MixBaseOperation() { +} + +void MixLinearLightOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + if (inputColor2[0] > 0.5f) + outputValue[0] = inputColor1[0] + value*(2.0f*(inputColor2[0]-0.5f)); + else + outputValue[0] = inputColor1[0] + value*(2.0f*(inputColor2[0]) - 1.0f); + if (inputColor2[1] > 0.5f) + outputValue[1] = inputColor1[1] + value*(2.0f*(inputColor2[1]-0.5f)); + else + outputValue[1] = inputColor1[1] + value*(2.0f*(inputColor2[1]) - 1.0f); + if (inputColor2[2] > 0.5f) + outputValue[2] = inputColor1[2] + value*(2.0f*(inputColor2[2]-0.5f)); + else + outputValue[2] = inputColor1[2] + value*(2.0f*(inputColor2[2]) - 1.0f); + + outputValue[3] = inputColor1[3]; +} diff --git a/source/blender/compositor/operations/COM_MixLinearLightOperation.h b/source/blender/compositor/operations/COM_MixLinearLightOperation.h new file mode 100644 index 00000000000..9fb2a433104 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixLinearLightOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixLinearLightOperation_h +#define _COM_MixLinearLightOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixLinearLightOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixLinearLightOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp b/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp new file mode 100644 index 00000000000..82c6c2e9c1f --- /dev/null +++ b/source/blender/compositor/operations/COM_MixMultiplyOperation.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixMultiplyOperation.h" + +MixMultiplyOperation::MixMultiplyOperation(): MixBaseOperation() { +} + +void MixMultiplyOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float inputValue[4]; + + inputValueOperation->read(inputValue, x, y, sampler, inputBuffers); + inputColor1Operation->read(inputColor1, x, y, sampler, inputBuffers); + inputColor2Operation->read(inputColor2, x, y, sampler, inputBuffers); + + float value = inputValue[0]; + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + outputValue[0] = inputColor1[0] *(valuem+value*inputColor2[0]); + outputValue[1] = inputColor1[1] *(valuem+value*inputColor2[1]); + outputValue[2] = inputColor1[2] *(valuem+value*inputColor2[2]); + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixMultiplyOperation.h b/source/blender/compositor/operations/COM_MixMultiplyOperation.h new file mode 100644 index 00000000000..c35e4bbf64b --- /dev/null +++ b/source/blender/compositor/operations/COM_MixMultiplyOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixMultiplyOperation_h +#define _COM_MixMultiplyOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixMultiplyOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixMultiplyOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp new file mode 100644 index 00000000000..8254701adad --- /dev/null +++ b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixOverlayOperation.h" + +MixOverlayOperation::MixOverlayOperation(): MixBaseOperation() { +} + +void MixOverlayOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + + float valuem= 1.0f-value; + + if(inputColor1[0] < 0.5f) { + outputValue[0] = inputColor1[0] * (valuem + 2.0f*value*inputColor2[0]); + } else { + outputValue[0] = 1.0f - (valuem + 2.0f*value*(1.0f - inputColor2[0])) * (1.0f - inputColor1[0]); + } + if(inputColor1[1] < 0.5f) { + outputValue[1] = inputColor1[1] * (valuem + 2.0f*value*inputColor2[1]); + } else { + outputValue[1] = 1.0f - (valuem + 2.0f*value*(1.0f - inputColor2[1])) * (1.0f - inputColor1[1]); + } + if(inputColor1[2] < 0.5f) { + outputValue[2] = inputColor1[2] * (valuem + 2.0f*value*inputColor2[2]); + } else { + outputValue[2] = 1.0f - (valuem + 2.0f*value*(1.0f - inputColor2[2])) * (1.0f - inputColor1[2]); + } + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixOverlayOperation.h b/source/blender/compositor/operations/COM_MixOverlayOperation.h new file mode 100644 index 00000000000..1a0e865b0e8 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixOverlayOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixOverlayOperation_h +#define _COM_MixOverlayOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixOverlayOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixOverlayOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp new file mode 100644 index 00000000000..18ff6f46c46 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixSaturationOperation.h" + +extern "C" { + #include "BLI_math.h" +} + +MixSaturationOperation::MixSaturationOperation(): MixBaseOperation() { +} + +void MixSaturationOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + + float rH,rS,rV; + rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); + if(rS!=0.0f){ + float colH,colS,colV; + rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); + hsv_to_rgb(rH , (valuem*rS+value*colS), rV, &outputValue[0], &outputValue[1], &outputValue[2]); + } + outputValue[3] = inputColor1[3]; +} diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.h b/source/blender/compositor/operations/COM_MixSaturationOperation.h new file mode 100644 index 00000000000..cea2c886a06 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixSaturationOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixSaturationOperation_h +#define _COM_MixSaturationOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixSaturationOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixSaturationOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixScreenOperation.cpp b/source/blender/compositor/operations/COM_MixScreenOperation.cpp new file mode 100644 index 00000000000..25004ca7257 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixScreenOperation.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixScreenOperation.h" + +MixScreenOperation::MixScreenOperation(): MixBaseOperation() { +} + +void MixScreenOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float valuev[4]; + + inputValueOperation->read(valuev, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + float value = valuev[0]; + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + + outputValue[0] = 1.0f - (valuem + value*(1.0f-inputColor2[0])) *(1.0f-inputColor1[0]); + outputValue[1] = 1.0f - (valuem + value*(1.0f-inputColor2[1])) *(1.0f-inputColor1[1]); + outputValue[2] = 1.0f - (valuem + value*(1.0f-inputColor2[2])) *(1.0f-inputColor1[2]); + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixScreenOperation.h b/source/blender/compositor/operations/COM_MixScreenOperation.h new file mode 100644 index 00000000000..5fb99c7582f --- /dev/null +++ b/source/blender/compositor/operations/COM_MixScreenOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixScreenOperation_h +#define _COM_MixScreenOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixScreenOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixScreenOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp new file mode 100644 index 00000000000..3195b3440ec --- /dev/null +++ b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixSoftLightOperation.h" + +MixSoftLightOperation::MixSoftLightOperation(): MixBaseOperation() { +} + +void MixSoftLightOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem = 1.0f-value; + float scr, scg, scb; + + /* first calculate non-fac based Screen mix */ + scr = 1.0f - (1.0f - inputColor2[0]) * (1.0f - inputColor1[0]); + scg = 1.0f - (1.0f - inputColor2[1]) * (1.0f - inputColor1[1]); + scb = 1.0f - (1.0f - inputColor2[2]) * (1.0f - inputColor1[2]); + + outputValue[0] = valuem*(inputColor1[0]) + value*(((1.0f - inputColor1[0]) * inputColor2[0] * (inputColor1[0])) + (inputColor1[0] * scr)); + outputValue[1] = valuem*(inputColor1[1]) + value*(((1.0f - inputColor1[1]) * inputColor2[1] * (inputColor1[1])) + (inputColor1[1] * scg)); + outputValue[2] = valuem*(inputColor1[2]) + value*(((1.0f - inputColor1[2]) * inputColor2[2] * (inputColor1[2])) + (inputColor1[2] * scb)); + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixSoftLightOperation.h b/source/blender/compositor/operations/COM_MixSoftLightOperation.h new file mode 100644 index 00000000000..1f5e9a24f07 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixSoftLightOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixSoftLightOperation_h +#define _COM_MixSoftLightOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixSoftLightOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixSoftLightOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp new file mode 100644 index 00000000000..49792c99c27 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixSubtractOperation.h" + +MixSubtractOperation::MixSubtractOperation(): MixBaseOperation() { +} + +void MixSubtractOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + outputValue[0] = inputColor1[0]-value*(inputColor2[0]); + outputValue[1] = inputColor1[1]-value*(inputColor2[1]); + outputValue[2] = inputColor1[2]-value*(inputColor2[2]); + outputValue[3] = inputColor1[3]; +} + diff --git a/source/blender/compositor/operations/COM_MixSubtractOperation.h b/source/blender/compositor/operations/COM_MixSubtractOperation.h new file mode 100644 index 00000000000..119d614081f --- /dev/null +++ b/source/blender/compositor/operations/COM_MixSubtractOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixSubtractOperation_h +#define _COM_MixSubtractOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixSubtractOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixSubtractOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_MixValueOperation.cpp b/source/blender/compositor/operations/COM_MixValueOperation.cpp new file mode 100644 index 00000000000..93bb7b59b5f --- /dev/null +++ b/source/blender/compositor/operations/COM_MixValueOperation.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MixValueOperation.h" + +extern "C" { + #include "BLI_math.h" +} + +MixValueOperation::MixValueOperation(): MixBaseOperation() { +} + +void MixValueOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float inputColor1[4]; + float inputColor2[4]; + float value; + + inputValueOperation->read(&value, x, y, sampler, inputBuffers); + inputColor1Operation->read(&inputColor1[0], x, y, sampler, inputBuffers); + inputColor2Operation->read(&inputColor2[0], x, y, sampler, inputBuffers); + + if (this->useValueAlphaMultiply()) { + value *= inputColor2[3]; + } + float valuem= 1.0f-value; + + float rH,rS,rV; + float colH,colS,colV; + rgb_to_hsv(inputColor1[0], inputColor1[1], inputColor1[2], &rH, &rS, &rV); + rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); + hsv_to_rgb(rH , rS, (valuem*rV+value*colV), &outputValue[0], &outputValue[1], &outputValue[2]); + outputValue[3] = inputColor1[3]; +} diff --git a/source/blender/compositor/operations/COM_MixValueOperation.h b/source/blender/compositor/operations/COM_MixValueOperation.h new file mode 100644 index 00000000000..ce358ebb506 --- /dev/null +++ b/source/blender/compositor/operations/COM_MixValueOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MixValueOperation_h +#define _COM_MixValueOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MixValueOperation : public MixBaseOperation { +public: + /** + * Default constructor + */ + MixValueOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; +#endif diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp new file mode 100644 index 00000000000..5d0e7e4a4fe --- /dev/null +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MovieClipAttributeOperation.h" +extern "C" { + #include "BKE_tracking.h" +} +MovieClipAttributeOperation::MovieClipAttributeOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_VALUE); + this->valueSet = false; + this->framenumber = 0; + this->attribute = MCA_X; +} + +void MovieClipAttributeOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + if (!valueSet) { + float loc[2], scale, angle; + loc[0] = 0.0f; + loc[1] = 0.0f; + scale = 1.0f; + angle = 0.0f; + if (clip) { + BKE_tracking_stabilization_data(&clip->tracking, framenumber, getWidth(), getHeight(), loc, &scale, &angle); + } + switch (this->attribute) { + case MCA_SCALE: + this->value = scale; + break; + case MCA_ANGLE: + this->value = angle; + break; + case MCA_X: + this->value = loc[0]; + break; + case MCA_Y: + this->value = loc[1]; + break; + } + valueSet = true; + } + outputValue[0] = this->value; +} + +void MovieClipAttributeOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + resolution[0] = preferredResolution[0]; + resolution[1] = preferredResolution[1]; +} + diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h new file mode 100644 index 00000000000..960d837dd7e --- /dev/null +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h @@ -0,0 +1,61 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MovieClipAttributeOperation_h +#define _COM_MovieClipAttributeOperation_h +#include "COM_NodeOperation.h" +#include "DNA_movieclip_types.h" + +typedef enum MovieClipAttribute { + MCA_SCALE, + MCA_X, + MCA_Y, + MCA_ANGLE +} MovieClipAttribute; +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class MovieClipAttributeOperation : public NodeOperation { +private: + MovieClip * clip; + float value; + bool valueSet; + int framenumber; + MovieClipAttribute attribute; +public: + /** + * Default constructor + */ + MovieClipAttributeOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + void setMovieClip(MovieClip* clip) {this->clip = clip;} + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + void setAttribute(MovieClipAttribute attribute) {this->attribute = attribute;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp new file mode 100644 index 00000000000..74179293c6c --- /dev/null +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MovieClipOperation.h" + +#include "BLI_listbase.h" +#include "DNA_scene_types.h" +#include "BLI_math.h" +extern "C" { + #include "BKE_movieclip.h" + #include "IMB_imbuf.h" +} +#include "BKE_image.h" + +MovieClipOperation::MovieClipOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_COLOR); + this->movieClip = NULL; + this->movieClipBuffer = NULL; + this->movieClipUser = NULL; + this->movieClipwidth = 0; + this->movieClipheight = 0; + this->framenumber = 0; +} + + +void MovieClipOperation::initExecution() { + if (this->movieClip) { + BKE_movieclip_user_set_frame(this->movieClipUser, this->framenumber); + ImBuf *ibuf; + ibuf= BKE_movieclip_get_ibuf(this->movieClip, this->movieClipUser); + if (ibuf) { + this->movieClipBuffer = ibuf; + if (ibuf->rect_float == NULL || ibuf->userflags&IB_RECT_INVALID) { + IMB_float_from_rect(ibuf); + ibuf->userflags&= ~IB_RECT_INVALID; + } + } + } +} + +void MovieClipOperation::deinitExecution() { + this->movieClipBuffer = NULL; +} + +void MovieClipOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + ImBuf *ibuf; + if (this->movieClip) { + ibuf= BKE_movieclip_get_ibuf(this->movieClip, this->movieClipUser); + if (ibuf) { + resolution[0] = ibuf->x; + resolution[1] = ibuf->y; + } + } +} + +void MovieClipOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + if (this->movieClipBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 0.0f; + } else { + switch (sampler) { + case COM_PS_NEAREST: + neareast_interpolation_color(this->movieClipBuffer, NULL, color, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->movieClipBuffer, NULL, color, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->movieClipBuffer, NULL, color, x, y); + break; + } + } +} diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h new file mode 100644 index 00000000000..c861115dee8 --- /dev/null +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + + +#ifndef _COM_ImageOperation_h +#define _COM_ImageOperation_h + +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "DNA_movieclip_types.h" +#include "BLI_listbase.h" +#include "IMB_imbuf_types.h" + +/** + * Base class for all renderlayeroperations + * + * @todo: rename to operation. + */ +class MovieClipOperation : public NodeOperation { +protected: + MovieClip* movieClip; + MovieClipUser* movieClipUser; + ImBuf *movieClipBuffer; + int movieClipheight; + int movieClipwidth; + int framenumber; + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + +public: + MovieClipOperation(); + + void initExecution(); + void deinitExecution(); + void setMovieClip(MovieClip* image) {this->movieClip = image;} + void setMovieClipUser(MovieClipUser* imageuser) {this->movieClipUser = imageuser;} + + void setFramenumber(int framenumber) {this->framenumber = framenumber;} + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp new file mode 100644 index 00000000000..360719aa59f --- /dev/null +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_MovieDistortionOperation.h" + +extern "C" { + #include "BKE_tracking.h" + +#include "BLI_linklist.h" +} + + +vector<DistortionCache*> s_cache; + + +MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputOperation = NULL; + this->movieClip = NULL; + this->cache = NULL; + this->distortion = distortion; +} +void MovieDistortionOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); + if (this->movieClip) { + for (int i = 0 ; i < s_cache.size() ; i ++) { + DistortionCache* c = (DistortionCache*)s_cache[i]; + if (c->isCacheFor(this->movieClip, this->width, this->height, this->distortion)) { + this->cache = c; + return; + } + } + DistortionCache* newC = new DistortionCache(this->movieClip, this->width, this->height, this->distortion); + s_cache.push_back(newC); + this->cache = newC; + } else { + this->cache = NULL; + } +} + +void MovieDistortionOperation::deinitExecution() { + this->inputOperation = NULL; + this->movieClip = NULL; +} + + +void MovieDistortionOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + + if (this->cache != NULL) { + float u, v; + this->cache->getUV(&this->movieClip->tracking, x, y, &u, &v); + this->inputOperation->read(color, u, v, sampler, inputBuffers); + } + else { + this->inputOperation->read(color, x, y, sampler, inputBuffers); + } +} + +bool MovieDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + newInput.xmax = input->xmax + 100; + newInput.xmin = input->xmin - 100; + newInput.ymax = input->ymax + 100; + newInput.ymin = input->ymin - 100; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h new file mode 100644 index 00000000000..21aa955075d --- /dev/null +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -0,0 +1,113 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_MovieDistortionOperation_h_ +#define _COM_MovieDistortionOperation_h_ + +#include "COM_NodeOperation.h" +#include "DNA_movieclip_types.h" +extern "C" { + #include "BKE_tracking.h" +} + +class DistortionCache { +private: + float k1; + float k2; + float k3; + int width; + int height; + bool inverted; + float *buffer; + int *bufferCalculated; +public: + DistortionCache(MovieClip* movieclip, int width, int height, bool inverted) { + this->k1 = movieclip->tracking.camera.k1; + this->k2 = movieclip->tracking.camera.k2; + this->k3 = movieclip->tracking.camera.k3; + this->width = width; + this->height = height; + this->inverted = inverted; + this->bufferCalculated = new int[this->width*this->height]; + this->buffer = new float[this->width*this->height*2]; + for (int i = 0 ; i < this->width*this->height ; i ++) { + this->bufferCalculated[i] = 0; + } + } + bool isCacheFor(MovieClip* movieclip, int width, int height, bool inverted) { + return this->k1 == movieclip->tracking.camera.k1 && + this->k2 == movieclip->tracking.camera.k2 && + this->k3 == movieclip->tracking.camera.k3 && + this->inverted == inverted && + this->width == width && + this->height == height; + } + + void getUV(MovieTracking* trackingData, int x, int y, float *u, float*v) { + if (x<0 || x >= this->width || y <0 || y >= this->height) { + *u = x; + *v = y; + } else { + int offset = y * this->width + x; + int offset2 = offset*2; + if (!bufferCalculated[offset]) { + float in[2]; + float out[2]; + in[0] = x; + in[1] = y; + if (inverted) { + BKE_tracking_invert_intrinsics(trackingData, in, out); + } else { + BKE_tracking_apply_intrinsics(trackingData, in, out); + } + buffer[offset2] = out[0]; + buffer[offset2+1] = out[1]; + bufferCalculated[offset] = 1; + } + *u = buffer[offset2]; + *v = buffer[offset2+1]; + } + } +}; + +class MovieDistortionOperation: public NodeOperation { +private: + DistortionCache *cache; + SocketReader *inputOperation; + MovieClip * movieClip; + +protected: + bool distortion; + +public: + MovieDistortionOperation(bool distortion); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setMovieClip(MovieClip* clip) {this->movieClip = clip;} + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp new file mode 100644 index 00000000000..53b71ed528e --- /dev/null +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Lukas Tönne + */ + +#include "COM_MultilayerImageOperation.h" +extern "C" { + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + +MultilayerBaseOperation::MultilayerBaseOperation(int pass): BaseImageOperation() { + this->passId = pass; +} +ImBuf* MultilayerBaseOperation::getImBuf() { + RenderPass *rpass; + rpass = (RenderPass *)BLI_findlink(&this->renderlayer->passes, this->passId); + if(rpass) { + this->imageUser->pass= this->passId; + BKE_image_multilayer_index(image->rr, this->imageUser); + return BaseImageOperation::getImBuf(); + } + return NULL; +} + +void MultilayerColorOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + int yi = y; + int xi = x; + if (this->imageBuffer == NULL || xi < 0 || yi < 0 || xi >= this->getWidth() || yi >= this->getHeight() ) { + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 0.0f; + } else { + if (this->numberOfChannels == 4) { + switch (sampler) { + case COM_PS_NEAREST: + neareast_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(this->buffer, NULL, color, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(this->buffer, NULL, color, x, y); + break; + } + } else { + int offset = (yi*this->getWidth()+xi)*3; + color[0] = this->imageBuffer[offset]; + color[1] = this->imageBuffer[offset+1]; + color[2] = this->imageBuffer[offset+2]; + } + } +} + +void MultilayerValueOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + int yi = y; + int xi = x; + if (this->imageBuffer == NULL || xi < 0 || yi < 0 || xi >= this->getWidth() || yi >= this->getHeight() ) { + color[0] = 0.0f; + } else { + float result = this->imageBuffer[yi*this->getWidth()+xi]; + color[0] = result; + } +} + +void MultilayerVectorOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + int yi = y; + int xi = x; + if (this->imageBuffer == NULL || xi < 0 || yi < 0 || xi >= this->getWidth() || yi >= this->getHeight() ) { + color[0] = 0.0f; + } else { + int offset = (yi*this->getWidth()+xi)*3; + color[0] = this->imageBuffer[offset]; + color[1] = this->imageBuffer[offset+1]; + color[2] = this->imageBuffer[offset+2]; + } +} diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h new file mode 100644 index 00000000000..37e8020d56c --- /dev/null +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h @@ -0,0 +1,68 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Lukas Tönne + */ + + +#ifndef _COM_MultilayerImageOperation_h +#define _COM_MultilayerImageOperation_h + +#include "COM_ImageOperation.h" + +class MultilayerBaseOperation: public BaseImageOperation { +private: + int passId; + RenderLayer* renderlayer; +protected: + ImBuf* getImBuf(); +public: + /** + * Constructor + */ + MultilayerBaseOperation(int pass); + void setRenderLayer(RenderLayer *renderlayer) {this->renderlayer = renderlayer;} +}; + +class MultilayerColorOperation: public MultilayerBaseOperation { +public: + MultilayerColorOperation(int pass): MultilayerBaseOperation(pass) { + this->addOutputSocket(COM_DT_COLOR); + } + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +class MultilayerValueOperation: public MultilayerBaseOperation { +public: + MultilayerValueOperation(int pass): MultilayerBaseOperation(pass) { + this->addOutputSocket(COM_DT_VALUE); + } + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +class MultilayerVectorOperation: public MultilayerBaseOperation { +public: + MultilayerVectorOperation(int pass): MultilayerBaseOperation(pass) { + this->addOutputSocket(COM_DT_VECTOR); + } + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp new file mode 100644 index 00000000000..ade2fde8d07 --- /dev/null +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp @@ -0,0 +1,108 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_NormalizeOperation.h" + +NormalizeOperation::NormalizeOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->imageReader = NULL; + this->cachedInstance = NULL; + this->setComplex(true); +} +void NormalizeOperation::initExecution() { + this->imageReader = this->getInputSocketReader(0); + NodeOperation::initMutex(); +} + +void NormalizeOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data) { + /* using generic two floats struct to store x: min y: mult */ + NodeTwoFloats *minmult = (NodeTwoFloats *)data; + + float output[4]; + this->imageReader->read(output, x, y, inputBuffers, NULL); + + color[0] = (output[0] - minmult->x) * minmult->y; +} + +void NormalizeOperation::deinitExecution() { + this->imageReader = NULL; + if (this->cachedInstance) { + delete cachedInstance; + } + NodeOperation::deinitMutex(); +} + +bool NormalizeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti imageInput; + + NodeOperation* operation = getInputOperation(0); + imageInput.xmax = operation->getWidth(); + imageInput.xmin = 0; + imageInput.ymax = operation->getHeight(); + imageInput.ymin = 0; + + if (operation->determineDependingAreaOfInterest(&imageInput, readOperation, output) ) { + return true; + } + return false; +} + +/* The code below assumes all data is inside range +- this, and that input buffer is single channel */ +#define BLENDER_ZMAX 10000.0f + +void* NormalizeOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + + BLI_mutex_lock(getMutex()); + + if (this->cachedInstance == NULL) { + MemoryBuffer* tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + /* using generic two floats struct to store x: min y: mult */ + NodeTwoFloats *minmult = new NodeTwoFloats(); + + float *buffer = tile->getBuffer(); + int p = tile->getWidth() * tile->getHeight(); + float *bc = buffer; + + float minv = 1.0f+BLENDER_ZMAX; + float maxv = -1.0f-BLENDER_ZMAX; + + float value; + while (p--) { + value=bc[0]; + maxv = max(value, maxv); + minv = min(value, minv); + bc+=4; + } + + minmult->x = minv; + /* The rare case of flat buffer would cause a divide by 0 */ + minmult->y = ((maxv!=minv)? 1.0f/(maxv-minv):0.f); + + this->cachedInstance = minmult; + } + + BLI_mutex_unlock(getMutex()); + return this->cachedInstance; +} + +void NormalizeOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) { +} diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.h b/source/blender/compositor/operations/COM_NormalizeOperation.h new file mode 100644 index 00000000000..9475cd3852a --- /dev/null +++ b/source/blender/compositor/operations/COM_NormalizeOperation.h @@ -0,0 +1,69 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_NormalizeOperation_h +#define _COM_NormalizeOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" + +/** + * @brief base class of normalize, implementing the simple normalize + * @ingroup operation + */ +class NormalizeOperation : public NodeOperation { +protected: + /** + * @brief Cached reference to the reader + */ + SocketReader * imageReader; + + /** + * @brief temporarily cache of the execution storage + * it stores x->min and y->mult + */ + NodeTwoFloats * cachedInstance; + +public: + NormalizeOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + + /** + * Initialize the execution + */ + void initExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl new file mode 100644 index 00000000000..d462f5d8250 --- /dev/null +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -0,0 +1,9 @@ +/// This file contains all opencl kernels for node-operation implementations + +__kernel void testKernel(__global __write_only image2d_t output){ + int x = get_global_id(0); + int y = get_global_id(1); + int2 coords = {x, y}; + float4 color = {0.0f, 1.0f, 0.0f, 1.0f}; + write_imagef(output, coords, color); +} diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl.cpp b/source/blender/compositor/operations/COM_OpenCLKernels.cl.cpp new file mode 100644 index 00000000000..4cf50823c00 --- /dev/null +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl.cpp @@ -0,0 +1,14 @@ +/// @todo: this source needs to be generated from COM_OpenCLKernels.cl. +/// not implemented yet. new data to h + +const char* sourcecode = "/// This file contains all opencl kernels for node-operation implementations \n" \ +"\n" \ +"__kernel void testKernel(__global __write_only image2d_t output){\n" \ +" int x = get_global_id(0);\n" \ +" int y = get_global_id(1);\n" \ +" int2 coords = {x, y}; \n" \ +" float4 color = {0.0f, 1.0f, 0.0f, 1.0f};\n" \ +" write_imagef(output, coords, color);\n" \ +"}\n" \ +"\0\n"; + diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp new file mode 100644 index 00000000000..e410dd966c8 --- /dev/null +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -0,0 +1,260 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Lukas Tönne + */ + +#include "COM_OutputFileOperation.h" +#include "COM_SocketConnection.h" +#include <string.h> +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "DNA_scene_types.h" +#include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_main.h" + +extern "C" { + #include "MEM_guardedalloc.h" + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + +static int get_datatype_size(DataType datatype) +{ + switch (datatype) { + case COM_DT_VALUE: return 1; + case COM_DT_VECTOR: return 3; + case COM_DT_COLOR: return 4; + default: return 0; + } +} + +static float *init_buffer(unsigned int width, unsigned int height, DataType datatype) { + // When initializing the tree during initial load the width and height can be zero. + if (width != 0 && height != 0) { + int size = get_datatype_size(datatype); + return (float *)MEM_callocN(width*height*size*sizeof(float), "OutputFile buffer"); + } + else + return NULL; +} + +static void write_buffer_rect(rcti *rect, MemoryBuffer** memoryBuffers, const bNodeTree *tree, + SocketReader *reader, float* buffer, unsigned int width, DataType datatype) +{ + float color[4]; + int i, size = get_datatype_size(datatype); + + if (!buffer) return; + int x1 = rect->xmin; + int y1 = rect->ymin; + int x2 = rect->xmax; + int y2 = rect->ymax; + int offset = (y1*width + x1 ) * size; + int x; + int y; + bool breaked = false; + + for (y = y1 ; y < y2 && (!breaked); y++) { + for (x = x1 ; x < x2 && (!breaked) ; x++) { + reader->read(color, x, y, COM_PS_NEAREST, memoryBuffers); + + for (i=0; i < size; ++i) + buffer[offset+i] = color[i]; + offset += size; + + if (tree->test_break && tree->test_break(tree->tbh)) + breaked = true; + } + offset += (width-(x2-x1)) * size; + } +} + + +OutputSingleLayerOperation::OutputSingleLayerOperation( + const Scene *scene, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path) +{ + this->scene = scene; + this->tree = tree; + + this->addInputSocket(datatype); + + this->outputBuffer = NULL; + this->datatype = datatype; + this->imageInput = NULL; + + this->format = format; + BLI_strncpy(this->path, path, sizeof(this->path)); +} + +void OutputSingleLayerOperation::initExecution() { + this->imageInput = getInputSocketReader(0); + this->outputBuffer = init_buffer(this->getWidth(), this->getHeight(), this->datatype); +} + +void OutputSingleLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) { + write_buffer_rect(rect, memoryBuffers, this->tree, imageInput, this->outputBuffer, this->getWidth(), this->datatype); +} + +void OutputSingleLayerOperation::deinitExecution() +{ + if (this->getWidth() * this->getHeight() != 0) { + + int size = get_datatype_size(this->datatype); + ImBuf *ibuf= IMB_allocImBuf(this->getWidth(), this->getHeight(), size*8, 0); + Main *bmain= G.main; /* TODO, have this passed along */ + char filename[FILE_MAX]; + + ibuf->channels = size; + ibuf->rect_float= this->outputBuffer; + ibuf->mall |= IB_rectfloat; + ibuf->dither= scene->r.dither_intensity; + + if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) + ibuf->profile = IB_PROFILE_LINEAR_RGB; + + BKE_makepicstring(filename, this->path, bmain->name, this->scene->r.cfra, this->format->imtype, + (this->scene->r.scemode & R_EXTENSION), true); + + if (0 == BKE_imbuf_write(ibuf, filename, this->format)) + printf("Cannot save Node File Output to %s\n", filename); + else + printf("Saved: %s\n", filename); + + IMB_freeImBuf(ibuf); + } + this->outputBuffer = NULL; + this->imageInput = NULL; +} + + +OutputOpenExrLayer::OutputOpenExrLayer(const char *name, DataType datatype) +{ + BLI_strncpy(this->name, name, sizeof(this->name)); + this->datatype = datatype; + /* these are created in initExecution */ + this->outputBuffer = 0; + this->imageInput = 0; +} + +OutputOpenExrMultiLayerOperation::OutputOpenExrMultiLayerOperation( + const Scene *scene, const bNodeTree *tree, const char *path, char exr_codec) +{ + this->scene = scene; + this->tree = tree; + + BLI_strncpy(this->path, path, sizeof(this->path)); + this->exr_codec = exr_codec; +} + +void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType datatype) +{ + this->addInputSocket(datatype); + layers.push_back(OutputOpenExrLayer(name, datatype)); +} + +void OutputOpenExrMultiLayerOperation::initExecution() +{ + for (int i=0; i < layers.size(); ++i) { + layers[i].imageInput = getInputSocketReader(i); + layers[i].outputBuffer = init_buffer(this->getWidth(), this->getHeight(), layers[i].datatype); + } +} + +void OutputOpenExrMultiLayerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) +{ + for (int i=0; i < layers.size(); ++i) { + write_buffer_rect(rect, memoryBuffers, this->tree, layers[i].imageInput, layers[i].outputBuffer, this->getWidth(), layers[i].datatype); + } +} + +void OutputOpenExrMultiLayerOperation::deinitExecution() +{ + unsigned int width = this->getWidth(); + unsigned int height = this->getHeight(); + if (width != 0 && height != 0) { + Main *bmain= G.main; /* TODO, have this passed along */ + char filename[FILE_MAX]; + void *exrhandle= IMB_exr_get_handle(); + + BKE_makepicstring(filename, this->path, bmain->name, this->scene->r.cfra, R_IMF_IMTYPE_MULTILAYER, + (this->scene->r.scemode & R_EXTENSION), true); + BLI_make_existing_file(filename); + + for (int i=0; i < layers.size(); ++i) { + char channelname[EXR_TOT_MAXNAME]; + BLI_strncpy(channelname, layers[i].name, sizeof(channelname)-2); + char *channelname_ext = channelname + strlen(channelname); + + float *buf = layers[i].outputBuffer; + + /* create channels */ + switch (layers[i].datatype) { + case COM_DT_VALUE: + strcpy(channelname_ext, ".V"); + IMB_exr_add_channel(exrhandle, 0, channelname, 1, width, buf); + break; + case COM_DT_VECTOR: + strcpy(channelname_ext, ".X"); + IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3*width, buf); + strcpy(channelname_ext, ".Y"); + IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3*width, buf+1); + strcpy(channelname_ext, ".Z"); + IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3*width, buf+2); + break; + case COM_DT_COLOR: + strcpy(channelname_ext, ".R"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf); + strcpy(channelname_ext, ".G"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf+1); + strcpy(channelname_ext, ".B"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf+2); + strcpy(channelname_ext, ".A"); + IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4*width, buf+3); + break; + default: + break; + } + + } + + /* when the filename has no permissions, this can fail */ + if (IMB_exr_begin_write(exrhandle, filename, width, height, this->exr_codec)) { + IMB_exr_write_channels(exrhandle); + } + else { + /* TODO, get the error from openexr's exception */ + /* XXX nice way to do report? */ + printf("Error Writing Render Result, see console\n"); + } + + IMB_exr_close(exrhandle); + for (int i=0; i < layers.size(); ++i) { + if (layers[i].outputBuffer) { + MEM_freeN(layers[i].outputBuffer); + layers[i].outputBuffer = NULL; + } + + layers[i].imageInput = NULL; + } + } +} diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h new file mode 100644 index 00000000000..0fbe874e9e0 --- /dev/null +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -0,0 +1,89 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + * Lukas Tönne + */ + +#ifndef _COM_OutputFileOperation_h +#define _COM_OutputFileOperation_h +#include "COM_NodeOperation.h" +#include "BLI_rect.h" +#include "BKE_utildefines.h" + +#include "intern/openexr/openexr_multi.h" + +/* Writes the image to a single-layer file. */ +class OutputSingleLayerOperation : public NodeOperation { +private: + const Scene *scene; + const bNodeTree* tree; + + ImageFormatData *format; + char path[FILE_MAX]; + + float *outputBuffer; + DataType datatype; + SocketReader* imageInput; + +public: + OutputSingleLayerOperation(const Scene *scene, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path); + + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + bool isOutputOperation(bool rendering) const {return true;} + void initExecution(); + void deinitExecution(); + const int getRenderPriority() const {return 7;} +}; + +/* extra info for OpenEXR layers */ +struct OutputOpenExrLayer { + OutputOpenExrLayer(const char *name, DataType datatype); + + char name[EXR_TOT_MAXNAME-2]; + float *outputBuffer; + DataType datatype; + SocketReader* imageInput; +}; + +/* Writes inputs into OpenEXR multilayer channels. */ +class OutputOpenExrMultiLayerOperation : public NodeOperation { +private: + typedef std::vector<OutputOpenExrLayer> LayerList; + + const Scene *scene; + const bNodeTree* tree; + + char path[FILE_MAX]; + char exr_codec; + LayerList layers; + +public: + OutputOpenExrMultiLayerOperation(const Scene *scene, const bNodeTree *tree, const char *path, char exr_codec); + + void add_layer(const char *name, DataType datatype); + + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + bool isOutputOperation(bool rendering) const {return true;} + void initExecution(); + void deinitExecution(); + const int getRenderPriority() const {return 7;} +}; + +#endif diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp new file mode 100644 index 00000000000..5191c940f70 --- /dev/null +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -0,0 +1,127 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_PreviewOperation.h" +#include "COM_SocketConnection.h" +#include "BLI_listbase.h" +#include "DNA_scene_types.h" +#include "BKE_image.h" +#include "WM_api.h" +#include "WM_types.h" +#include "PIL_time.h" +#include "BLI_utildefines.h" +#include "BLI_math_color.h" +#include "COM_defines.h" +#include "BLI_math.h" +extern "C" { + #include "MEM_guardedalloc.h" + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + + +PreviewOperation::PreviewOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); + this->outputBuffer = NULL; + this->input = NULL; + this->divider = 1.0f; + this->node = NULL; + this->priority = 0; +} + +void PreviewOperation::initExecution() { + this->input = getInputSocketReader(0); + if (!this->node->preview) { + this->node->preview = (bNodePreview*)MEM_callocN(sizeof(bNodePreview), "node preview"); + } else { + if (this->getWidth() == (unsigned int)this->node->preview->xsize && this->getHeight() == (unsigned int)this->node->preview->ysize) { + this->outputBuffer = this->node->preview->rect; + } + } + + if (this->outputBuffer == NULL) { + this->outputBuffer = (unsigned char*)MEM_callocN(sizeof(unsigned char)*4*getWidth()*getHeight(), "PreviewOperation"); + if(this->node->preview->rect) { + MEM_freeN(this->node->preview->rect); + } + this->node->preview->xsize= getWidth(); + this->node->preview->ysize= getHeight(); + this->node->preview->rect= outputBuffer; + } +} + +void PreviewOperation::deinitExecution() { + this->outputBuffer = NULL; + this->input = NULL; +} + +void PreviewOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers) { + int offset; + float color[4]; + for (int y = rect->ymin ; y < rect->ymax ; y++) { + offset = (y * getWidth() + rect->xmin)*4; + for (int x = rect->xmin ; x < rect->xmax ; x++) { + float rx = floor(x/divider); + float ry = floor(y/divider); + + color[0] = 0.0f; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 1.0f; + input->read(color, rx, ry, COM_PS_NEAREST, memoryBuffers); + /// @todo: linear conversion only when scene color management is selected, also check predivide. + linearrgb_to_srgb_v4(color, color); + F4TOCHAR4(color, outputBuffer+offset); + offset +=4; + } + } +} +bool PreviewOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + newInput.xmin = input->xmin/divider; + newInput.xmax = input->xmax/divider; + newInput.ymin = input->ymin/divider; + newInput.ymax = input->ymax/divider; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} +void PreviewOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + NodeOperation::determineResolution(resolution, preferredResolution); + int width = resolution[0]; + int height = resolution[1]; + this->divider = 0.0f; + if (width > height) { + divider = COM_PREVIEW_SIZE / (width-1); + } else { + divider = COM_PREVIEW_SIZE / (height-1); + } + width = width * divider; + height = height * divider; + + resolution[0] = width; + resolution[1] = height; +} + +const int PreviewOperation::getRenderPriority() const { + return this->priority; +} diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h new file mode 100644 index 00000000000..c36c85ad746 --- /dev/null +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -0,0 +1,56 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_PreviewOperation_h +#define _COM_PreviewOperation_h +#include "COM_NodeOperation.h" +#include "DNA_image_types.h" +#include "BLI_rect.h" + +class PreviewOperation : public NodeOperation { +protected: + unsigned char *outputBuffer; + + /** + * @brief holds reference to the SDNA bNode, where this nodes will render the preview image for + */ + bNode* node; + const bNodeTree* tree; + SocketReader* input; + float divider; + int priority; + +public: + PreviewOperation(); + bool isOutputOperation(bool rendering) const {return true;} + void initExecution(); + void deinitExecution(); + const int getRenderPriority() const; + + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers); + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + void setbNode(bNode* node) { this->node = node;} + void setbNodeTree(const bNodeTree* tree) { this->tree = tree;} + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void setPriority(int priority) { this->priority = priority; } +}; +#endif diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp new file mode 100644 index 00000000000..adb72f9abb3 --- /dev/null +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ProjectorLensDistortionOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +ProjectorLensDistortionOperation::ProjectorLensDistortionOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + this->inputProgram = NULL; +} +void ProjectorLensDistortionOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); + kr = 0.25f*MAX2(MIN2(this->dispersion, 1.f), 0.f); + kr2 = kr * 20; +} + +void* ProjectorLensDistortionOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + void* buffer = inputProgram->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void ProjectorLensDistortionOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float inputValue[4]; + const float height = this->getHeight(); + const float width = this->getWidth(); + const float v = (y + 0.5f)/height; + const float u = (x + 0.5f)/width; + MemoryBuffer * inputBuffer = (MemoryBuffer*)data; + inputBuffer->readCubic(inputValue, (u*width + kr2) - 0.5f, v*height - 0.5f); + color[0] = inputValue[0]; + inputBuffer->read(inputValue, x, y); + color[1] = inputValue[1]; + inputBuffer->readCubic(inputValue, (u*width - kr2) - 0.5f, v*height - 0.5f); + color[2] = inputValue[2]; + color[3] = 1.0f; +} + +void ProjectorLensDistortionOperation::deinitExecution() { + this->inputProgram = NULL; +} + +bool ProjectorLensDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + newInput.ymax = input->ymax; + newInput.ymin = input->ymin; + newInput.xmin = input->xmin-kr2-2; + newInput.xmax = input->xmax+kr2+2; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h new file mode 100644 index 00000000000..6b05dbfcd41 --- /dev/null +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ProjectorLensDistortionOperation_h +#define _COM_ProjectorLensDistortionOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" + +class ProjectorLensDistortionOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; + + NodeLensDist * data; + + float dispersion; + float kr, kr2; +public: + ProjectorLensDistortionOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setData(NodeLensDist* data) {this->data = data;} + void setDispertion(float dispersion) {this->dispersion = dispersion;} + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.cpp b/source/blender/compositor/operations/COM_QualityStepHelper.cpp new file mode 100644 index 00000000000..c21163e03ac --- /dev/null +++ b/source/blender/compositor/operations/COM_QualityStepHelper.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_QualityStepHelper.h" + +QualityStepHelper::QualityStepHelper() { + this->quality = COM_QUALITY_HIGH; + this->step = 1; + this->offsetadd = 4; +} + +void QualityStepHelper::initExecution(QualityHelper helper) { + switch (helper) { + case COM_QH_INCREASE: + switch (this->quality) { + case COM_QUALITY_HIGH: + default: + this->step = 1; + this->offsetadd = 4; + break; + case COM_QUALITY_MEDIUM: + this->step = 2; + this->offsetadd = 8; + break; + case COM_QUALITY_LOW: + this->step = 3; + this->offsetadd = 12; + break; + } + break; + case COM_QH_MULTIPLY: + switch (this->quality) { + case COM_QUALITY_HIGH: + default: + this->step = 1; + this->offsetadd = 4; + break; + case COM_QUALITY_MEDIUM: + this->step = 2; + this->offsetadd = 8; + break; + case COM_QUALITY_LOW: + this->step = 4; + this->offsetadd = 16; + break; + } + break; + } +} + diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.h b/source/blender/compositor/operations/COM_QualityStepHelper.h new file mode 100644 index 00000000000..ff4870f03bd --- /dev/null +++ b/source/blender/compositor/operations/COM_QualityStepHelper.h @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_QualityStepHelper_h +#define _COM_QualityStepHelper_h +#include "COM_defines.h" + +typedef enum QualityHelper { + COM_QH_INCREASE, + COM_QH_MULTIPLY +} QualityHelper; + +class QualityStepHelper { +private: + CompositorQuality quality; + int step; + int offsetadd; + +protected: + /** + * Initialize the execution + */ + void initExecution(QualityHelper helper); + + inline int getStep() const {return this->step;} + inline int getOffsetAdd() const {return this->offsetadd;} + +public: + QualityStepHelper(); + + + void setQuality(CompositorQuality quality) {this->quality = quality;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp new file mode 100644 index 00000000000..483a75a69d2 --- /dev/null +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ReadBufferOperation.h" +#include "COM_WriteBufferOperation.h" +#include "COM_defines.h" + +ReadBufferOperation::ReadBufferOperation():NodeOperation() { + this->addOutputSocket(COM_DT_COLOR); + this->offset = 0; +} + +void* ReadBufferOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + return getInputMemoryBuffer(memoryBuffers); +} + +void ReadBufferOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + if (this->memoryProxy != NULL) { + WriteBufferOperation * operation = memoryProxy->getWriteBufferOperation(); + operation->determineResolution(resolution, preferredResolution); + operation->setResolution(resolution); + + /// @todo: may not occur!, but does with blur node + if (memoryProxy->getExecutor()) memoryProxy->getExecutor()->setResolution(resolution); + } +} +void ReadBufferOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + MemoryBuffer *inputBuffer = inputBuffers[this->offset]; + if (inputBuffer) { + if (sampler == COM_PS_NEAREST) { + inputBuffer->read(color, x, y); + } else { + inputBuffer->readCubic(color, x, y); + } + } +} + +void ReadBufferOperation::executePixel(float *color, float x, float y, float dx, float dy, MemoryBuffer *inputBuffers[]) { + MemoryBuffer *inputBuffer = inputBuffers[this->offset]; + if (inputBuffer) { + inputBuffer->readEWA(color, x, y, dx, dy); + } +} + +bool ReadBufferOperation::determineDependingAreaOfInterest(rcti * input, ReadBufferOperation* readOperation, rcti* output) { + if (this==readOperation) { + BLI_init_rcti(output, input->xmin, input->xmax, input->ymin, input->ymax); + return true; + } + return false; +} diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h new file mode 100644 index 00000000000..807f615f2e1 --- /dev/null +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ReadBufferOperation_h +#define _COM_ReadBufferOperation_h + +#include "COM_NodeOperation.h" +#include "COM_MemoryProxy.h" + +class ReadBufferOperation: public NodeOperation { +private: + MemoryProxy *memoryProxy; + unsigned int offset; +public: + ReadBufferOperation(); + int isBufferOperation() {return true;} + void setMemoryProxy(MemoryProxy* memoryProxy) {this->memoryProxy = memoryProxy;} + MemoryProxy* getMemoryProxy() {return this->memoryProxy;} + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void executePixel(float *color, float x, float y, float dx, float dy, MemoryBuffer *inputBuffers[]); + const bool isReadBufferOperation() const {return true;} + void setOffset(unsigned int offset) {this->offset = offset;} + unsigned int getOffset() {return this->offset;} + bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti* output); + MemoryBuffer* getInputMemoryBuffer(MemoryBuffer** memoryBuffers) {return memoryBuffers[offset];} + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersAOOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersAOOperation.cpp new file mode 100644 index 00000000000..a73f29c3615 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersAOOperation.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersAOOperation.h" + +RenderLayersAOOperation::RenderLayersAOOperation() :RenderLayersBaseProg(SCE_PASS_AO, 3) { + this->addOutputSocket(COM_DT_COLOR); +} + diff --git a/source/blender/compositor/operations/COM_RenderLayersAOOperation.h b/source/blender/compositor/operations/COM_RenderLayersAOOperation.h new file mode 100644 index 00000000000..71b0b885e81 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersAOOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersAOOperation_h +#define _COM_RenderLayersAOOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersAOOperation : public RenderLayersBaseProg { +public: + RenderLayersAOOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp new file mode 100644 index 00000000000..d85d54489ac --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersAlphaProg.h" + +RenderLayersAlphaProg::RenderLayersAlphaProg() :RenderLayersBaseProg(SCE_PASS_COMBINED, 4) { + this->addOutputSocket(COM_DT_VALUE); +} + +void RenderLayersAlphaProg::executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + int ix = x; + int iy = y; + float * inputBuffer = this->getInputBuffer(); + + if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { + output[0] = 0.0f; + output[1] = 0.0f; + output[2] = 0.0f; + output[3] = 0.0f; + } else { + unsigned int offset = (iy*this->getWidth()+ix) * 4; + output[0] = inputBuffer[offset+3]; + output[1] = 0.0f; + output[2] = 0.0f; + output[3] = 0.0f; + } +} diff --git a/source/blender/compositor/operations/COM_RenderLayersAlphaProg.h b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.h new file mode 100644 index 00000000000..6386915230c --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersAlphaProg.h @@ -0,0 +1,35 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersAlphaProg_h +#define _COM_RenderLayersAlphaProg_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersAlphaProg : public RenderLayersBaseProg { +public: + RenderLayersAlphaProg(); + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp new file mode 100644 index 00000000000..e63fcd5df4d --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersBaseProg.h" + +#include "BLI_listbase.h" +#include "DNA_scene_types.h" + +extern "C" { + #include "RE_pipeline.h" + #include "RE_shader_ext.h" + #include "RE_render_ext.h" +} + +RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize): NodeOperation() { + this->renderpass = renderpass; + this->setScene(NULL); + this->inputBuffer = NULL; + this->elementsize = elementsize; +} + + +void RenderLayersBaseProg::initExecution() { + Scene * scene = this->getScene(); + Render *re= (scene)? RE_GetRender(scene->id.name): NULL; + RenderResult *rr= NULL; + + if(re) + rr= RE_AcquireResultRead(re); + + if(rr) { + SceneRenderLayer *srl= (SceneRenderLayer*)BLI_findlink(&scene->r.layers, getLayerId()); + if(srl) { + + RenderLayer *rl= RE_GetRenderLayer(rr, srl->name); + if(rl && rl->rectf) { + this->inputBuffer = RE_RenderLayerGetPass(rl, renderpass); + + if (this->inputBuffer == NULL || renderpass == SCE_PASS_COMBINED) { + this->inputBuffer = rl->rectf; + } + } + } + } + if (re) { + RE_ReleaseResult(re); + re = NULL; + } +} + +void RenderLayersBaseProg::executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + int ix = x; + int iy = y; + + if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { + output[0] = 0.0f; + output[1] = 0.0f; + output[2] = 0.0f; + output[3] = 0.0f; + } else { + unsigned int offset = (iy*this->getWidth()+ix) * elementsize; + if (elementsize == 1) { + output[0] = inputBuffer[offset]; + output[1] = 0.0f; + output[2] = 0.0f; + output[3] = 0.0f; + } else if (elementsize == 3){ + output[0] = inputBuffer[offset]; + output[1] = inputBuffer[offset+1]; + output[2] = inputBuffer[offset+2]; + output[3] = 1.0f; + } else { + output[0] = inputBuffer[offset]; + output[1] = inputBuffer[offset+1]; + output[2] = inputBuffer[offset+2]; + output[3] = inputBuffer[offset+3]; + } + } +} + +void RenderLayersBaseProg::deinitExecution() { + this->inputBuffer = NULL; +} + +void RenderLayersBaseProg::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + Scene *sce= this->getScene(); + Render *re= (sce)? RE_GetRender(sce->id.name): NULL; + RenderResult *rr= NULL; + + resolution[0] = 0; + resolution[1] = 0; + + if(re) + rr= RE_AcquireResultRead(re); + + if(rr) { + SceneRenderLayer *srl= (SceneRenderLayer*)BLI_findlink(&sce->r.layers, getLayerId()); + if(srl) { + RenderLayer *rl= RE_GetRenderLayer(rr, srl->name); + if(rl && rl->rectf) { + resolution[0]=rl->rectx; + resolution[1]=rl->recty; + } + } + } + + if(re) + RE_ReleaseResult(re); + +} + diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h new file mode 100644 index 00000000000..a1802d1db65 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h @@ -0,0 +1,99 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + + +#ifndef _COM_RenderLayersBaseProg_h +#define _COM_RenderLayersBaseProg_h + +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "BLI_listbase.h" +#include "BKE_image.h" +extern "C" { + #include "RE_pipeline.h" + #include "RE_shader_ext.h" + #include "RE_render_ext.h" + #include "MEM_guardedalloc.h" +} + +/** + * Base class for all renderlayeroperations + * + * @todo: rename to operation. + */ +class RenderLayersBaseProg : public NodeOperation { +private: + /** + * Reference to the scene object. + */ + Scene* scene; + + /** + * layerId of the layer where this operation needs to get its data from + */ + short layerId; + + /** + * cached instance to the float buffer inside the layer + */ + float* inputBuffer; + + /** + * renderpass where this operation needs to get its data from + */ + int renderpass; + + int elementsize; + +protected: + /** + * Constructor + */ + RenderLayersBaseProg(int renderpass, int elementsize); + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + /** + * retrieve the reference to the float buffer of the renderer. + */ + inline float* getInputBuffer() {return this->inputBuffer;} + +public: + /** + * setter for the scene field. Will be called from + * @see RenderLayerNode to set the actual scene where + * the data will be retrieved from. + */ + void setScene(Scene* scene) {this->scene = scene;} + Scene* getScene() {return this->scene;} + void setLayerId(short layerId) {this->layerId = layerId;} + short getLayerId() {return this->layerId;} + void initExecution(); + void deinitExecution(); + void executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersColorOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersColorOperation.cpp new file mode 100644 index 00000000000..71461ac0e3f --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersColorOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersColorOperation.h" + +RenderLayersColorOperation::RenderLayersColorOperation() :RenderLayersBaseProg(SCE_PASS_RGBA, 4) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersColorOperation.h b/source/blender/compositor/operations/COM_RenderLayersColorOperation.h new file mode 100644 index 00000000000..4f4dfbfb6f3 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersColorOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersColorOperation_h +#define _COM_RenderLayersColorOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersColorOperation : public RenderLayersBaseProg { +public: + RenderLayersColorOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.cpp new file mode 100644 index 00000000000..17e2c6683d9 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersCyclesOperation.h" + +RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) :RenderLayersBaseProg(pass, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.h b/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.h new file mode 100644 index 00000000000..baa53c7388b --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersCyclesOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersCyclesOperation_h +#define _COM_RenderLayersCyclesOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersCyclesOperation : public RenderLayersBaseProg { +public: + RenderLayersCyclesOperation(int pass); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersDepthProg.cpp b/source/blender/compositor/operations/COM_RenderLayersDepthProg.cpp new file mode 100644 index 00000000000..badb9189206 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersDepthProg.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersDepthProg.h" + +RenderLayersDepthProg::RenderLayersDepthProg() :RenderLayersBaseProg(SCE_PASS_Z, 1) { + this->addOutputSocket(COM_DT_VALUE); +} + diff --git a/source/blender/compositor/operations/COM_RenderLayersDepthProg.h b/source/blender/compositor/operations/COM_RenderLayersDepthProg.h new file mode 100644 index 00000000000..fdbe25c818e --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersDepthProg.h @@ -0,0 +1,34 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersDepthProg_h +#define _COM_RenderLayersDepthProg_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersDepthProg : public RenderLayersBaseProg { +public: + RenderLayersDepthProg(); + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.cpp new file mode 100644 index 00000000000..6c3359ed063 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersDiffuseOperation.h" + +RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() :RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.h b/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.h new file mode 100644 index 00000000000..8c20d6f497d --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersDiffuseOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersDiffuseOperation_h +#define _COM_RenderLayersDiffuseOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersDiffuseOperation : public RenderLayersBaseProg { +public: + RenderLayersDiffuseOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersEmitOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersEmitOperation.cpp new file mode 100644 index 00000000000..936b1f0c59a --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersEmitOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersEmitOperation.h" + +RenderLayersEmitOperation::RenderLayersEmitOperation() :RenderLayersBaseProg(SCE_PASS_EMIT, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersEmitOperation.h b/source/blender/compositor/operations/COM_RenderLayersEmitOperation.h new file mode 100644 index 00000000000..c003cb2f87b --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersEmitOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersEmitOperation_h +#define _COM_RenderLayersEmitOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersEmitOperation : public RenderLayersBaseProg { +public: + RenderLayersEmitOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.cpp new file mode 100644 index 00000000000..642f07d7e16 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersEnvironmentOperation.h" + +RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() :RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.h b/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.h new file mode 100644 index 00000000000..b9310a1778b --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersEnvironmentOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersEnvironmentOperation_h +#define _COM_RenderLayersEnvironmentOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersEnvironmentOperation : public RenderLayersBaseProg { +public: + RenderLayersEnvironmentOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersImageProg.cpp b/source/blender/compositor/operations/COM_RenderLayersImageProg.cpp new file mode 100644 index 00000000000..a58f16b10a1 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersImageProg.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersImageProg.h" + +RenderLayersColourProg::RenderLayersColourProg() :RenderLayersBaseProg(SCE_PASS_COMBINED, 4) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersImageProg.h b/source/blender/compositor/operations/COM_RenderLayersImageProg.h new file mode 100644 index 00000000000..b6ddac425cb --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersImageProg.h @@ -0,0 +1,34 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersColourProg_h +#define _COM_RenderLayersColourProg_h + +#include "COM_RenderLayersBaseProg.h" + +/// @TODO rename to image operation +class RenderLayersColourProg : public RenderLayersBaseProg { +public: + RenderLayersColourProg(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.cpp new file mode 100644 index 00000000000..db61c237c61 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersIndirectOperation.h" + +RenderLayersIndirectOperation::RenderLayersIndirectOperation() :RenderLayersBaseProg(SCE_PASS_INDIRECT, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.h b/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.h new file mode 100644 index 00000000000..d64207a4355 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersIndirectOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersIndirectOperation_h +#define _COM_RenderLayersIndirectOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersIndirectOperation : public RenderLayersBaseProg { +public: + RenderLayersIndirectOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.cpp new file mode 100644 index 00000000000..96bab2569dd --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersMaterialIndexOperation.h" + +RenderLayersMaterialIndexOperation::RenderLayersMaterialIndexOperation() :RenderLayersBaseProg(SCE_PASS_INDEXMA, 1) { + this->addOutputSocket(COM_DT_VALUE); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.h b/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.h new file mode 100644 index 00000000000..d06568f5a10 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersMaterialIndexOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersMaterialIndexOperation_h +#define _COM_RenderLayersMaterialIndexOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersMaterialIndexOperation : public RenderLayersBaseProg { +public: + RenderLayersMaterialIndexOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersMistOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersMistOperation.cpp new file mode 100644 index 00000000000..d3be993b3f9 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersMistOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersMistOperation.h" + +RenderLayersMistOperation::RenderLayersMistOperation() :RenderLayersBaseProg(SCE_PASS_MIST, 1) { + this->addOutputSocket(COM_DT_VALUE); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersMistOperation.h b/source/blender/compositor/operations/COM_RenderLayersMistOperation.h new file mode 100644 index 00000000000..8c0ee9bfcab --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersMistOperation.h @@ -0,0 +1,11 @@ +#ifndef _COM_RenderLayersMistOperation_h +#define _COM_RenderLayersMistOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersMistOperation : public RenderLayersBaseProg { +public: + RenderLayersMistOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersNormalOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersNormalOperation.cpp new file mode 100644 index 00000000000..dba40e3cc7a --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersNormalOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersNormalOperation.h" + +RenderLayersNormalOperation::RenderLayersNormalOperation() :RenderLayersBaseProg(SCE_PASS_NORMAL, 3) { + this->addOutputSocket(COM_DT_VECTOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersNormalOperation.h b/source/blender/compositor/operations/COM_RenderLayersNormalOperation.h new file mode 100644 index 00000000000..39b2040863a --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersNormalOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersNormalOperation_h +#define _COM_RenderLayersNormalOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersNormalOperation : public RenderLayersBaseProg { +public: + RenderLayersNormalOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.cpp new file mode 100644 index 00000000000..d4d14de6d98 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersObjectIndexOperation.h" + +RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() :RenderLayersBaseProg(SCE_PASS_INDEXOB, 1) { + this->addOutputSocket(COM_DT_VALUE); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.h b/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.h new file mode 100644 index 00000000000..e8a1602cbfc --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersObjectIndexOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersObjectIndexOperation_h +#define _COM_RenderLayersObjectIndexOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersObjectIndexOperation : public RenderLayersBaseProg { +public: + RenderLayersObjectIndexOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.cpp new file mode 100644 index 00000000000..0417a6fade2 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersReflectionOperation.h" + +RenderLayersReflectionOperation::RenderLayersReflectionOperation() :RenderLayersBaseProg(SCE_PASS_REFLECT, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.h b/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.h new file mode 100644 index 00000000000..3dc7148930b --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersReflectionOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersReflectionOperation_h +#define _COM_RenderLayersReflectionOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersReflectionOperation : public RenderLayersBaseProg { +public: + RenderLayersReflectionOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.cpp new file mode 100644 index 00000000000..74042f46f78 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersRefractionOperation.h" + +RenderLayersRefractionOperation::RenderLayersRefractionOperation() :RenderLayersBaseProg(SCE_PASS_REFRACT, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.h b/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.h new file mode 100644 index 00000000000..02ac7aa14f4 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersRefractionOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersRefractionOperation_h +#define _COM_RenderLayersRefractionOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersRefractionOperation : public RenderLayersBaseProg { +public: + RenderLayersRefractionOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersShadowOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersShadowOperation.cpp new file mode 100644 index 00000000000..87155607d82 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersShadowOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersShadowOperation.h" + +RenderLayersShadowOperation::RenderLayersShadowOperation() :RenderLayersBaseProg(SCE_PASS_SHADOW, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersShadowOperation.h b/source/blender/compositor/operations/COM_RenderLayersShadowOperation.h new file mode 100644 index 00000000000..af35915c2ee --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersShadowOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersShadowOperation_h +#define _COM_RenderLayersShadowOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersShadowOperation : public RenderLayersBaseProg { +public: + RenderLayersShadowOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.cpp new file mode 100644 index 00000000000..ed6a0853436 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersSpecularOperation.h" + +RenderLayersSpecularOperation::RenderLayersSpecularOperation() :RenderLayersBaseProg(SCE_PASS_SPEC, 3) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.h b/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.h new file mode 100644 index 00000000000..fc7d77976a3 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersSpecularOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersSpecularOperation_h +#define _COM_RenderLayersSpecularOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersSpecularOperation : public RenderLayersBaseProg { +public: + RenderLayersSpecularOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.cpp new file mode 100644 index 00000000000..0a76d04959e --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersSpeedOperation.h" + +RenderLayersSpeedOperation::RenderLayersSpeedOperation() :RenderLayersBaseProg(SCE_PASS_VECTOR, 4) { + this->addOutputSocket(COM_DT_COLOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.h b/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.h new file mode 100644 index 00000000000..d341aa43950 --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersSpeedOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersSpeedOperation_h +#define _COM_RenderLayersSpeedOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersSpeedOperation : public RenderLayersBaseProg { +public: + RenderLayersSpeedOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RenderLayersUVOperation.cpp b/source/blender/compositor/operations/COM_RenderLayersUVOperation.cpp new file mode 100644 index 00000000000..b15bbb0f3dd --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersUVOperation.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RenderLayersUVOperation.h" + +RenderLayersUVOperation::RenderLayersUVOperation() :RenderLayersBaseProg(SCE_PASS_UV, 3) { + this->addOutputSocket(COM_DT_VECTOR); +} diff --git a/source/blender/compositor/operations/COM_RenderLayersUVOperation.h b/source/blender/compositor/operations/COM_RenderLayersUVOperation.h new file mode 100644 index 00000000000..3068372a66c --- /dev/null +++ b/source/blender/compositor/operations/COM_RenderLayersUVOperation.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RenderLayersUVOperation_h +#define _COM_RenderLayersUVOperation_h + +#include "COM_RenderLayersBaseProg.h" + +class RenderLayersUVOperation : public RenderLayersBaseProg { +public: + RenderLayersUVOperation(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_RotateOperation.cpp b/source/blender/compositor/operations/COM_RotateOperation.cpp new file mode 100644 index 00000000000..ef6c5bee90a --- /dev/null +++ b/source/blender/compositor/operations/COM_RotateOperation.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_RotateOperation.h" +#include "BLI_math.h" + +RotateOperation::RotateOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->imageSocket = NULL; + this->degreeSocket = NULL; + this->doDegree2RadConversion = false; +} +void RotateOperation::initExecution() { + this->imageSocket = this->getInputSocketReader(0); + this->degreeSocket = this->getInputSocketReader(1); + this->centerX = this->getWidth()/2.0; + this->centerY = this->getHeight()/2.0; + float degree[4]; + this->degreeSocket->read(degree, 0, 0, COM_PS_NEAREST, NULL); + double rad; + if (this->doDegree2RadConversion) { + rad = DEG2RAD(degree[0]); + } else { + rad = degree[0]; + } + this->cosine = cos(rad); + this->sine = sin(rad); +} + +void RotateOperation::deinitExecution() { + this->imageSocket = NULL; + this->degreeSocket = NULL; +} + + +void RotateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + const float dy = y - this->centerY; + const float dx = x - this->centerX; + const float nx = this->centerX+(this->cosine*dx + this->sine*dy); + const float ny = this->centerY+(-this->sine*dx + this->cosine*dy); + this->imageSocket->read(color, nx, ny, sampler, inputBuffers); +} + +bool RotateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + const float dxmin = input->xmin - this->centerX; + const float dymin = input->ymin - this->centerY; + const float dxmax = input->xmax - this->centerX; + const float dymax = input->ymax - this->centerY; + + const float x1 = this->centerX+(this->cosine*dxmin + this->sine*dymin); + const float x2 = this->centerX+(this->cosine*dxmax + this->sine*dymin); + const float x3 = this->centerX+(this->cosine*dxmin + this->sine*dymax); + const float x4 = this->centerX+(this->cosine*dxmax + this->sine*dymax); + const float y1 = this->centerY+(-this->sine*dxmin + this->cosine*dymin); + const float y2 = this->centerY+(-this->sine*dxmax + this->cosine*dymin); + const float y3 = this->centerY+(-this->sine*dxmin + this->cosine*dymax); + const float y4 = this->centerY+(-this->sine*dxmax + this->cosine*dymax); + const float minx = min(x1, min(x2, min(x3, x4))); + const float maxx = max(x1, max(x2, max(x3, x4))); + const float miny = min(y1, min(y2, min(y3, y4))); + const float maxy = max(y1, max(y2, max(y3, y4))); + + newInput.xmax = ceil(maxx)+1; + newInput.xmin = floor(minx)-1; + newInput.ymax = ceil(maxy)+1; + newInput.ymin = floor(miny)-1; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h new file mode 100644 index 00000000000..9965d1021da --- /dev/null +++ b/source/blender/compositor/operations/COM_RotateOperation.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_RotateOperation_h_ +#define _COM_RotateOperation_h_ + +#include "COM_NodeOperation.h" + +class RotateOperation: public NodeOperation { +private: + SocketReader *imageSocket; + SocketReader *degreeSocket; + float centerX; + float centerY; + float cosine; + float sine; + bool doDegree2RadConversion; +public: + RotateOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void initExecution(); + void deinitExecution(); + void setDoDegree2RadConversion(bool abool) {this->doDegree2RadConversion = abool;} +}; + +#endif diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp new file mode 100644 index 00000000000..ef3d8250bab --- /dev/null +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -0,0 +1,196 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ScaleOperation.h" + +ScaleOperation::ScaleOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputOperation = NULL; + this->inputXOperation = NULL; + this->inputYOperation = NULL; +} +void ScaleOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); + this->inputXOperation = this->getInputSocketReader(1); + this->inputYOperation = this->getInputSocketReader(2); + this->centerX = this->getWidth()/2.0; + this->centerY = this->getHeight()/2.0; +} + +void ScaleOperation::deinitExecution() { + this->inputOperation = NULL; + this->inputXOperation = NULL; + this->inputYOperation = NULL; +} + + +void ScaleOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float scaleX[4]; + float scaleY[4]; + + this->inputXOperation->read(scaleX, x, y, sampler, inputBuffers); + this->inputYOperation->read(scaleY, x, y, sampler, inputBuffers); + + const float scx = scaleX[0]; + const float scy = scaleY[0]; + + float nx = this->centerX+ (x - this->centerX) / scx; + float ny = this->centerY+ (y - this->centerY) / scy; + this->inputOperation->read(color, nx, ny, sampler, inputBuffers); +} + +bool ScaleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + float scaleX[4]; + float scaleY[4]; + + this->inputXOperation->read(scaleX, 0, 0, COM_PS_NEAREST, NULL); + this->inputYOperation->read(scaleY, 0, 0, COM_PS_NEAREST, NULL); + + const float scx = scaleX[0]; + const float scy = scaleY[0]; + + newInput.xmax = this->centerX+ (input->xmax - this->centerX) / scx; + newInput.xmin = this->centerX+ (input->xmin - this->centerX) / scx; + newInput.ymax = this->centerY+ (input->ymax - this->centerY) / scy; + newInput.ymin = this->centerY+ (input->ymin - this->centerY) / scy; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} + + +// SCALE ABSOLUTE +ScaleAbsoluteOperation::ScaleAbsoluteOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputOperation = NULL; + this->inputXOperation= NULL; + this->inputYOperation = NULL; +} +void ScaleAbsoluteOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); + this->inputXOperation = this->getInputSocketReader(1); + this->inputYOperation = this->getInputSocketReader(2); + this->centerX = this->getWidth()/2.0; + this->centerY = this->getHeight()/2.0; +} + +void ScaleAbsoluteOperation::deinitExecution() { + this->inputOperation = NULL; + this->inputXOperation = NULL; + this->inputYOperation = NULL; +} + + +void ScaleAbsoluteOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float scaleX[4]; + float scaleY[4]; + + this->inputXOperation->read(scaleX, x, y, sampler, inputBuffers); + this->inputYOperation->read(scaleY, x, y, sampler, inputBuffers); + + const float scx = scaleX[0]; // target absolute scale + const float scy = scaleY[0]; // target absolute scale + const float width = this->getWidth(); + const float height = this->getHeight(); + //div + float relativeXScale = scx/width; + float relativeYScale = scy/height; + + float nx = this->centerX+ (x - this->centerX) / relativeXScale; + float ny = this->centerY+ (y - this->centerY) / relativeYScale; + this->inputOperation->read(color, nx, ny, sampler, inputBuffers); +} + +bool ScaleAbsoluteOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + float scaleX[4]; + float scaleY[4]; + + this->inputXOperation->read(scaleX, 0, 0, COM_PS_NEAREST, NULL); + this->inputYOperation->read(scaleY, 0, 0, COM_PS_NEAREST, NULL); + + const float scx = scaleX[0]; + const float scy = scaleY[0]; + const float width = this->getWidth(); + const float height = this->getHeight(); + //div + float relateveXScale = scx/width; + float relateveYScale = scy/height; + + newInput.xmax = this->centerX+ (input->xmax - this->centerX) / relateveXScale; + newInput.xmin = this->centerX+ (input->xmin - this->centerX) / relateveXScale; + newInput.ymax = this->centerY+ (input->ymax - this->centerY) / relateveYScale; + newInput.ymin = this->centerY+ (input->ymin - this->centerY) / relateveYScale; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} + + +// Absolute fixed siez +ScaleFixedSizeOperation::ScaleFixedSizeOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputOperation = NULL; +} +void ScaleFixedSizeOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); + this->relX = inputOperation->getWidth() / (float)this->newWidth; + this->relY = inputOperation->getHeight() / (float)this->newHeight; +} + +void ScaleFixedSizeOperation::deinitExecution() { + this->inputOperation = NULL; +} + + +void ScaleFixedSizeOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + this->inputOperation->read(color, x*relX, y*relY, sampler, inputBuffers); +} + +bool ScaleFixedSizeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + newInput.xmax = input->xmax *relX; + newInput.xmin = input->xmin *relX; + newInput.ymax = input->ymax *relY; + newInput.ymin = input->ymin *relY; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} + +void ScaleFixedSizeOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + unsigned int nr[2]; + nr[0] = newWidth; + nr[1] = newHeight; + NodeOperation::determineResolution(resolution, nr); + resolution[0] = newWidth; + resolution[1] = newHeight; +} diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h new file mode 100644 index 00000000000..3e075249fa1 --- /dev/null +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -0,0 +1,77 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ScaleOperation_h_ +#define _COM_ScaleOperation_h_ + +#include "COM_NodeOperation.h" + +class ScaleOperation: public NodeOperation { +private: + SocketReader *inputOperation; + SocketReader *inputXOperation; + SocketReader *inputYOperation; + float centerX; + float centerY; +public: + ScaleOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); +}; + +class ScaleAbsoluteOperation: public NodeOperation { + SocketReader *inputOperation; + SocketReader *inputXOperation; + SocketReader *inputYOperation; + float centerX; + float centerY; +public: + ScaleAbsoluteOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); +}; + +class ScaleFixedSizeOperation: public NodeOperation { + SocketReader *inputOperation; + int newWidth; + int newHeight; + float relX; + float relY; +public: + ScaleFixedSizeOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + void setNewWidth(int width) {this->newWidth = width;} + void setNewHeight(int height) {this->newHeight = height;} +}; + +#endif diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp new file mode 100644 index 00000000000..4a4ac6c6833 --- /dev/null +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -0,0 +1,164 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ScreenLensDistortionOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" +extern "C" { + #include "BLI_rand.h" +} + +ScreenLensDistortionOperation::ScreenLensDistortionOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + this->inputProgram = NULL; +} +void ScreenLensDistortionOperation::initExecution() { + this->inputProgram = this->getInputSocketReader(0); + kg = MAX2(MIN2(this->distortion, 1.f), -0.999f); + // smaller dispersion range for somewhat more control + const float d = 0.25f*MAX2(MIN2(this->dispersion, 1.f), 0.f); + kr = MAX2(MIN2((kg+d), 1.f), -0.999f); + kb = MAX2(MIN2((kg-d), 1.f), -0.999f); + maxk = MAX3(kr, kg, kb); + sc = (this->data->fit && (maxk > 0.f)) ? (1.f/(1.f + 2.f*maxk)) : (1.f/(1.f + maxk)); + drg = 4.f*(kg - kr); + dgb = 4.f*(kb - kg); + + kr4 = kr*4; + kg4 = kg*4.f; + kb4 *= kb*4.f; + cx = 0.5f*(float)getWidth(); + cy = 0.5f*(float)getHeight(); + +} + +void* ScreenLensDistortionOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + void* buffer = inputProgram->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void ScreenLensDistortionOperation::executePixel(float* outputColor, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + const float height = this->getHeight(); + const float width = this->getWidth(); + MemoryBuffer* buffer = (MemoryBuffer*)data; + + int dr = 0, dg = 0, db = 0; + float d, t, ln[6] = {0, 0, 0, 0, 0, 0}; + float tc[4] = {0, 0, 0, 0}; + const float v = sc*((y + 0.5f) - cy)/cy; + const float u = sc*((x + 0.5f) - cx)/cx; + int sta = 0, mid = 0, end = 0; + + if ((t = 1.f - kr4*(u*u + v*v)) >= 0.f) { + d = 1.f/(1.f + sqrtf(t)); + ln[0] = (u*d + 0.5f)*width - 0.5f, ln[1] = (v*d + 0.5f)*height - 0.5f; + sta = 1; + } + if ((t = 1.f - kg4*(u*u + v*v)) >= 0.f) { + d = 1.f/(1.f + sqrtf(t)); + ln[2] = (u*d + 0.5f)*width - 0.5f, ln[3] = (v*d + 0.5f)*height - 0.5f; + mid = 1; + } + if ((t = 1.f - kb4*(u*u + v*v)) >= 0.f) { + d = 1.f/(1.f + sqrtf(t)); + ln[4] = (u*d + 0.5f)*width - 0.5f, ln[5] = (v*d + 0.5f)*height - 0.5f; + end = 1; + } + + if (sta && mid && end) { + float jit = this->data->jit; + float z; + float color[4]; + { + // RG + const int dx = ln[2] - ln[0], dy = ln[3] - ln[1]; + const float dsf = sqrtf(dx*dx + dy*dy) + 1.f; + const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); + const float sd = 1.f/(float)ds; + + for (z=0; z<ds; ++z) { + const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd; + t = 1.f - (kr4 + tz*drg)*(u*u + v*v); + d = 1.f / (1.f + sqrtf(t)); + const float nx = (u*d + 0.5f)*getWidth() - 0.5f; + const float ny = (v*d + 0.5f)*getHeight() - 0.5f; + buffer->readCubic(color, nx, ny); + tc[0] += (1.f-tz)*color[0], tc[1] += tz*color[1]; + dr++, dg++; + } + } + { + // GB + const int dx = ln[4] - ln[2], dy = ln[5] - ln[3]; + const float dsf = sqrtf(dx*dx + dy*dy) + 1.f; + const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); + const float sd = 1.f/(float)ds; + + for (z=0; z<ds; ++z) { + const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd; + t = 1.f - (kg4 + tz*dgb)*(u*u + v*v); + d = 1.f / (1.f + sqrtf(t)); + const float nx = (u*d + 0.5f)*getWidth() - 0.5f; + const float ny = (v*d + 0.5f)*getHeight() - 0.5f; + buffer->readCubic(color, nx, ny); + tc[1] += (1.f-tz)*color[1], tc[2] += tz*color[2]; + dg++, db++; + } + + } + if (dr) outputColor[0] = 2.f*tc[0] / (float)dr; + if (dg) outputColor[1] = 2.f*tc[1] / (float)dg; + if (db) outputColor[2] = 2.f*tc[2] / (float)db; + + /* set alpha */ + outputColor[3]= 1.0f; + } else { + outputColor[0]= 0.0f; + outputColor[1]= 0.0f; + outputColor[2]= 0.0f; + outputColor[3]= 0.0f; + } +} + +void ScreenLensDistortionOperation::deinitExecution() { + this->inputProgram = NULL; +} + +void ScreenLensDistortionOperation::determineUV(float result[2], float x, float y) const { + const float v = sc*((y + 0.5f) - cy)/cy; + const float u = sc*((x + 0.5f) - cx)/cx; + const float t = ABS(MIN3(kr, kg, kb)*4); + float d = 1.f/(1.f + sqrtf(t)); + result[0] = (u*d + 0.5f)*getWidth() - 0.5f; + result[1] = (v*d + 0.5f)*getHeight() - 0.5f; +} + +bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + newInput.xmin = 0; + newInput.ymin = 0; + newInput.ymax = inputProgram->getHeight(); + newInput.xmax = inputProgram->getWidth(); + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h new file mode 100644 index 00000000000..65262cfd3dd --- /dev/null +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h @@ -0,0 +1,74 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ScreenLensDistortionOperation_h +#define _COM_ScreenLensDistortionOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" + +class ScreenLensDistortionOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader* inputProgram; + + NodeLensDist * data; + + float dispersion; + float distortion; + float kr, kg, kb; + float kr4, kg4, kb4; + float maxk; + float drg; + float dgb; + float sc, cx, cy; +public: + ScreenLensDistortionOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setData(NodeLensDist* data) {this->data = data;} + void setDispertion(float dispersion) {this->dispersion = dispersion;} + void setDistortion(float distortion) {this->distortion = distortion;} + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + +private: + void determineUV(float* result, float x, float y) const; + +}; +#endif diff --git a/source/blender/compositor/operations/COM_SeparateChannelOperation.cpp b/source/blender/compositor/operations/COM_SeparateChannelOperation.cpp new file mode 100644 index 00000000000..4e0ad1580cd --- /dev/null +++ b/source/blender/compositor/operations/COM_SeparateChannelOperation.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SeparateChannelOperation.h" + +SeparateChannelOperation::SeparateChannelOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VALUE); + this->inputOperation = NULL; +} +void SeparateChannelOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void SeparateChannelOperation::deinitExecution() { + this->inputOperation = NULL; +} + + +void SeparateChannelOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float input[4]; + this->inputOperation->read(input, x, y, sampler, inputBuffers); + color[0] = input[this->channel]; +} diff --git a/source/blender/compositor/operations/COM_SeparateChannelOperation.h b/source/blender/compositor/operations/COM_SeparateChannelOperation.h new file mode 100644 index 00000000000..3c1eed4bdd9 --- /dev/null +++ b/source/blender/compositor/operations/COM_SeparateChannelOperation.h @@ -0,0 +1,42 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SeparateChannelOperation_h_ +#define _COM_SeparateChannelOperation_h_ + +#include "COM_NodeOperation.h" + +class SeparateChannelOperation: public NodeOperation { +private: + SocketReader *inputOperation; + int channel; +public: + SeparateChannelOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + void setChannel(int channel) {this->channel = channel;} +}; + +#endif diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.cpp b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp new file mode 100644 index 00000000000..b6545912a80 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SetAlphaOperation.h" + +SetAlphaOperation::SetAlphaOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + + this->inputColor = NULL; + this->inputAlpha = NULL; +} + +void SetAlphaOperation::initExecution() { + this->inputColor = getInputSocketReader(0); + this->inputAlpha = getInputSocketReader(1); +} + +void SetAlphaOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float alphaInput[4]; + + this->inputColor->read(outputValue, x, y, sampler, inputBuffers); + this->inputAlpha->read(alphaInput, x, y, sampler, inputBuffers); + + outputValue[3] = alphaInput[0]; +} + +void SetAlphaOperation::deinitExecution() { + this->inputColor = NULL; + this->inputAlpha = NULL; +} diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.h b/source/blender/compositor/operations/COM_SetAlphaOperation.h new file mode 100644 index 00000000000..2cb42bf8cf3 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SetAlphaOperation_h +#define _COM_SetAlphaOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class SetAlphaOperation : public NodeOperation { +private: + SocketReader *inputColor; + SocketReader *inputAlpha; + +public: + /** + * Default constructor + */ + SetAlphaOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_SetColorOperation.cpp b/source/blender/compositor/operations/COM_SetColorOperation.cpp new file mode 100644 index 00000000000..729a8073d7a --- /dev/null +++ b/source/blender/compositor/operations/COM_SetColorOperation.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SetColorOperation.h" + +SetColorOperation::SetColorOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_COLOR); +} + +void SetColorOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + outputValue[0] = this->channel1; + outputValue[1] = this->channel2; + outputValue[2] = this->channel3; + outputValue[3] = this->channel4; +} + +void SetColorOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + resolution[0] = preferredResolution[0]; + resolution[1] = preferredResolution[1]; +} diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h new file mode 100644 index 00000000000..13d4bc21392 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetColorOperation.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SetColorOperation_h +#define _COM_SetColorOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class SetColorOperation : public NodeOperation { +private: + float channel1; + float channel2; + float channel3; + float channel4; + +public: + /** + * Default constructor + */ + SetColorOperation(); + + const float getChannel1() {return this->channel1;} + void setChannel1(float value) {this->channel1 = value;} + const float getChannel2() {return this->channel2;} + void setChannel2(float value) {this->channel2 = value;} + const float getChannel3() {return this->channel3;} + void setChannel3(float value) {this->channel3 = value;} + const float getChannel4() {return this->channel4;} + void setChannel4(float value) {this->channel4 = value;} + void setChannels(float value[4]) {this->channel1 = value[0];this->channel2 = value[1];this->channel3 = value[2];this->channel4 = value[3];} + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + const bool isSetOperation() const {return true;} + +}; +#endif diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp new file mode 100644 index 00000000000..d5fda4a8827 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SetSamplerOperation.h" + +SetSamplerOperation::SetSamplerOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); +} + +void SetSamplerOperation::initExecution() { + this->reader = this->getInputSocketReader(0); +} +void SetSamplerOperation::deinitExecution() { + this->reader = NULL; +} + +void SetSamplerOperation::executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + reader->read(output, x, y, this->sampler, inputBuffers); +} diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.h b/source/blender/compositor/operations/COM_SetSamplerOperation.h new file mode 100644 index 00000000000..f7b850fcfe9 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SetSamplerOperation_h +#define _COM_SetSamplerOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output Sampler. + * it assumes we are in sRGB colour space. + */ +class SetSamplerOperation : public NodeOperation { +private: + PixelSampler sampler; + SocketReader *reader; +public: + /** + * Default constructor + */ + SetSamplerOperation(); + + void setSampler(PixelSampler sampler) {this->sampler = sampler;} + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void initExecution(); + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_SetValueOperation.cpp b/source/blender/compositor/operations/COM_SetValueOperation.cpp new file mode 100644 index 00000000000..a8a681a6659 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetValueOperation.cpp @@ -0,0 +1,36 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SetValueOperation.h" + +SetValueOperation::SetValueOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_VALUE); +} + +void SetValueOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + outputValue[0] = this->value; +} + +void SetValueOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + resolution[0] = preferredResolution[0]; + resolution[1] = preferredResolution[1]; +} diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h new file mode 100644 index 00000000000..30a8de16dc4 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetValueOperation.h @@ -0,0 +1,54 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SetValueOperation_h +#define _COM_SetValueOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class SetValueOperation : public NodeOperation { +private: + float value; + +public: + /** + * Default constructor + */ + SetValueOperation(); + + const float getValue() {return this->value;} + void setValue(float value) {this->value = value;} + + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + const bool isSetOperation() const {return true;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cpp b/source/blender/compositor/operations/COM_SetVectorOperation.cpp new file mode 100644 index 00000000000..b9c8f4bc369 --- /dev/null +++ b/source/blender/compositor/operations/COM_SetVectorOperation.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SetVectorOperation.h" +#include "COM_defines.h" + +SetVectorOperation::SetVectorOperation(): NodeOperation() { + this->addOutputSocket(COM_DT_VECTOR); +} + +void SetVectorOperation::executePixel(float* outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + outputValue[0] = this->x; + outputValue[1] = this->y; + outputValue[2] = this->z; + outputValue[3] = this->w; +} + +void SetVectorOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + if (preferredResolution[0] == 0 ||preferredResolution[1]==0) { + resolution[0] = COM_DEFAULT_RESOLUTION_WIDTH; + resolution[1] = COM_DEFAULT_RESOLUTION_HEIGHT; + } else { + resolution[0] = preferredResolution[0]; + resolution[1] = preferredResolution[1]; + } +} diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h new file mode 100644 index 00000000000..c1f3c679b5b --- /dev/null +++ b/source/blender/compositor/operations/COM_SetVectorOperation.h @@ -0,0 +1,68 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SetVectorOperation_h +#define _COM_SetVectorOperation_h +#include "COM_NodeOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class SetVectorOperation : public NodeOperation { +private: + float x; + float y; + float z; + float w; + +public: + /** + * Default constructor + */ + SetVectorOperation(); + + const float getX() {return this->x;} + void setX(float value) {this->x = value;} + const float getY() {return this->y;} + void setY(float value) {this->y = value;} + const float getZ() {return this->z;} + void setZ(float value) {this->z = value;} + const float getW() {return this->w;} + void setW(float value) {this->w = value;} + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + const bool isSetOperation() const {return true;} + + void setVector(float vector[3]) { + setX(vector[0]); + setY(vector[1]); + setZ(vector[2]); + } +}; +#endif diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp new file mode 100644 index 00000000000..161bdb3e295 --- /dev/null +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SocketProxyOperation.h" + +SocketProxyOperation::SocketProxyOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR/*|COM_DT_VECTOR|COM_DT_VALUE*/); + this->addOutputSocket(COM_DT_COLOR); + this->inputOperation = NULL; +} + +void SocketProxyOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); +} + +void SocketProxyOperation::deinitExecution() { + this->inputOperation = NULL; +} + +void SocketProxyOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + this->inputOperation->read(color, x, y, sampler, inputBuffers); +} diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h new file mode 100644 index 00000000000..a86134c1ea9 --- /dev/null +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h @@ -0,0 +1,39 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SocketProxyOperation_h_ +#define _COM_SocketProxyOperation_h_ + +#include "COM_NodeOperation.h" + +class SocketProxyOperation: public NodeOperation { +private: + SocketReader *inputOperation; +public: + SocketProxyOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp b/source/blender/compositor/operations/COM_SplitViewerOperation.cpp new file mode 100644 index 00000000000..f9000cc63da --- /dev/null +++ b/source/blender/compositor/operations/COM_SplitViewerOperation.cpp @@ -0,0 +1,102 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_SplitViewerOperation.h" +#include "COM_SocketConnection.h" +#include "BLI_listbase.h" +#include "DNA_scene_types.h" +#include "BKE_image.h" +#include "BLI_utildefines.h" +#include "BLI_math_color.h" +#include "BLI_math_vector.h" + +extern "C" { + #include "MEM_guardedalloc.h" + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + + +SplitViewerOperation::SplitViewerOperation() : ViewerBaseOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->image1Input = NULL; + this->image2Input = NULL; +} + +void SplitViewerOperation::initExecution() { + // When initializing the tree during initial load the width and height can be zero. + this->image1Input = getInputSocketReader(0); + this->image2Input = getInputSocketReader(1); + ViewerBaseOperation::initExecution(); +} + +void SplitViewerOperation::deinitExecution() { + this->image1Input = NULL; + this->image2Input = NULL; + ViewerBaseOperation::deinitExecution(); +} + + +void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) { + float* buffer = this->outputBuffer; + unsigned char* bufferDisplay = this->outputBufferDisplay; + + if (!buffer) return; + int x1 = rect->xmin; + int y1 = rect->ymin; + int x2 = rect->xmax; + int y2 = rect->ymax; + int offset = (y1*this->getWidth() + x1 ) * 4; + int x; + int y; + int perc = xSplit?this->splitPercentage*getWidth()/100.0f:this->splitPercentage*getHeight()/100.0f; + for (y = y1 ; y < y2 ; y++) { + for (x = x1 ; x < x2 ; x++) { + bool image1; + float srgb[4]; + image1 = xSplit?x>perc:y>perc; + if (image1) { + image1Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST, memoryBuffers); + } else { + image2Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST, memoryBuffers); + } + /// @todo: linear conversion only when scene color management is selected, also check predivide. + if (this->doColorManagement) { + if(this->doColorPredivide) { + linearrgb_to_srgb_predivide_v4(srgb, buffer+offset); + } else { + linearrgb_to_srgb_v4(srgb, buffer+offset); + } + } else { + copy_v4_v4(srgb, buffer+offset); + } + + F4TOCHAR4(srgb, bufferDisplay+offset); + + offset +=4; + } + offset += (this->getWidth()-(x2-x1))*4; + } + updateImage(rect); +} + diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.h b/source/blender/compositor/operations/COM_SplitViewerOperation.h new file mode 100644 index 00000000000..61e4b027cec --- /dev/null +++ b/source/blender/compositor/operations/COM_SplitViewerOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_SplitViewerOperation_h +#define _COM_SplitViewerOperation_h +#include "COM_ViewerBaseOperation.h" +#include "DNA_image_types.h" +#include "BLI_rect.h" + +class SplitViewerOperation : public ViewerBaseOperation { +private: + SocketReader* image1Input; + SocketReader* image2Input; + + float splitPercentage; + bool xSplit; +public: + SplitViewerOperation(); + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + void initExecution(); + void deinitExecution(); + void setSplitPercentage(float splitPercentage) {this->splitPercentage = splitPercentage;} + void setXSplit(bool xsplit) {this->xSplit = xsplit;} +}; +#endif diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp new file mode 100644 index 00000000000..1ca986f8893 --- /dev/null +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_TextureOperation.h" + +#include "BLI_listbase.h" +#include "DNA_scene_types.h" + +TextureBaseOperation::TextureBaseOperation(): NodeOperation() { + this->addInputSocket(COM_DT_VECTOR);//offset + this->addInputSocket(COM_DT_VECTOR);//size + this->texture = NULL; + this->inputSize = NULL; + this->inputOffset = NULL; +} +TextureOperation::TextureOperation() : TextureBaseOperation() { + this->addOutputSocket(COM_DT_COLOR); +} +TextureAlphaOperation::TextureAlphaOperation() : TextureBaseOperation() { + this->addOutputSocket(COM_DT_VALUE); +} + +void TextureBaseOperation::initExecution() { + this->inputOffset = getInputSocketReader(0); + this->inputSize = getInputSocketReader(1); +} +void TextureBaseOperation::deinitExecution() { + this->inputSize = NULL; + this->inputOffset = NULL; +} + +void TextureBaseOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { + if (preferredResolution[0] == 0 || preferredResolution[1] == 0) { + resolution[0] = COM_DEFAULT_RESOLUTION_WIDTH; + resolution[1] = COM_DEFAULT_RESOLUTION_HEIGHT; + } else { + resolution[0] = preferredResolution[0]; + resolution[1] = preferredResolution[1]; + } +} + +void TextureAlphaOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + TextureBaseOperation::executePixel(color, x, y, sampler, inputBuffers); + color[0] = color[3]; + color[1] = 0.0f; + color[2] = 0.0f; + color[3] = 0.0f; +} + +void TextureBaseOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; + float textureSize[4]; + float textureOffset[4]; + float vec[3]; + int retval; + const float cx = this->getWidth()/2; + const float cy = this->getHeight()/2; + const float u = (cx-x)/this->getWidth()*2; + const float v = (cy-y)/this->getHeight()*2; + + this->inputSize->read(textureSize, x, y, sampler, inputBuffers); + this->inputOffset->read(textureOffset, x, y, sampler, inputBuffers); + + vec[0]= textureSize[0]*(u + textureOffset[0]); + vec[1]= textureSize[1]*(v + textureOffset[1]); + vec[2]= textureSize[2]*textureOffset[2]; + + retval= multitex_ext(this->texture, vec, NULL, NULL, 0, &texres); + + if(texres.talpha) + color[3]= texres.ta; + else + color[3]= texres.tin; + + if((retval & TEX_RGB)) { + color[0]= texres.tr; + color[1]= texres.tg; + color[2]= texres.tb; + } + else color[0]= color[1]= color[2]= color[3]; +} diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h new file mode 100644 index 00000000000..a545a5eea97 --- /dev/null +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -0,0 +1,81 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + + +#ifndef _COM_TextureOperation_h +#define _COM_TextureOperation_h + +#include "COM_NodeOperation.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" +#include "BLI_listbase.h" +extern "C" { + #include "RE_pipeline.h" + #include "RE_shader_ext.h" + #include "RE_render_ext.h" + #include "MEM_guardedalloc.h" +} + +/** + * Base class for all renderlayeroperations + * + * @todo: rename to operation. + */ +class TextureBaseOperation : public NodeOperation { +private: + Tex* texture; + SocketReader *inputSize; + SocketReader *inputOffset; + +protected: + + /** + * Determine the output resolution. The resolution is retrieved from the Renderer + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + /** + * Constructor + */ + TextureBaseOperation(); + +public: + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void setTexture(Tex* texture) {this->texture = texture;} + void initExecution(); + void deinitExecution(); +}; + +class TextureOperation:public TextureBaseOperation { +public: + TextureOperation(); + +}; +class TextureAlphaOperation:public TextureBaseOperation { +public: + TextureAlphaOperation(); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + +}; + +#endif diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp new file mode 100644 index 00000000000..84e893d0b2e --- /dev/null +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -0,0 +1,163 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_TonemapOperation.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + + + +TonemapOperation::TonemapOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); + this->addOutputSocket(COM_DT_COLOR); + this->imageReader = NULL; + this->data = NULL; + this->cachedInstance = NULL; + this->setComplex(true); +} +void TonemapOperation::initExecution() { + this->imageReader = this->getInputSocketReader(0); + NodeOperation::initMutex(); +} + +void TonemapOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data) { + AvgLogLum * avg = (AvgLogLum*)data; + + float output[4]; + this->imageReader->read(output, x, y, inputBuffers, NULL); + output[0] *= avg->al; + output[1] *= avg->al; + output[2] *= avg->al; + float dr = output[0] + this->data->offset; + float dg = output[1] + this->data->offset; + float db = output[2] + this->data->offset; + output[0] /= ((dr == 0.f) ? 1.f : dr); + output[1] /= ((dg == 0.f) ? 1.f : dg); + output[2] /= ((db == 0.f) ? 1.f : db); + const float igm = avg->igm; + if (igm != 0.f) { + output[0] = pow((double)MAX2(output[0], 0.), (double)igm); + output[1] = pow((double)MAX2(output[1], 0.), (double)igm); + output[2] = pow((double)MAX2(output[2], 0.), (double)igm); + } + + color[0] = output[0]; + color[1] = output[1]; + color[2] = output[2]; + color[3] = output[3]; +} +void PhotoreceptorTonemapOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data) { + AvgLogLum * avg = (AvgLogLum*)data; + NodeTonemap *ntm = this->data; + + const float f = exp((double)-this->data->f); + const float m = (ntm->m > 0.f) ? ntm->m : (0.3f + 0.7f*pow((double)avg->auto_key, 1.4)); + const float ic = 1.f - ntm->c, ia = 1.f - ntm->a; + + float output[4]; + this->imageReader->read(output, x, y, inputBuffers, NULL); + + const float L = 0.212671f*output[0] + 0.71516f*output[1] + 0.072169f*output[2]; + float I_l = output[0] + ic*(L - output[0]); + float I_g = avg->cav[0] + ic*(avg->lav - avg->cav[0]); + float I_a = I_l + ia*(I_g - I_l); + output[0] /= (output[0] + pow((double)f*I_a, (double)m)); + I_l = output[1] + ic*(L - output[1]); + I_g = avg->cav[1] + ic*(avg->lav - avg->cav[1]); + I_a = I_l + ia*(I_g - I_l); + output[1] /= (output[1] + pow((double)f*I_a,(double)m)); + I_l = output[2] + ic*(L - output[2]); + I_g = avg->cav[2] + ic*(avg->lav - avg->cav[2]); + I_a = I_l + ia*(I_g - I_l); + output[2] /= (output[2] + pow((double)f*I_a, (double)m)); + + color[0] = output[0]; + color[1] = output[1]; + color[2] = output[2]; + color[3] = output[3]; +} + +void TonemapOperation::deinitExecution() { + this->imageReader = NULL; + if (this->cachedInstance) { + delete cachedInstance; + } + NodeOperation::deinitMutex(); +} + +bool TonemapOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti imageInput; + + NodeOperation* operation = getInputOperation(0); + imageInput.xmax = operation->getWidth(); + imageInput.xmin = 0; + imageInput.ymax = operation->getHeight(); + imageInput.ymin = 0; + if (operation->determineDependingAreaOfInterest(&imageInput, readOperation, output) ) { + return true; + } + return false; +} + +void* TonemapOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + BLI_mutex_lock(getMutex()); + if (this->cachedInstance == NULL) { + MemoryBuffer* tile = (MemoryBuffer*)imageReader->initializeTileData(rect, memoryBuffers); + AvgLogLum *data = new AvgLogLum(); + + float * buffer = tile->getBuffer(); + + float lsum = 0; + int p = tile->getWidth() * tile->getHeight(); + float* bc = buffer; + float avl, maxl = -1e10f, minl = 1e10f; + const float sc = 1.f/(p); + float Lav = 0.f; + float cav[4] = {0.0f,0.0f,0.0f,0.0f}; + while (p--) { + float L = 0.212671f*bc[0] + 0.71516f*bc[1] + 0.072169f*bc[2]; + Lav += L; + cav[0] += bc[0]; + cav[1] += bc[1]; + cav[2] += bc[2]; + lsum += (float)log((double)MAX2(L, 0.0) + 1e-5); + maxl = (L > maxl) ? L : maxl; + minl = (L < minl) ? L : minl; + bc+=4; + } + data->lav = Lav * sc; + data->cav[0] = cav[0]*sc; + data->cav[1] = cav[1]*sc; + data->cav[2] = cav[2]*sc; + maxl = log((double)maxl + 1e-5); minl = log((double)minl + 1e-5f); avl = lsum*sc; + data->auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.f; + float al = exp((double)avl); + data->al = (al == 0.f) ? 0.f : (this->data->key / al); + data->igm = (this->data->gamma==0.f) ? 1 : (1.f / this->data->gamma); + this->cachedInstance = data; + } + BLI_mutex_unlock(getMutex()); + return this->cachedInstance; +} + +void TonemapOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) { +} diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h new file mode 100644 index 00000000000..c895fdcba77 --- /dev/null +++ b/source/blender/compositor/operations/COM_TonemapOperation.h @@ -0,0 +1,103 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_TonemapOperation_h +#define _COM_TonemapOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" + +/** + * @brief temporarily storage during execution of Tonemap + * @ingroup operation + */ +typedef struct AvgLogLum { + float al; + float auto_key; + float lav; + float cav[4]; + float igm; +} AvgLogLum; + +/** + * @brief base class of tonemap, implementing the simple tonemap + * @ingroup operation + */ +class TonemapOperation : public NodeOperation { +protected: + /** + * @brief Cached reference to the reader + */ + SocketReader * imageReader; + + /** + * @brief settings of the Tonemap + */ + NodeTonemap * data; + + /** + * @brief temporarily cache of the execution storage + */ + AvgLogLum * cachedInstance; + +public: + TonemapOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data); + + /** + * Initialize the execution + */ + void initExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setData(NodeTonemap* data) {this->data = data;} + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + +}; + +/** + * @brief class of tonemap, implementing the photoreceptor tonemap + * most parts have already been done in TonemapOperation + * @ingroup operation + */ + +class PhotoreceptorTonemapOperation : public TonemapOperation { +public: + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void * data); +}; + +#endif diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp new file mode 100644 index 00000000000..48774833e14 --- /dev/null +++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_TranslateOperation.h" + +TranslateOperation::TranslateOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + this->inputOperation = NULL; + this->inputXOperation = NULL; + this->inputYOperation = NULL; +} +void TranslateOperation::initExecution() { + this->inputOperation = this->getInputSocketReader(0); + this->inputXOperation = this->getInputSocketReader(1); + this->inputYOperation = this->getInputSocketReader(2); + + float tempDelta[4]; + this->inputXOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL); + this->deltaX = tempDelta[0]; + this->inputYOperation->read(tempDelta, 0, 0, COM_PS_NEAREST, NULL); + this->deltaY = tempDelta[0]; +} + +void TranslateOperation::deinitExecution() { + this->inputOperation = NULL; + this->inputXOperation = NULL; + this->inputYOperation = NULL; +} + + +void TranslateOperation::executePixel(float *color,float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + this->inputOperation->read(color, x-this->getDeltaX(), y-this->getDeltaY(), sampler, inputBuffers); +} + +bool TranslateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + + newInput.xmax = input->xmax - this->getDeltaX(); + newInput.xmin = input->xmin - this->getDeltaX(); + newInput.ymax = input->ymax - this->getDeltaY(); + newInput.ymin = input->ymin - this->getDeltaY(); + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h new file mode 100644 index 00000000000..eab3391041e --- /dev/null +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_TranslateOperation_h_ +#define _COM_TranslateOperation_h_ + +#include "COM_NodeOperation.h" + +class TranslateOperation: public NodeOperation { +private: + SocketReader *inputOperation; + SocketReader*inputXOperation; + SocketReader*inputYOperation; + float deltaX; + float deltaY; +public: + TranslateOperation(); + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + void initExecution(); + void deinitExecution(); + + float getDeltaX() {return this->deltaX;} + float getDeltaY() {return this->deltaY;} +}; + +#endif diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp new file mode 100644 index 00000000000..e97b1155e22 --- /dev/null +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_VariableSizeBokehBlurOperation.h" +#include "BLI_math.h" + +extern "C" { + #include "RE_pipeline.h" +} + +VariableSizeBokehBlurOperation::VariableSizeBokehBlurOperation() : NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); // do not resize the bokeh image. + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + + this->inputProgram = NULL; + this->inputBokehProgram = NULL; + this->inputSizeProgram = NULL; + this->maxBlur = 32.0f; + this->threshold = 0.0f; +} + + +void VariableSizeBokehBlurOperation::initExecution() { + this->inputProgram = getInputSocketReader(0); + this->inputBokehProgram = getInputSocketReader(1); + this->inputSizeProgram = getInputSocketReader(2); + QualityStepHelper::initExecution(COM_QH_INCREASE); +} + +void VariableSizeBokehBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float tempColor[4]; + float readColor[4]; + float bokeh[4]; + tempColor[0] = 0; + tempColor[1] = 0; + tempColor[2] = 0; + tempColor[3] = 0; + float tempSize[4]; + float overallmultiplyerr = 0; + float overallmultiplyerg = 0; + float overallmultiplyerb = 0; + + int miny = y - maxBlur; + int maxy = y + maxBlur; + int minx = x - maxBlur; + int maxx = x + maxBlur; + { + inputProgram->read(readColor, x, y, COM_PS_NEAREST, inputBuffers); + tempColor[0] += readColor[0]; + tempColor[1] += readColor[1]; + tempColor[2] += readColor[2]; + overallmultiplyerr += 1; + overallmultiplyerg += 1; + overallmultiplyerb += 1; + + for (int ny = miny ; ny < maxy ; ny += QualityStepHelper::getStep()) { + for (int nx = minx ; nx < maxx ; nx += QualityStepHelper::getStep()) { + if (nx >=0 && nx < this->getWidth() && ny >= 0 && ny < getHeight()) { + inputSizeProgram->read(tempSize, nx, ny, COM_PS_NEAREST, inputBuffers); + float size = tempSize[0]; + size += this->threshold; + float dx = nx - x; + float dy = ny - y; + if (nx == x && ny == y) { + } else if (size>= fabs(dx) && size >= fabs(dy)) { + float u = 256+ dx*256/size; + float v = 256+ dy*256/size; + inputBokehProgram->read(bokeh, u, v, COM_PS_NEAREST, inputBuffers); + inputProgram->read(readColor, nx, ny, COM_PS_NEAREST, inputBuffers); + tempColor[0] += bokeh[0] * readColor[0]; + tempColor[1] += bokeh[1] * readColor[1]; + tempColor[2] += bokeh[2]* readColor[2]; + overallmultiplyerr += bokeh[0]; + overallmultiplyerg += bokeh[1]; + overallmultiplyerb += bokeh[2]; + } + } + } + } + color[0] = tempColor[0]*(1.0/overallmultiplyerr); + color[1] = tempColor[1]*(1.0/overallmultiplyerg); + color[2] = tempColor[2]*(1.0/overallmultiplyerb); + color[3] = 1.0f; + } + +} + +void VariableSizeBokehBlurOperation::deinitExecution() { + this->inputProgram = NULL; + this->inputBokehProgram = NULL; + this->inputSizeProgram = NULL; +} + +bool VariableSizeBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + rcti newInput; + rcti bokehInput; + + newInput.xmax = input->xmax + maxBlur+2; + newInput.xmin = input->xmin - maxBlur+2; + newInput.ymax = input->ymax + maxBlur-2; + newInput.ymin = input->ymin - maxBlur-2; + bokehInput.xmax = 512; + bokehInput.xmin = 0; + bokehInput.ymax = 512; + bokehInput.ymin = 0; + + NodeOperation* operation = getInputOperation(2); + if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) { + return true; + } + operation = getInputOperation(1); + if (operation->determineDependingAreaOfInterest(&bokehInput, readOperation, output) ) { + return true; + } + operation = getInputOperation(0); + if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) { + return true; + } + return false; +} diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h new file mode 100644 index 00000000000..6c3159a8092 --- /dev/null +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h @@ -0,0 +1,62 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_BokehVariableSizeBokehBlurOperation_h +#define _COM_VariableSizeBokehBlurOperation_h +#include "COM_NodeOperation.h" +#include "COM_QualityStepHelper.h" + +class VariableSizeBokehBlurOperation : public NodeOperation, public QualityStepHelper { +private: + int maxBlur; + float threshold; + SocketReader* inputProgram; + SocketReader* inputBokehProgram; + SocketReader* inputSizeProgram; + +public: + VariableSizeBokehBlurOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setMaxBlur(int maxRadius) {this->maxBlur = maxRadius;} + + void setThreshold(float threshold) {this->threshold = threshold;} + + +}; +#endif diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp new file mode 100644 index 00000000000..7d660177fbb --- /dev/null +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_VectorBlurOperation.h" +#include "BLI_math.h" + +// use the implementation of blender internal renderer to calculate the vector blur. +extern "C" { + #include "RE_pipeline.h" +} + +VectorBlurOperation::VectorBlurOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); // ZBUF + this->addInputSocket(COM_DT_COLOR); //SPEED + this->addOutputSocket(COM_DT_COLOR); + this->settings = NULL; + this->cachedInstance = NULL; + this->inputImageProgram = NULL; + this->inputSpeedProgram = NULL; + this->inputZProgram = NULL; + setComplex(true); +} +void VectorBlurOperation::initExecution() { + initMutex(); + this->inputImageProgram = getInputSocketReader(0); + this->inputZProgram = getInputSocketReader(1); + this->inputSpeedProgram = getInputSocketReader(2); + this->cachedInstance = NULL; + QualityStepHelper::initExecution(COM_QH_INCREASE); + +} + +void VectorBlurOperation::executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data) { + float* buffer = (float*) data; + int index = (y*this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; + color[0] = buffer[index]; + color[1] = buffer[index+1]; + color[2] = buffer[index+2]; + color[3] = buffer[index+3]; +} + +void VectorBlurOperation::deinitExecution() { + deinitMutex(); + this->inputImageProgram = NULL; + this->inputSpeedProgram = NULL; + this->inputZProgram = NULL; + if (this->cachedInstance) { + delete cachedInstance; + this->cachedInstance = NULL; + } +} +void* VectorBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { + if (this->cachedInstance) return this->cachedInstance; + + BLI_mutex_lock(getMutex()); + if (this->cachedInstance == NULL) { + MemoryBuffer* tile = (MemoryBuffer*)inputImageProgram->initializeTileData(rect, memoryBuffers); + MemoryBuffer* speed= (MemoryBuffer*)inputSpeedProgram->initializeTileData(rect, memoryBuffers); + MemoryBuffer* z = (MemoryBuffer*)inputZProgram->initializeTileData(rect, memoryBuffers); + float* data = new float[this->getWidth()*this->getHeight()*COM_NUMBER_OF_CHANNELS]; + memcpy(data, tile->getBuffer(),this->getWidth()*this->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + this->generateVectorBlur(data, tile, speed, z); + this->cachedInstance = data; + } + BLI_mutex_unlock(getMutex()); + return this->cachedInstance; +} + +bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) { + if (this->cachedInstance == NULL) { + rcti newInput; + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } else { + return false; + } +} + +void VectorBlurOperation::generateVectorBlur(float* data, MemoryBuffer* inputImage, MemoryBuffer* inputSpeed, MemoryBuffer* inputZ) { + float *zbuf = inputZ->convertToValueBuffer(); + NodeBlurData blurdata; + blurdata.samples = this->settings->samples/QualityStepHelper::getStep(); + blurdata.maxspeed = this->settings->maxspeed; + blurdata.minspeed = this->settings->minspeed; + blurdata.curved = this->settings->curved; + blurdata.fac = this->settings->fac; + RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf); + delete zbuf; + return; +} diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.h b/source/blender/compositor/operations/COM_VectorBlurOperation.h new file mode 100644 index 00000000000..e3275f1bc15 --- /dev/null +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.h @@ -0,0 +1,73 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_VectorBlurOperation_h +#define _COM_VectorBlurOperation_h +#include "COM_NodeOperation.h" +#include "DNA_node_types.h" +#include "COM_QualityStepHelper.h" + +class VectorBlurOperation : public NodeOperation, public QualityStepHelper { +private: + /** + * @brief Cached reference to the inputProgram + */ + SocketReader * inputImageProgram; + SocketReader * inputSpeedProgram; + SocketReader * inputZProgram; + + /** + * @brief settings of the glare node. + */ + NodeBlurData * settings; + + float* cachedInstance; + +public: + VectorBlurOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, int x, int y, MemoryBuffer *inputBuffers[], void* data); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + + void setVectorBlurSettings(NodeBlurData * settings) {this->settings = settings;} + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +protected: + + void generateVectorBlur(float* data, MemoryBuffer* inputImage, MemoryBuffer* inputSpeed, MemoryBuffer* inputZ); + + +}; +#endif diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp new file mode 100644 index 00000000000..697d082c33e --- /dev/null +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_VectorCurveOperation.h" + +#ifdef __cplusplus +extern "C" { +#endif + #include "BKE_colortools.h" +#ifdef __cplusplus +} +#endif + +VectorCurveOperation::VectorCurveOperation(): CurveBaseOperation() { + this->addInputSocket(COM_DT_VECTOR); + this->addOutputSocket(COM_DT_VECTOR); + + this->inputProgram = NULL; +} +void VectorCurveOperation::initExecution() { + CurveBaseOperation::initExecution(); + this->inputProgram = this->getInputSocketReader(0); +} + +void VectorCurveOperation::executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float input[4]; + + + this->inputProgram->read(input, x, y, sampler, inputBuffers); + + curvemapping_evaluate_premulRGBF(this->curveMapping, output, input); + output[3]= input[3]; +} + +void VectorCurveOperation::deinitExecution() { + this->inputProgram = NULL; +} diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.h b/source/blender/compositor/operations/COM_VectorCurveOperation.h new file mode 100644 index 00000000000..d3097345ae5 --- /dev/null +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.h @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_VectorCurveOperation_h +#define _COM_VectorCurveOperation_h +#include "COM_NodeOperation.h" +#include "COM_CurveBaseOperation.h" + +class VectorCurveOperation : public CurveBaseOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; +public: + VectorCurveOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float* Vector, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp new file mode 100644 index 00000000000..16143af7165 --- /dev/null +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ViewerBaseOperation.h" +#include "COM_SocketConnection.h" +#include "BLI_listbase.h" +#include "DNA_scene_types.h" +#include "BKE_image.h" +#include "WM_api.h" +#include "WM_types.h" +#include "PIL_time.h" +#include "BLI_utildefines.h" +#include "BLI_math_color.h" + +extern "C" { + #include "MEM_guardedalloc.h" + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + + +ViewerBaseOperation::ViewerBaseOperation() : NodeOperation() { + this->setImage(NULL); + this->setImageUser(NULL); + this->outputBuffer = NULL; + this->outputBufferDisplay = NULL; + this->active = false; + this->doColorManagement = true; +} + +void ViewerBaseOperation::initExecution() { + // When initializing the tree during initial load the width and height can be zero. + initImage(); +} + +void ViewerBaseOperation::initImage() { + Image* anImage = this->image; + ImBuf *ibuf= BKE_image_acquire_ibuf(anImage, this->imageUser, &this->lock); + + if (!ibuf) return; + if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) { + imb_freerectImBuf(ibuf); + imb_freerectfloatImBuf(ibuf); + IMB_freezbuffloatImBuf(ibuf); + ibuf->x= getWidth(); + ibuf->y= getHeight(); + imb_addrectImBuf(ibuf); + imb_addrectfloatImBuf(ibuf); + anImage->ok= IMA_OK_LOADED; + } + + /* now we combine the input with ibuf */ + this->outputBuffer = ibuf->rect_float; + this->outputBufferDisplay = (unsigned char*)ibuf->rect; + + BKE_image_release_ibuf(this->image, this->lock); +} +void ViewerBaseOperation:: updateImage(rcti *rect) { + /// @todo: introduce new event to update smaller area + WM_main_add_notifier(NC_WINDOW|ND_DRAW, NULL); +} + +void ViewerBaseOperation::deinitExecution() { + this->outputBuffer = NULL; +} + +const int ViewerBaseOperation::getRenderPriority() const { + if (this->isActiveViewerOutput()) { + return 8; + } else { + return 0; + } +} diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h new file mode 100644 index 00000000000..e94d2644e36 --- /dev/null +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h @@ -0,0 +1,71 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ViewerBaseOperation_h +#define _COM_ViewerBaseOperation_h +#include "COM_NodeOperation.h" +#include "DNA_image_types.h" +#include "BLI_rect.h" + +class ViewerBaseOperation : public NodeOperation { +protected: + float *outputBuffer; + unsigned char *outputBufferDisplay; + Image * image; + ImageUser * imageUser; + void *lock; + bool active; + const bNodeTree* tree; + float centerX; + float centerY; + OrderOfChunks chunkOrder; + bool doColorManagement; + bool doColorPredivide; + +public: + bool isOutputOperation(bool rendering) const {return true;} + void initExecution(); + void deinitExecution(); + void setImage(Image* image) {this->image = image;} + void setImageUser(ImageUser* imageUser) {this->imageUser = imageUser;} + const bool isActiveViewerOutput() const {return active;} + void setActive(bool active) {this->active = active;} + void setbNodeTree(const bNodeTree* tree) {this->tree = tree;} + void setCenterX(float centerX) {this->centerX = centerX;} + void setCenterY(float centerY) {this->centerY = centerY;} + void setChunkOrder(OrderOfChunks tileOrder) {this->chunkOrder = tileOrder;} + float getCenterX() { return this->centerX; } + float getCenterY() { return this->centerY; } + OrderOfChunks getChunkOrder() { return this->chunkOrder; } + const int getRenderPriority() const; + void setColorManagement(bool doColorManagement) {this->doColorManagement = doColorManagement;} + void setColorPredivide(bool doColorPredivide) {this->doColorPredivide = doColorPredivide;} + bool isViewerOperation() {return true;} + +protected: + ViewerBaseOperation(); + void updateImage(rcti*rect); + +private: + void initImage(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp new file mode 100644 index 00000000000..b0d443f1cbd --- /dev/null +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -0,0 +1,108 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ViewerOperation.h" +#include "COM_SocketConnection.h" +#include "BLI_listbase.h" +#include "DNA_scene_types.h" +#include "BKE_image.h" +#include "WM_api.h" +#include "WM_types.h" +#include "PIL_time.h" +#include "BLI_utildefines.h" +#include "BLI_math_color.h" +#include "BLI_math_vector.h" + +extern "C" { + #include "MEM_guardedalloc.h" + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" +} + + +ViewerOperation::ViewerOperation() : ViewerBaseOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + + this->imageInput = NULL; + this->alphaInput = NULL; +} + +void ViewerOperation::initExecution() { + // When initializing the tree during initial load the width and height can be zero. + this->imageInput = getInputSocketReader(0); + this->alphaInput = getInputSocketReader(1); + ViewerBaseOperation::initExecution(); +} + +void ViewerOperation::deinitExecution() { + this->imageInput = NULL; + this->alphaInput = NULL; + ViewerBaseOperation::deinitExecution(); +} + + +void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) { + float* buffer = this->outputBuffer; + unsigned char* bufferDisplay = this->outputBufferDisplay; + if (!buffer) return; + const int x1 = rect->xmin; + const int y1 = rect->ymin; + const int x2 = rect->xmax; + const int y2 = rect->ymax; + const int offsetadd = (this->getWidth()-(x2-x1))*4; + int offset = (y1*this->getWidth() + x1 ) * 4; + float alpha[4], srgb[4]; + int x; + int y; + bool breaked = false; + + for (y = y1 ; y < y2 && (!breaked) ; y++) { + for (x = x1 ; x < x2; x++) { + imageInput->read(&(buffer[offset]), x, y, COM_PS_NEAREST, memoryBuffers); + if (alphaInput != NULL) { + alphaInput->read(alpha, x, y, COM_PS_NEAREST, memoryBuffers); + buffer[offset+3] = alpha[0]; + } + /// @todo: linear conversion only when scene color management is selected, also check predivide. + if (this->doColorManagement) { + if(this->doColorPredivide) { + linearrgb_to_srgb_predivide_v4(srgb, buffer+offset); + } else { + linearrgb_to_srgb_v4(srgb, buffer+offset); + } + } else { + copy_v4_v4(srgb, buffer+offset); + } + + F4TOCHAR4(srgb, bufferDisplay+offset); + + offset +=4; + } + if (tree->test_break && tree->test_break(tree->tbh)) { + breaked = true; + } + + offset += offsetadd; + } + updateImage(rect); +} diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h new file mode 100644 index 00000000000..951e9ff6fc3 --- /dev/null +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -0,0 +1,41 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ViewerOperation_h +#define _COM_ViewerOperation_h +#include "COM_NodeOperation.h" +#include "DNA_image_types.h" +#include "BLI_rect.h" +#include "COM_ViewerBaseOperation.h" + +class ViewerOperation : public ViewerBaseOperation { +private: + SocketReader* imageInput; + SocketReader* alphaInput; + +public: + ViewerOperation(); + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + void initExecution(); + void deinitExecution(); +}; +#endif diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp new file mode 100644 index 00000000000..44a769ee947 --- /dev/null +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -0,0 +1,161 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_WriteBufferOperation.h" +#include "COM_defines.h" +#include "COM_MemoryManager.h" +#include <stdio.h> + +/// @TODO: writebuffers don't have an actual data type set. +WriteBufferOperation::WriteBufferOperation() :NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->memoryProxy = new MemoryProxy(); + this->memoryProxy->setWriteBufferOperation(this); + this->memoryProxy->setExecutor(NULL); + this->tree = NULL; +} +WriteBufferOperation::~WriteBufferOperation() { + if (this->memoryProxy) { + delete this->memoryProxy; + this->memoryProxy = NULL; + } +} + +void WriteBufferOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + input->read(color, x, y, sampler, inputBuffers); +} +void WriteBufferOperation::initExecution() { + this->input = this->getInputOperation(0); + MemoryManager::addMemoryProxy(this->memoryProxy); +} +void WriteBufferOperation::deinitExecution() { + this->input = NULL; +} + + +void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) { + MemoryBuffer* memoryBuffer = MemoryManager::getMemoryBuffer(this->getMemoryProxy(), tileNumber); + float* buffer = memoryBuffer->getBuffer(); + if (this->input->isComplex()) { + void* data = this->input->initializeTileData(rect, memoryBuffers); + int x1 = rect->xmin; + int y1 = rect->ymin; + int x2 = rect->xmax; + int y2 = rect->ymax; + int offset4 = 0; + int x; + int y; + bool breaked = false; + for (y = y1 ; y < y2 && (!breaked) ; y++) { + for (x = x1 ; x < x2; x++) { + input->read(&(buffer[offset4]), x, y, memoryBuffers, data); + offset4 +=4; + + } + if (tree->test_break && tree->test_break(tree->tbh)) { + breaked = true; + } + + } + if (data) { + this->input->deinitializeTileData(rect, memoryBuffers, data); + data = NULL; + } + } else { + int x1 = rect->xmin; + int y1 = rect->ymin; + int x2 = rect->xmax; + int y2 = rect->ymax; + int offset4 = 0; + int x; + int y; + bool breaked = false; + for (y = y1 ; y < y2 && (!breaked) ; y++) { + for (x = x1 ; x < x2 ; x++) { + input->read(&(buffer[offset4]), x, y, COM_PS_NEAREST, memoryBuffers); + offset4 +=4; + } + if (tree->test_break && tree->test_break(tree->tbh)) { + breaked = true; + } + } + } + memoryBuffer->setCreatedState(); +} + +void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** inputMemoryBuffers) { + MemoryBuffer* outputMemoryBuffer = MemoryManager::getMemoryBuffer(this->getMemoryProxy(), chunkNumber); + float* outputFloatBuffer = outputMemoryBuffer->getBuffer(); + cl_int error; + /* + 1. create cl_mem from outputbuffer + 2. call NodeOperation (input) executeOpenCLChunk(.....) + 3. schedule readback from opencl to main device (outputbuffer) + 4. schedule native callback + + note: list of cl_mem will be filled by 2, and needs to be cleaned up by 4 + */ + // STEP 1 + const unsigned int outputBufferWidth = outputMemoryBuffer->getWidth(); + const unsigned int outputBufferHeight = outputMemoryBuffer->getHeight(); + + const cl_image_format imageFormat = { + CL_RGBA, + CL_FLOAT + }; + + cl_mem clOutputBuffer = clCreateImage2D(context, CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR, &imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + + // STEP 2 + list<cl_mem> * clMemToCleanUp = new list<cl_mem>(); + clMemToCleanUp->push_back(clOutputBuffer); + list<cl_kernel> *clKernelsToCleanUp = new list<cl_kernel>(); + + this->input->executeOpenCL(context, program, queue, outputMemoryBuffer, clOutputBuffer, inputMemoryBuffers, clMemToCleanUp, clKernelsToCleanUp); + + // STEP 3 + + size_t origin[3] = {0,0,0}; + size_t region[3] = {outputBufferWidth,outputBufferHeight,1}; + + error = clEnqueueBarrier(queue); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + error = clEnqueueReadImage(queue, clOutputBuffer, CL_TRUE, origin, region, 0, 0, outputFloatBuffer, 0, NULL, NULL); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + // STEP 4 + + while (clMemToCleanUp->size()>0) { + cl_mem mem = clMemToCleanUp->front(); + error = clReleaseMemObject(mem); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + clMemToCleanUp->pop_front(); + } + + while (clKernelsToCleanUp->size()>0) { + cl_kernel kernel = clKernelsToCleanUp->front(); + error = clReleaseKernel(kernel); + if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } + clKernelsToCleanUp->pop_front(); + } + delete clKernelsToCleanUp; +} diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h new file mode 100644 index 00000000000..3b28ffd4f63 --- /dev/null +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_WriteBufferOperation_h_ +#define _COM_WriteBufferOperation_h_ + +#include "COM_NodeOperation.h" +#include "COM_MemoryProxy.h" +#include "COM_SocketReader.h" +/** + * @brief Operation to write to a tile + * @ingroup Operation + */ +class WriteBufferOperation: public NodeOperation { + MemoryProxy *memoryProxy; + NodeOperation *input; + const bNodeTree * tree; +public: + WriteBufferOperation(); + ~WriteBufferOperation(); + int isBufferOperation() {return true;} + MemoryProxy* getMemoryProxy() {return this->memoryProxy;} + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); + const bool isWriteBufferOperation() const {return true;} + + void executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers); + void initExecution(); + void deinitExecution(); + void setbNodeTree(const bNodeTree* tree) {this->tree = tree;} + void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers); + +}; +#endif diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cpp b/source/blender/compositor/operations/COM_ZCombineOperation.cpp new file mode 100644 index 00000000000..9aa06df1ead --- /dev/null +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_ZCombineOperation.h" +#include "BLI_utildefines.h" + +ZCombineOperation::ZCombineOperation(): NodeOperation() { + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + + this->image1Reader = NULL; + this->depth1Reader = NULL; + this->image2Reader = NULL; + this->depth2Reader = NULL; + +} + +void ZCombineOperation::initExecution() { + this->image1Reader = this->getInputSocketReader(0); + this->depth1Reader = this->getInputSocketReader(1); + this->image2Reader = this->getInputSocketReader(2); + this->depth2Reader = this->getInputSocketReader(3); +} + +void ZCombineOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float depth1[4]; + float depth2[4]; + + this->depth1Reader->read(depth1, x, y, sampler, inputBuffers); + this->depth2Reader->read(depth2, x, y, sampler, inputBuffers); + if (depth1[0]<depth2[0]) { + this->image1Reader->read(color, x, y, sampler, inputBuffers); + } else { + this->image2Reader->read(color, x, y, sampler, inputBuffers); + } +} +void ZCombineAlphaOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { + float depth1[4]; + float depth2[4]; + float color1[4]; + float color2[4]; + + this->depth1Reader->read(depth1, x, y, sampler, inputBuffers); + this->depth2Reader->read(depth2, x, y, sampler, inputBuffers); + if (depth1[0]<depth2[0]) { + this->image1Reader->read(color1, x, y, sampler, inputBuffers); + this->image2Reader->read(color2, x, y, sampler, inputBuffers); + } else { + this->image1Reader->read(color2, x, y, sampler, inputBuffers); + this->image2Reader->read(color1, x, y, sampler, inputBuffers); + } + float fac = color1[3]; + float ifac = 1.0f-fac; + color[0] = color1[0]+ifac*color2[0]; + color[1] = color1[1]+ifac*color2[1]; + color[2] = color1[2]+ifac*color2[2]; + color[3] = MAX2(color1[3], color2[3]); +} + +void ZCombineOperation::deinitExecution() { + this->image1Reader = NULL; + this->depth1Reader = NULL; + this->image2Reader = NULL; + this->depth2Reader = NULL; +} diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h new file mode 100644 index 00000000000..d5a3f02fea2 --- /dev/null +++ b/source/blender/compositor/operations/COM_ZCombineOperation.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Jeroen Bakker + * Monique Dewanchand + */ + +#ifndef _COM_ZCombineOperation_h +#define _COM_ZCombineOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input colour to an output value. + * it assumes we are in sRGB colour space. + */ +class ZCombineOperation : public NodeOperation { +protected: + SocketReader* image1Reader; + SocketReader* depth1Reader; + SocketReader* image2Reader; + SocketReader* depth2Reader; +public: + /** + * Default constructor + */ + ZCombineOperation(); + + void initExecution(); + void deinitExecution(); + + /** + * the inner loop of this program + */ + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +class ZCombineAlphaOperation: public ZCombineOperation { + void executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); +}; + +#endif |