/* * Copyright 2011, Blender Foundation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; 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; }