Fix T38529, Blur node size 0 doesn't work.

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.
This commit is contained in:
Lukas Tönne 2014-02-13 11:46:15 +01:00
parent 5fdf6169a3
commit 51efa8a1f5
Notes: blender-bot 2023-02-14 11:14:28 +01:00
Referenced by issue #38529, Blur size can't be set to 0
12 changed files with 139 additions and 162 deletions

View 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;

View 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();

View 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;
}

View 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();

View 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();

View 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();

View 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]);
}

View 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();

View 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;
}

View File

@ -28,7 +28,7 @@
class GaussianXBlurOperation : public BlurBaseOperation {
private:
float *m_gausstab;
int m_rad;
int m_filtersize;
void updateGauss();
public:
GaussianXBlurOperation();

View 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();

View File

@ -28,7 +28,7 @@
class GaussianYBlurOperation : public BlurBaseOperation {
private:
float *m_gausstab;
int m_rad;
int m_filtersize;
void updateGauss();
public:
GaussianYBlurOperation();