Merging r49840 through r49854 from trunk into soc-2011-tomato
[blender.git] / source / blender / compositor / operations / COM_InpaintOperation.cpp
index eb732cc2b80f5f6b5b82d4743c0e25a57940c757..b0e9c601e077ddd6c3ea29bfa79d3ccc65d4df5f 100644 (file)
@@ -57,7 +57,7 @@ void InpaintSimpleOperation::initExecution()
        this->initMutex();
 }
 
-void InpaintSimpleOperation::clamp_xy(int & x, int & y) 
+void InpaintSimpleOperation::clamp_xy(int &x, int &y)
 {
        int width = this->getWidth();
        int height = this->getHeight();
@@ -97,7 +97,7 @@ int InpaintSimpleOperation::mdist(int x, int y)
        return this->m_manhatten_distance[y * width + x];
 }
 
-bool InpaintSimpleOperation::next_pixel(int & x, int & y, int & curr, int iters)
+bool InpaintSimpleOperation::next_pixel(int &x, int &y, int & curr, int iters)
 {
        int width = this->getWidth();
 
@@ -110,7 +110,7 @@ bool InpaintSimpleOperation::next_pixel(int & x, int & y, int & curr, int iters)
        x = r % width;
        y = r / width;
 
-       if (mdist(x, y) > iters) {
+       if (this->mdist(x, y) > iters) {
                return false;
        }
        
@@ -176,11 +176,9 @@ void InpaintSimpleOperation::calc_manhatten_distance()
 
 void InpaintSimpleOperation::pix_step(int x, int y)
 {
-       int d = this->mdist(x, y);
-
-       float n = 0;
-
+       const int d = this->mdist(x, y);
        float pix[3] = {0.0f, 0.0f, 0.0f};
+       float pix_divider = 0.0f;
 
        for (int dx = -1; dx <= 1; dx++) {
                for (int dy = -1; dy <= 1; dy++) {
@@ -202,13 +200,19 @@ void InpaintSimpleOperation::pix_step(int x, int y)
                                        }
 
                                        madd_v3_v3fl(pix, this->get_pixel(x_ofs, y_ofs), weight);
-                                       n += weight;
+                                       pix_divider += weight;
                                }
                        }
                }
        }
 
-       mul_v3_v3fl(this->get_pixel(x, y), pix, 1.0f / n);
+       float *output = this->get_pixel(x, y);
+       if (pix_divider != 0.0f) {
+               mul_v3_fl(pix, 1.0f / pix_divider);
+               /* use existing pixels alpha to blend into */
+               interp_v3_v3v3(output, pix, output, output[3]);
+               output[3] = 1.0f;
+       }
 
        this->get_pixel(x, y)[3] = 1.0f;
 }
@@ -225,14 +229,14 @@ void *InpaintSimpleOperation::initializeTileData(rcti *rect)
                this->m_cached_buffer = new float[this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS];
                memcpy(this->m_cached_buffer, buf->getBuffer(), this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
 
-               calc_manhatten_distance();
+               this->calc_manhatten_distance();
 
                int curr = 0;
                int x, y;
 
        
-               while (next_pixel(x, y, curr, this->m_iterations)) {
-                       pix_step(x, y);
+               while (this->next_pixel(x, y, curr, this->m_iterations)) {
+                       this->pix_step(x, y);
                }
                this->m_cached_buffer_ready = true;
        }