Fix for harmless uninitialized-variable warning
[blender.git] / source / blender / compositor / operations / COM_MovieDistortionOperation.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_MovieDistortionOperation.h"
24
25 extern "C" {
26         #include "BKE_tracking.h"
27         #include "BKE_movieclip.h"
28         #include "BLI_linklist.h"
29 }
30
31
32 vector<DistortionCache *> s_cache;
33
34 void deintializeDistortionCache(void) 
35 {
36         while (s_cache.size() > 0) {
37                 DistortionCache * cache = s_cache.back();
38                 s_cache.pop_back();
39                 delete cache;
40         }
41 }
42
43 MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation()
44 {
45         this->addInputSocket(COM_DT_COLOR);
46         this->addOutputSocket(COM_DT_COLOR);
47         this->setResolutionInputSocketIndex(0);
48         this->m_inputOperation = NULL;
49         this->m_movieClip = NULL;
50         this->m_cache = NULL;
51         this->m_distortion = distortion;
52 }
53
54 void MovieDistortionOperation::initExecution()
55 {
56         this->m_inputOperation = this->getInputSocketReader(0);
57         if (this->m_movieClip) {
58                 MovieClipUser clipUser = {0};
59                 int calibration_width, calibration_height;
60
61                 BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber);
62                 BKE_movieclip_get_size(this->m_movieClip, &clipUser, &calibration_width, &calibration_height);
63
64                 for (unsigned int i = 0; i < s_cache.size(); i++) {
65                         DistortionCache *c = (DistortionCache *)s_cache[i];
66                         if (c->isCacheFor(this->m_movieClip, this->m_width, this->m_height,
67                                           calibration_width, calibration_height, this->m_distortion))
68                         {
69                                 this->m_cache = c;
70                                 this->m_cache->updateLastUsage();
71                                 return;
72                         }
73                 }
74                 DistortionCache *newC = new DistortionCache(this->m_movieClip, this->m_width, this->m_height,
75                                                             calibration_width, calibration_height, this->m_distortion);
76                 s_cache.push_back(newC);
77                 this->m_cache = newC;
78         }
79         else {
80                 this->m_cache = NULL;
81         }
82 }
83
84 void MovieDistortionOperation::deinitExecution()
85 {
86         this->m_inputOperation = NULL;
87         this->m_movieClip = NULL;
88         while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) {
89                 double minTime = PIL_check_seconds_timer();
90                 vector<DistortionCache*>::iterator minTimeIterator = s_cache.begin();
91                 for (vector<DistortionCache*>::iterator it = s_cache.begin(); it < s_cache.end(); it ++) {
92                         DistortionCache * cache = *it;
93                         if (cache->getTimeLastUsage() < minTime) {
94                                 minTime = cache->getTimeLastUsage();
95                                 minTimeIterator = it;
96                         }
97                 }
98                 s_cache.erase(minTimeIterator);
99         }
100 }
101
102
103 void MovieDistortionOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
104 {
105         
106         if (this->m_cache != NULL) {
107                 float u, v;
108                 this->m_cache->getUV(&this->m_movieClip->tracking, x, y, &u, &v);
109                 this->m_inputOperation->read(output, u, v, COM_PS_BILINEAR);
110         }
111         else {
112                 this->m_inputOperation->read(output, x, y, COM_PS_BILINEAR);
113         }
114 }
115
116 bool MovieDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
117 {
118         const int marginX = this->m_width*0.15;
119         const int marginY = this->m_height*0.15;
120
121         rcti newInput;
122         newInput.xmin = input->xmin - marginX;
123         newInput.ymin = input->ymin - marginY;
124         newInput.xmax = input->xmax + marginX;
125         newInput.ymax = input->ymax + marginY;
126         return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
127 }