Fix T38529, Blur node size 0 doesn't work.
authorLukas Tönne <lukas.toenne@gmail.com>
Thu, 13 Feb 2014 10:46:15 +0000 (11:46 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Thu, 13 Feb 2014 10:52:22 +0000 (11:52 +0100)
The blur operations were clamping the filter size to 1, which prevents
no-op blur nodes. Further any value < 1 would also be ignored and in
many combinations the filter scale setting ("Size") would only work in
integer steps.

Now most blur settings will work with smooth Size value scaling as well,
meaning you can choose a reasonably large filter size (e.g. 10) and then
use the Size factor to scale the actual blur radius smoothly.

Note that non-integer filter sizes also depend on the filter type
selected in the Blur node, e.g. "Flat" filtering will still ignore
smooth filter sizes. Gaussian filters work best for this purpose.

12 files changed:
source/blender/compositor/operations/COM_BlurBaseOperation.cpp
source/blender/compositor/operations/COM_BlurBaseOperation.h
source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianXBlurOperation.h
source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianYBlurOperation.h

index c8d53b6992d950f6ba91cb76d08872a729345e42..d13fea921bec2edc2497d58826138bd4ca882669 100644 (file)
@@ -68,20 +68,21 @@ void BlurBaseOperation::initExecution()
 
 }
 
