compositor: replace C++ new/delete with guardedalloc.
[blender.git] / source / blender / compositor / operations / COM_VectorBlurOperation.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 #include "COM_VectorBlurOperation.h"
24 #include "BLI_math.h"
25
26 #include "MEM_guardedalloc.h"
27
28 // use the implementation of blender internal renderer to calculate the vector blur.
29 extern "C" {
30         #include "RE_pipeline.h"
31 }
32
33 VectorBlurOperation::VectorBlurOperation() : NodeOperation()
34 {
35         this->addInputSocket(COM_DT_COLOR);
36         this->addInputSocket(COM_DT_VALUE); // ZBUF
37         this->addInputSocket(COM_DT_COLOR); //SPEED
38         this->addOutputSocket(COM_DT_COLOR);
39         this->m_settings = NULL;
40         this->m_cachedInstance = NULL;
41         this->m_inputImageProgram = NULL;
42         this->m_inputSpeedProgram = NULL;
43         this->m_inputZProgram = NULL;
44         setComplex(true);
45 }
46 void VectorBlurOperation::initExecution()
47 {
48         initMutex();
49         this->m_inputImageProgram = getInputSocketReader(0);
50         this->m_inputZProgram = getInputSocketReader(1);
51         this->m_inputSpeedProgram = getInputSocketReader(2);
52         this->m_cachedInstance = NULL;
53         QualityStepHelper::initExecution(COM_QH_INCREASE);
54         
55 }
56
57 void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data)
58 {
59         float *buffer = (float *) data;
60         int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS;
61         copy_v4_v4(output, &buffer[index]);
62 }
63
64 void VectorBlurOperation::deinitExecution()
65 {
66         deinitMutex();
67         this->m_inputImageProgram = NULL;
68         this->m_inputSpeedProgram = NULL;
69         this->m_inputZProgram = NULL;
70         if (this->m_cachedInstance) {
71                 MEM_freeN(this->m_cachedInstance);
72                 this->m_cachedInstance = NULL;
73         }
74 }
75 void *VectorBlurOperation::initializeTileData(rcti *rect)
76 {
77         if (this->m_cachedInstance) {
78                 return this->m_cachedInstance;
79         }
80         
81         lockMutex();
82         if (this->m_cachedInstance == NULL) {
83                 MemoryBuffer *tile = (MemoryBuffer *)this->m_inputImageProgram->initializeTileData(rect);
84                 MemoryBuffer *speed = (MemoryBuffer *)this->m_inputSpeedProgram->initializeTileData(rect);
85                 MemoryBuffer *z = (MemoryBuffer *)this->m_inputZProgram->initializeTileData(rect);
86                 float *data = (float *)MEM_dupallocN(tile->getBuffer());
87                 this->generateVectorBlur(data, tile, speed, z);
88                 this->m_cachedInstance = data;
89         }
90         unlockMutex();
91         return this->m_cachedInstance;
92 }
93
94 bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
95 {
96         if (this->m_cachedInstance == NULL) {
97                 rcti newInput;
98                 newInput.xmax = this->getWidth();
99                 newInput.xmin = 0;
100                 newInput.ymax = this->getHeight();
101                 newInput.ymin = 0;
102                 return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
103         }
104         else {
105                 return false;
106         }
107 }
108
109 void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ)
110 {
111         float *zbuf = inputZ->convertToValueBuffer();
112         NodeBlurData blurdata;
113         blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep();
114         blurdata.maxspeed = this->m_settings->maxspeed;
115         blurdata.minspeed = this->m_settings->minspeed;
116         blurdata.curved = this->m_settings->curved;
117         blurdata.fac = this->m_settings->fac;
118         RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf);
119         MEM_freeN((void *)zbuf);
120         return;
121 }