From 578f98d7ad31d7f1630f674253aeb4872502b6da Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 18 Feb 2016 01:28:41 +1100 Subject: Fix T47452: Translate-node seams w/ subpixel offset --- source/blender/blenlib/BLI_math_interp.h | 6 ++++ source/blender/blenlib/intern/math_interp.c | 37 ++++++++++++++++++---- .../blender/compositor/intern/COM_MemoryBuffer.h | 4 ++- 3 files changed, 39 insertions(+), 8 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_math_interp.h b/source/blender/blenlib/BLI_math_interp.h index d2ec7b80d86..a3c5ce82630 100644 --- a/source/blender/blenlib/BLI_math_interp.h +++ b/source/blender/blenlib/BLI_math_interp.h @@ -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]; diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index b45d8b4c13b..069d23e7147 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -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" diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index de8c14e1a66..f9e2dd87d05 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -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]); -- cgit v1.2.3