diff options
Diffstat (limited to 'source/blender/compositor/operations/COM_ScaleOperation.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_ScaleOperation.cpp | 196 |
1 files changed, 196 insertions, 0 deletions
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; +} |