Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2013-12-04 14:56:36 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2013-12-04 15:09:13 +0400
commit45fc80153a40fb01db6b1e25b4ab575a06a331b8 (patch)
tree898972a78c5074ef1fc3f4f90c9f9791225c538f /source/blender/compositor
parenta698709d956f01ff4a2a1c0d27450c6880dd2ad5 (diff)
Fix for interpolation errors on lower-left borders in compositor image
inputs. http://wiki.blender.org/uploads/4/4c/Compo_image_interpolation_borders.png Problem is that all image buffer reader nodes (RenderLayer, Image, MovieClip) were clipping pixel coordinates to 0..N range (N being width or height respectively). Bilinear interpolation works ok then on the upper-right borders (x, N) and (N, y), since the last (N-1) pixel fades out to N (background). But the lower-left (x, 0) and (0, y) borders are not correctly interpolated because the nodes cut off the negative pixels before the interpolation function can calculate their value. To fix this, the interpolation functions are now entirely responsible for handling "out of range" cases, i.e. setting (0,0,0,0) results for invalid pixels, while also handling interpolation for borders. Callers should not do pixel range checks themselves, which also makes the code simpler. Should not have any real performance penalty, the interpolation functions do this check anyway, so is probably even slightly faster.
Diffstat (limited to 'source/blender/compositor')
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.cpp14
-rw-r--r--source/blender/compositor/operations/COM_MovieClipOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MultilayerImageOperation.cpp42
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.cpp14
4 files changed, 45 insertions, 27 deletions
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp
index adc325de377..353d6e8f6ce 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_ImageOperation.cpp
@@ -148,7 +148,7 @@ static void sampleImageAtLocation(ImBuf *ibuf, float x, float y, PixelSampler sa
void ImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- if ((this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) {
+ if (this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) {
zero_v4(output);
}
else {
@@ -160,7 +160,7 @@ void ImageAlphaOperation::executePixelSampled(float output[4], float x, float y,
{
float tempcolor[4];
- if ((this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) {
+ if (this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) {
output[0] = 0.0f;
}
else {
@@ -172,11 +172,15 @@ void ImageAlphaOperation::executePixelSampled(float output[4], float x, float y,
void ImageDepthOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- if (this->m_depthBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) {
+ if (this->m_depthBuffer == NULL) {
output[0] = 0.0f;
}
else {
- int offset = y * this->m_width + x;
- output[0] = this->m_depthBuffer[offset];
+ if (x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight())
+ output[0] = 0.0f;
+ else {
+ int offset = y * this->m_width + x;
+ output[0] = this->m_depthBuffer[offset];
+ }
}
}
diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
index 5b75113e7f3..dcb5ca06662 100644
--- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp
+++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
@@ -90,7 +90,7 @@ void MovieClipBaseOperation::executePixelSampled(float output[4], float x, float
{
ImBuf *ibuf = this->m_movieClipBuffer;
- if (ibuf == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) {
+ if (ibuf == NULL) {
zero_v4(output);
}
else if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
index 84c1fdfb6f5..ffa319f20a8 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
@@ -44,9 +44,7 @@ ImBuf *MultilayerBaseOperation::getImBuf()
void MultilayerColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- int yi = y;
- int xi = x;
- if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
+ if (this->m_imageFloatBuffer == NULL) {
zero_v4(output);
}
else {
@@ -64,34 +62,48 @@ void MultilayerColorOperation::executePixelSampled(float output[4], float x, flo
}
}
else {
- int offset = (yi * this->getWidth() + xi) * 3;
- copy_v3_v3(output, &this->m_imageFloatBuffer[offset]);
+ int yi = y;
+ int xi = x;
+ if (xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight())
+ zero_v4(output);
+ else {
+ int offset = (yi * this->getWidth() + xi) * 3;
+ copy_v3_v3(output, &this->m_imageFloatBuffer[offset]);
+ }
}
}
}
void MultilayerValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- int yi = y;
- int xi = x;
- if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
+ if (this->m_imageFloatBuffer == NULL) {
output[0] = 0.0f;
}
else {
- float result = this->m_imageFloatBuffer[yi * this->getWidth() + xi];
- output[0] = result;
+ int yi = y;
+ int xi = x;
+ if (xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight())
+ output[0] = 0.0f;
+ else {
+ float result = this->m_imageFloatBuffer[yi * this->getWidth() + xi];
+ output[0] = result;
+ }
}
}
void MultilayerVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- int yi = y;
- int xi = x;
- if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
+ if (this->m_imageFloatBuffer == NULL) {
output[0] = 0.0f;
}
else {
- int offset = (yi * this->getWidth() + xi) * 3;
- copy_v3_v3(output, &this->m_imageFloatBuffer[offset]);
+ int yi = y;
+ int xi = x;
+ if (xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight())
+ output[0] = 0.0f;
+ else {
+ int offset = (yi * this->getWidth() + xi) * 3;
+ copy_v3_v3(output, &this->m_imageFloatBuffer[offset]);
+ }
}
}
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
index 2c2a4c6f180..f72af2780d7 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
@@ -75,13 +75,15 @@ void RenderLayersBaseProg::initExecution()
void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
{
unsigned int offset;
- int ix, iy;
int width = this->getWidth(), height = this->getHeight();
switch (sampler) {
- case COM_PS_NEAREST:
- ix = x;
- iy = y;
+ case COM_PS_NEAREST: {
+ int ix = x;
+ int iy = y;
+ if (ix < 0 || iy < 0 || ix >= width || iy >= height)
+ break;
+
offset = (iy * width + ix) * this->m_elementsize;
if (this->m_elementsize == 1)
@@ -90,8 +92,8 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
copy_v3_v3(output, &this->m_inputBuffer[offset]);
else
copy_v4_v4(output, &this->m_inputBuffer[offset]);
-
break;
+ }
case COM_PS_BILINEAR:
BLI_bilinear_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
@@ -137,7 +139,7 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
int iy = y;
#endif
- if (this->m_inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
+ if (this->m_inputBuffer == NULL) {
zero_v4(output);
}
else {