-float *BlurBaseOperation::make_gausstab(int rad)
+float *BlurBaseOperation::make_gausstab(float rad, int size)
 {
        float *gausstab, sum, val;
        int i, n;
 
-       n = 2 * rad + 1;
+       n = 2 * size + 1;
 
        gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
 
        sum = 0.0f;
-       for (i = -rad; i <= rad; i++) {
-               val = RE_filter_value(this->m_data->filtertype, (float)i / (float)rad);
+       float fac = (rad > 0.0f ? 1.0f/rad : 0.0f);
+       for (i = -size; i <= size; i++) {
+               val = RE_filter_value(this->m_data->filtertype, (float)i * fac);
                sum += val;
-               gausstab[i + rad] = val;
+               gausstab[i + size] = val;
        }
 
        sum = 1.0f / sum;
@@ -93,17 +94,18 @@ float *BlurBaseOperation::make_gausstab(int rad)
 
 /* normalized distance from the current (inverted so 1.0 is close and 0.0 is far)
  * 'ease' is applied after, looks nicer */
-float *BlurBaseOperation::make_dist_fac_inverse(int rad, int falloff)
+float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff)
 {
        float *dist_fac_invert, val;
        int i, n;
 
-       n = 2 * rad + 1;
+       n = 2 * size + 1;
 
        dist_fac_invert = (float *)MEM_mallocN(sizeof(float) * n, __func__);
 
-       for (i = -rad; i <= rad; i++) {
-               val = 1.0f - fabsf(((float)i / (float)rad));
+       float fac = (rad > 0.0f ? 1.0f/rad : 0.0f);
+       for (i = -size; i <= size; i++) {
+               val = 1.0f - fabsf((float)i * fac);
 
                /* keep in sync with proportional_falloff_curve_only_items */
                switch (falloff) {
@@ -132,7 +134,7 @@ float *BlurBaseOperation::make_dist_fac_inverse(int rad, int falloff)
                                /* nothing */
                                break;
                }
-               dist_fac_invert[i + rad] = val;
+               dist_fac_invert[i + size] = val;
        }
 
        return dist_fac_invert;
index a868f0bfa04c3f5e60521d66b76e474398e24d60..c5d89b1bc91d1060b12dc7bf6268b0de4d35cdcd 100644 (file)
@@ -33,8 +33,8 @@ private:
 protected:
 
        BlurBaseOperation(DataType data_type);
-       float *make_gausstab(int rad);
-       float *make_dist_fac_inverse(int rad, int falloff);
+       float *make_gausstab(float rad, int size);
+       float *make_dist_fac_inverse(float rad, int size, int falloff);
 
        void updateSize();
 
index f4c73c31ed8b16a73b4edf12f52dc8d4dfa9cbf7..4ae0b4e78b22d8fe5040ed18f6496e3d2e4c5351 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
 GaussianAlphaXBlurOperation::GaussianAlphaXBlurOperation() : BlurBaseOperation(COM_DT_VALUE)
 {
        this->m_gausstab = NULL;
-       this->m_rad = 0;
+       this->m_filtersize = 0;
        this->m_falloff = -1;  /* intentionally invalid, so we can detect uninitialized values */
 }
 
@@ -54,12 +54,11 @@ void GaussianAlphaXBlurOperation::initExecution()
        initMutex();
 
        if (this->m_sizeavailable) {
-               float rad = this->m_size * this->m_data->sizex;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
-               this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+               float rad = max_ff(m_size * m_data->sizex, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
+               m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
        }
 }
 
@@ -67,20 +66,18 @@ void GaussianAlphaXBlurOperation::updateGauss()
 {
        if (this->m_gausstab == NULL) {
                updateSize();
-               float rad = this->m_size * this->m_data->sizex;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+               float rad = max_ff(m_size * m_data->sizex, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
        }
 
        if (this->m_distbuf_inv == NULL) {
                updateSize();
-               float rad = this->m_size * this->m_data->sizex;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+               float rad = max_ff(m_size * m_data->sizex, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
        }
 }
 
@@ -98,18 +95,15 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
        int bufferstartx = inputBuffer->getRect()->xmin;
        int bufferstarty = inputBuffer->getRect()->ymin;
 
-       int miny = y;
-       int minx = x - this->m_rad;
-       int maxx = x + this->m_rad;  // UNUSED
-       miny = max(miny, inputBuffer->getRect()->ymin);
-       minx = max(minx, inputBuffer->getRect()->xmin);
-       maxx = min(maxx, inputBuffer->getRect()->xmax -1);
-
+       rcti &rect = *inputBuffer->getRect();
+       int xmin = max_ii(x - m_filtersize,     rect.xmin);
+       int xmax = min_ii(x + m_filtersize + 1, rect.xmax);
+       int ymin = max_ii(y,                    rect.ymin);
 
        /* *** this is the main part which is different to 'GaussianXBlurOperation'  *** */
        int step = getStep();
        int offsetadd = getOffsetAdd();
-       int bufferindex = ((minx - bufferstartx) * 4) + ((miny - bufferstarty) * 4 * bufferwidth);
+       int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
 
        /* gauss */
        float alpha_accum = 0.0f;
@@ -119,8 +113,8 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
        float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
        float distfacinv_max = 1.0f; /* 0 to 1 */
 
-       for (int nx = minx; nx <= maxx; nx += step) {
-               const int index = (nx - x) + this->m_rad;
+       for (int nx = xmin; nx < xmax; nx += step) {
+               const int index = (nx - x) + this->m_filtersize;
                float value = finv_test(buffer[bufferindex], do_invert);
                float multiplier;
 
@@ -178,8 +172,8 @@ bool GaussianAlphaXBlurOperation::determineDependingAreaOfInterest(rcti *input,
 #endif
        {
                if (this->m_sizeavailable && this->m_gausstab != NULL) {
-                       newInput.xmax = input->xmax + this->m_rad + 1;
-                       newInput.xmin = input->xmin - this->m_rad - 1;
+                       newInput.xmax = input->xmax + this->m_filtersize + 1;
+                       newInput.xmin = input->xmin - this->m_filtersize - 1;
                        newInput.ymax = input->ymax;
                        newInput.ymin = input->ymin;
                }
index 21e80c5daf554133b17a017c1ccd0962c1d4b6a6..0d61e964009e1c9d4356adf9e9ba88d19f5015ae 100644 (file)
@@ -32,7 +32,7 @@ private:
        float *m_distbuf_inv;
        int m_falloff;  /* falloff for distbuf_inv */
        bool m_do_subtract;
-       int m_rad;
+       int m_filtersize;
        void updateGauss();
 public:
        GaussianAlphaXBlurOperation();
index 4866fb9b4289805cb776398c20df5dcc425aadb1..fb407bf9ee4fda28bb08e67a8140e2bddcd50ab3 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
 GaussianAlphaYBlurOperation::GaussianAlphaYBlurOperation() : BlurBaseOperation(COM_DT_VALUE)
 {
        this->m_gausstab = NULL;
-       this->m_rad = 0;
+       this->m_filtersize = 0;
        this->m_falloff = -1;  /* intentionally invalid, so we can detect uninitialized values */
 }
 
@@ -54,12 +54,11 @@ void GaussianAlphaYBlurOperation::initExecution()
        initMutex();
 
        if (this->m_sizeavailable) {
-               float rad = this->m_size * this->m_data->sizey;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
-               this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+               float rad = max_ff(m_size * m_data->sizey, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
+               m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
        }
 }
 
@@ -67,20 +66,18 @@ void GaussianAlphaYBlurOperation::updateGauss()
 {
        if (this->m_gausstab == NULL) {
                updateSize();
-               float rad = this->m_size * this->m_data->sizey;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+               float rad = max_ff(m_size * m_data->sizey, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
        }
 
        if (this->m_distbuf_inv == NULL) {
                updateSize();
-               float rad = this->m_size * this->m_data->sizex;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, this->m_falloff);
+               float rad = max_ff(m_size * m_data->sizey, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
        }
 }
 
@@ -98,12 +95,10 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
        int bufferstartx = inputBuffer->getRect()->xmin;
        int bufferstarty = inputBuffer->getRect()->ymin;
 
-       int miny = y - this->m_rad;
-       int maxy = y + this->m_rad;
-       int minx = x;
-       miny = max(miny, inputBuffer->getRect()->ymin);
-       minx = max(minx, inputBuffer->getRect()->xmin);
-       maxy = min(maxy, inputBuffer->getRect()->ymax - 1);
+       rcti &rect = *inputBuffer->getRect();
+       int xmin = max_ii(x,                    rect.xmin);
+       int ymin = max_ii(y - m_filtersize,     rect.ymin);
+       int ymax = min_ii(y + m_filtersize + 1, rect.ymax);
 
        /* *** this is the main part which is different to 'GaussianYBlurOperation'  *** */
        int step = getStep();
@@ -116,10 +111,10 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
        float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
        float distfacinv_max = 1.0f; /* 0 to 1 */
 
-       for (int ny = miny; ny <= maxy; ny += step) {
-               int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
+       for (int ny = ymin; ny < ymax; ny += step) {
+               int bufferindex = ((xmin - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
 
-               const int index = (ny - y) + this->m_rad;
+               const int index = (ny - y) + this->m_filtersize;
                float value = finv_test(buffer[bufferindex], do_invert);
                float multiplier;
 
@@ -179,8 +174,8 @@ bool GaussianAlphaYBlurOperation::determineDependingAreaOfInterest(rcti *input,
                if (this->m_sizeavailable && this->m_gausstab != NULL) {
                        newInput.xmax = input->xmax;
                        newInput.xmin = input->xmin;
-                       newInput.ymax = input->ymax + this->m_rad + 1;
-                       newInput.ymin = input->ymin - this->m_rad - 1;
+                       newInput.ymax = input->ymax + this->m_filtersize + 1;
+                       newInput.ymin = input->ymin - this->m_filtersize - 1;
                }
                else {
                        newInput.xmax = this->getWidth();
index cb8b2e048ce9068b182eca9795a704b058a96804..36b1201c9d77f2b7db9e4f953972041252be3d03 100644 (file)
@@ -32,7 +32,7 @@ private:
        float *m_distbuf_inv;
        bool m_do_subtract;
        int m_falloff;
-       int m_rad;
+       int m_filtersize;
        void updateGauss();
 public:
        GaussianAlphaYBlurOperation();
index 41d1fe65b11e7a3734422d6834d3e0e20c6177ab..44752d4e12e1b40f840a0de607fde1deb6c83060 100644 (file)
@@ -69,17 +69,11 @@ void GaussianBokehBlurOperation::updateGauss()
                        updateSize();
                }
                radxf = this->m_size * (float)this->m_data->sizex;
-               if (radxf > width / 2.0f)
-                       radxf = width / 2.0f;
-               else if (radxf < 1.0f)
-                       radxf = 1.0f;
+               CLAMP(radxf, 0.0f, width / 2.0f);
        
                /* vertical */
                radyf = this->m_size * (float)this->m_data->sizey;
-               if (radyf > height / 2.0f)
-                       radyf = height / 2.0f;
-               else if (radyf < 1.0f)
-                       radyf = 1.0f;
+               CLAMP(radyf, 0.0f, height / 2.0f);
        
                this->m_radx = ceil(radxf);
                this->m_rady = ceil(radyf);
@@ -92,16 +86,19 @@ void GaussianBokehBlurOperation::updateGauss()
                ddgauss = (float *)MEM_mallocN(sizeof(float) * n, __func__);
                dgauss = ddgauss;
                float sum = 0.0f;
+               float facx = (radxf > 0.0f ? 1.0f/radxf : 0.0f);
+               float facy = (radyf > 0.0f ? 1.0f/radyf : 0.0f);
                for (j = -this->m_rady; j <= this->m_rady; j++) {
                        for (i = -this->m_radx; i <= this->m_radx; i++, dgauss++) {
-                               float fj = (float)j / radyf;
-                               float fi = (float)i / radxf;
+                               float fj = (float)j * facy;
+                               float fi = (float)i * facx;
                                float dist = sqrt(fj * fj + fi * fi);
                                *dgauss = RE_filter_value(this->m_data->filtertype, dist);
                                
                                sum += *dgauss;
                        }
                }
+
                if (sum > 0.0f) {
                        /* normalize */
                        float norm = 1.0f / sum;
@@ -131,24 +128,21 @@ void GaussianBokehBlurOperation::executePixel(float output[4], int x, int y, voi
        int bufferstartx = inputBuffer->getRect()->xmin;
        int bufferstarty = inputBuffer->getRect()->ymin;
 
-       int miny = y - this->m_rady;
-       int maxy = y + this->m_rady;
-       int minx = x - this->m_radx;
-       int maxx = x + this->m_radx;
-       miny = max(miny, inputBuffer->getRect()->ymin);
-       minx = max(minx, inputBuffer->getRect()->xmin);
-       maxy = min(maxy, inputBuffer->getRect()->ymax);
-       maxx = min(maxx, inputBuffer->getRect()->xmax);
+       rcti &rect = *inputBuffer->getRect();
+       int ymin = max_ii(y - this->m_rady, rect.ymin);
+       int ymax = min_ii(y + this->m_rady + 1,  rect.ymax);
+       int xmin = max_ii(x - this->m_radx, rect.xmin);
+       int xmax = min_ii(x + this->m_radx + 1,  rect.xmax);
 
        int index;
        int step = QualityStepHelper::getStep();
        int offsetadd = QualityStepHelper::getOffsetAdd();
-       const int addConst = (minx - x + this->m_radx);
+       const int addConst = (xmin - x + this->m_radx);
        const int mulConst = (this->m_radx * 2 + 1);
-       for (int ny = miny; ny < maxy; ny += step) {
+       for (int ny = ymin; ny < ymax; ny += step) {
                index = ((ny - y) + this->m_rady) * mulConst + addConst;
-               int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
-               for (int nx = minx; nx < maxx; nx += step) {
+               int bufferindex = ((xmin - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
+               for (int nx = xmin; nx < xmax; nx += step) {
                        const float multiplier = this->m_gausstab[index];
                        madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplier);
                        multiplier_accum += multiplier;
@@ -239,32 +233,32 @@ void GaussianBlurReferenceOperation::initExecution()
        
        
        /* horizontal */
-       m_radx = (float)this->m_data->sizex;
+       m_filtersizex = (float)this->m_data->sizex;
        int imgx = getWidth() / 2;
-       if (m_radx > imgx)
-               m_radx = imgx;
-       else if (m_radx < 1)
-               m_radx = 1;
-       m_radxf = (float)m_radx;
+       if (m_filtersizex > imgx)
+               m_filtersizex = imgx;
+       else if (m_filtersizex < 1)
+               m_filtersizex = 1;
+       m_radx = (float)m_filtersizex;
 
        /* vertical */
-       m_rady = (float)this->m_data->sizey;
+       m_filtersizey = (float)this->m_data->sizey;
        int imgy = getHeight() / 2;
-       if (m_rady > imgy)
-               m_rady = imgy;
-       else if (m_rady < 1)
-               m_rady = 1;
-       m_radyf = (float)m_rady;
+       if (m_filtersizey > imgy)
+               m_filtersizey = imgy;
+       else if (m_filtersizey < 1)
+               m_filtersizey = 1;
+       m_rady = (float)m_filtersizey;
        updateGauss();
 }
 
 void GaussianBlurReferenceOperation::updateGauss()
 {
        int i;
-       int x = max(m_radx, m_rady);
-       this->m_maintabs = (float **)MEM_mallocN(x * sizeof(float *), "gauss array");
+       int x = max(m_filtersizex, m_filtersizey);
+       m_maintabs = (float **)MEM_mallocN(x * sizeof(float *), "gauss array");
        for (i = 0; i < x; i++) {
-               m_maintabs[i] = make_gausstab(i + 1);
+               m_maintabs[i] = make_gausstab(i + 1, i + 1);
        }
 }
 
@@ -283,11 +277,11 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
        float tempSize[4];
        this->m_inputSize->read(tempSize, x, y, data);
        float refSize = tempSize[0];
-       int refradx = (int)(refSize * m_radxf);
-       int refrady = (int)(refSize * m_radyf);
-       if (refradx > m_radx) refradx = m_radx;
+       int refradx = (int)(refSize * m_radx);
+       int refrady = (int)(refSize * m_rady);
+       if (refradx > m_filtersizex) refradx = m_filtersizex;
        else if (refradx < 1) refradx = 1;
-       if (refrady > m_rady) refrady = m_rady;
+       if (refrady > m_filtersizey) refrady = m_filtersizey;
        else if (refrady < 1) refrady = 1;
 
        if (refradx == 1 && refrady == 1) {
@@ -331,7 +325,7 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
 void GaussianBlurReferenceOperation::deinitExecution()
 {
        int x, i;
-       x = max(this->m_radx, this->m_rady);
+       x = max(this->m_filtersizex, this->m_filtersizey);
        for (i = 0; i < x; i++) {
                MEM_freeN(this->m_maintabs[i]);
        }
index 09994043c758be381485072db1a3ca13ccdc40fa..081c3743076ce9543739ab5d240b07b09862508e 100644 (file)
@@ -54,10 +54,10 @@ private:
        float **m_maintabs;
        
        void updateGauss();
-       int m_radx;
-       int m_rady;
-       float m_radxf;
-       float m_radyf;
+       int m_filtersizex;
+       int m_filtersizey;
+       float m_radx;
+       float m_rady;
 
 public:
        GaussianBlurReferenceOperation();
index 648ca0965c8e1768a8d4a9aa542fd75662b10a9e..127417bf70158db4f9fd87a84836dc3d7c69f9b8 100644 (file)
@@ -31,7 +31,7 @@ extern "C" {
 GaussianXBlurOperation::GaussianXBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
        this->m_gausstab = NULL;
-       this->m_rad = 0;
+       this->m_filtersize = 0;
 }
 
 void *GaussianXBlurOperation::initializeTileData(rcti *rect)
@@ -52,11 +52,10 @@ void GaussianXBlurOperation::initExecution()
        initMutex();
 
        if (this->m_sizeavailable) {
-               float rad = this->m_size * this->m_data->sizex;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+               float rad = max_ff(m_size * m_data->sizex, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
        }
 }
 
@@ -64,11 +63,10 @@ void GaussianXBlurOperation::updateGauss()
 {
        if (this->m_gausstab == NULL) {
                updateSize();
-               float rad = this->m_size * this->m_data->sizex;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+               float rad = max_ff(m_size * m_data->sizex, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
        }
 }
 
@@ -82,17 +80,15 @@ void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *d
        int bufferstartx = inputBuffer->getRect()->xmin;
        int bufferstarty = inputBuffer->getRect()->ymin;
 
-       int miny = y;
-       int minx = x - this->m_rad;
-       int maxx = x + this->m_rad;
-       miny = max(miny, inputBuffer->getRect()->ymin);
-       minx = max(minx, inputBuffer->getRect()->xmin);
-       maxx = min(maxx, inputBuffer->getRect()->xmax - 1);
+       rcti &rect = *inputBuffer->getRect();
+       int xmin = max_ii(x - m_filtersize,     rect.xmin);
+       int xmax = min_ii(x + m_filtersize + 1, rect.xmax);
+       int ymin = max_ii(y,                    rect.ymin);
 
        int step = getStep();
        int offsetadd = getOffsetAdd();
-       int bufferindex = ((minx - bufferstartx) * 4) + ((miny - bufferstarty) * 4 * bufferwidth);
-       for (int nx = minx, index = (minx - x) + this->m_rad; nx <= maxx; nx += step, index += step) {
+       int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
+       for (int nx = xmin, index = (xmin - x) + this->m_filtersize; nx < xmax; nx += step, index += step) {
                const float multiplier = this->m_gausstab[index];
                madd_v4_v4fl(color_accum, &buffer[bufferindex], multiplier);
                multiplier_accum += multiplier;
@@ -129,8 +125,8 @@ bool GaussianXBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB
        }
        {
                if (this->m_sizeavailable && this->m_gausstab != NULL) {
-                       newInput.xmax = input->xmax + this->m_rad + 1;
-                       newInput.xmin = input->xmin - this->m_rad - 1;
+                       newInput.xmax = input->xmax + this->m_filtersize + 1;
+                       newInput.xmin = input->xmin - this->m_filtersize - 1;
                        newInput.ymax = input->ymax;
                        newInput.ymin = input->ymin;
                }
index 4c3786b081048ede91d870e5ce5086bb23d11ef3..6442f2141381e60028f0fd9c3d5a60e7f6051b02 100644 (file)
@@ -28,7 +28,7 @@
 class GaussianXBlurOperation : public BlurBaseOperation {
 private:
        float *m_gausstab;
-       int m_rad;
+       int m_filtersize;
        void updateGauss();
 public:
        GaussianXBlurOperation();
index f58e3a2b4f285ff89c0e8c297f8911549a480b2c..583305a0fc4104dbf4afc1005180e612f06f6e60 100644 (file)
@@ -31,7 +31,7 @@ extern "C" {
 GaussianYBlurOperation::GaussianYBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
        this->m_gausstab = NULL;
-       this->m_rad = 0;
+       this->m_filtersize = 0;
 }
 
 void *GaussianYBlurOperation::initializeTileData(rcti *rect)
@@ -52,11 +52,10 @@ void GaussianYBlurOperation::initExecution()
        initMutex();
 
        if (this->m_sizeavailable) {
-               float rad = this->m_size * this->m_data->sizey;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+               float rad = max_ff(m_size * m_data->sizey, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
        }
 }
 
@@ -64,11 +63,10 @@ void GaussianYBlurOperation::updateGauss()
 {
        if (this->m_gausstab == NULL) {
                updateSize();
-               float rad = this->m_size * this->m_data->sizey;
-               CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS);
-
-               this->m_rad = rad;
-               this->m_gausstab = BlurBaseOperation::make_gausstab(rad);
+               float rad = max_ff(m_size * m_data->sizey, 0.0f);
+               m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
+               
+               this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
        }
 }
 
@@ -82,18 +80,16 @@ void GaussianYBlurOperation::executePixel(float output[4], int x, int y, void *d
        int bufferstartx = inputBuffer->getRect()->xmin;
        int bufferstarty = inputBuffer->getRect()->ymin;
 
-       int miny = y - this->m_rad;
-       int maxy = y + this->m_rad;
-       int minx = x;
-       miny = max(miny, inputBuffer->getRect()->ymin);
-       minx = max(minx, inputBuffer->getRect()->xmin);
-       maxy = min(maxy, inputBuffer->getRect()->ymax - 1);
+       rcti &rect = *inputBuffer->getRect();
+       int xmin = max_ii(x,                    rect.xmin);
+       int ymin = max_ii(y - m_filtersize,     rect.ymin);
+       int ymax = min_ii(y + m_filtersize + 1, rect.ymax);
 
        int index;
        int step = getStep();
-       const int bufferIndexx = ((minx - bufferstartx) * 4);
-       for (int ny = miny; ny <= maxy; ny += step) {
-               index = (ny - y) + this->m_rad;
+       const int bufferIndexx = ((xmin - bufferstartx) * 4);
+       for (int ny = ymin; ny < ymax; ny += step) {
+               index = (ny - y) + this->m_filtersize;
                int bufferindex = bufferIndexx + ((ny - bufferstarty) * 4 * bufferwidth);
                const float multiplier = this->m_gausstab[index];
                madd_v4_v4fl(color_accum, &buffer[bufferindex], multiplier);
@@ -132,8 +128,8 @@ bool GaussianYBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB
                if (this->m_sizeavailable && this->m_gausstab != NULL) {
                        newInput.xmax = input->xmax;
                        newInput.xmin = input->xmin;
-                       newInput.ymax = input->ymax + this->m_rad + 1;
-                       newInput.ymin = input->ymin - this->m_rad - 1;
+                       newInput.ymax = input->ymax + this->m_filtersize + 1;
+                       newInput.ymin = input->ymin - this->m_filtersize - 1;
                }
                else {
                        newInput.xmax = this->getWidth();
index 69dcb7e48fbe078789c6d23924fe048dc5ae6090..16503360de20c20c25da4193e07b7634a180657b 100644 (file)
@@ -28,7 +28,7 @@
 class GaussianYBlurOperation : public BlurBaseOperation {
 private:
        float *m_gausstab;
-       int m_rad;
+       int m_filtersize;
        void updateGauss();
 public:
        GaussianYBlurOperation();