Fix T47452: Translate-node seams w/ subpixel offset
authorCampbell Barton <ideasman42@gmail.com>
Wed, 17 Feb 2016 14:28:41 +0000 (01:28 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 17 Feb 2016 15:16:49 +0000 (02:16 +1100)
source/blender/blenlib/BLI_math_interp.h
source/blender/blenlib/intern/math_interp.c
source/blender/compositor/intern/COM_MemoryBuffer.h

index d2ec7b80d866f47100f41672adda41051eaa0124..a3c5ce82630bb2050c1459a591a3c5ebb28ecbde 100644 (file)
@@ -45,6 +45,12 @@ void BLI_bilinear_interpolation_fl(const float *buffer, float *output, int width
 void BLI_bilinear_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
                                      int components, float u, float v);
 
+void BLI_bilinear_interpolation_wrap_fl(const float *buffer, float *output, int width, int height,
+                                        int components, float u, float v, bool wrap_x, bool wrap_y);
+
+void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer, unsigned char *output, int width, int height,
+                                          int components, float u, float v, bool wrap_x, bool wrap_y);
+
 #define EWA_MAXIDX 255
 extern const float EWA_WTS[EWA_MAXIDX + 1];
 
index b45d8b4c13b25149e8d681c2a6e98bc12068931b..069d23e7147a6d7d62b887090417c1cc316273ec 100644 (file)
@@ -262,7 +262,7 @@ void BLI_bicubic_interpolation_char(const unsigned char *buffer, unsigned char *
 /* BILINEAR INTERPOLATION */
 BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const float *float_buffer,
                                        unsigned char *byte_output, float *float_output, int width, int height,
-                                       int components, float u, float v)
+                                       int components, float u, float v, bool wrap_x, bool wrap_y)
 {
        float a, b;
        float a_b, ma_b, a_mb, ma_mb;
@@ -279,11 +279,21 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f
                const float *row1, *row2, *row3, *row4;
                float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 
-               /* sample area entirely outside image? */
-               if (x2 < 0 || x1 > width - 1 || y2 < 0 || y1 > height - 1) {
-                       copy_vn_fl(float_output, components, 0.0f);
-                       return;
+               /* pixel value must be already wrapped, however values at boundaries may flip */
+               if (wrap_x) {
+                       if (x1 < 0) x1 = width  - 1;
+                       if (x2 >= width) x2 = 0;
                }
+               if (wrap_y) {
+                       if (y1 < 0) y1 = height - 1;
+                       if (y2 >= height) y2 = 0;
+               }
+
+               CLAMP(x1, 0, width - 1);
+               CLAMP(x2, 0, width - 1);
+
+               CLAMP(y1, 0, height - 1);
+               CLAMP(y2, 0, height - 1);
 
                /* sample including outside of edges of image */
                if (x1 < 0 || y1 < 0) row1 = empty;
@@ -364,15 +374,28 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f
 void BLI_bilinear_interpolation_fl(const float *buffer, float *output, int width, int height,
                                    int components, float u, float v)
 {
-       bilinear_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
+       bilinear_interpolation(NULL, buffer, NULL, output, width, height, components, u, v, false, false);
 }
 
 void BLI_bilinear_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
                                      int components, float u, float v)
 {
-       bilinear_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
+       bilinear_interpolation(buffer, NULL, output, NULL, width, height, components, u, v, false, false);
 }
 
+void BLI_bilinear_interpolation_wrap_fl(const float *buffer, float *output, int width, int height,
+                                        int components, float u, float v, bool wrap_x, bool wrap_y)
+{
+       bilinear_interpolation(NULL, buffer, NULL, output, width, height, components, u, v, wrap_x, wrap_y);
+}
+
+void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer, unsigned char *output, int width, int height,
+                                          int components, float u, float v, bool wrap_x, bool wrap_y)
+{
+       bilinear_interpolation(buffer, NULL, output, NULL, width, height, components, u, v, wrap_x, wrap_y);
+}
+
+
 /**************************************************************************
  * Filtering method based on
  * "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
index de8c14e1a66c2e5b95a1a9ac0e8dd13290bb0ced..f9e2dd87d05cc2e624f09aa68cb6c355fea1cacd 100644 (file)
@@ -259,7 +259,9 @@ public:
                float u = x;
                float v = y;
                this->wrap_pixel(u, v, extend_x, extend_y);
-               BLI_bilinear_interpolation_fl(this->m_buffer, result, this->m_width, this->m_height, this->m_num_channels, u, v);
+               BLI_bilinear_interpolation_wrap_fl(
+                       this->m_buffer, result, this->m_width, this->m_height, this->m_num_channels, u, v,
+                       extend_x == COM_MB_REPEAT, extend_y == COM_MB_REPEAT);
        }
 
        void readEWA(float *result, const float uv[2], const float derivatives[2][2]);