void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *data) { float color_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float multiplier_accum = 0.0f; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); 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); 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) { const float multiplier = this->m_gausstab[index]; madd_v4_v4fl(color_accum, &buffer[bufferindex], multiplier); multiplier_accum += multiplier; bufferindex += offsetadd; } mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum); }
void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, void *data) { const bool do_invert = this->m_do_subtract; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; int bufferstarty = inputBuffer->getRect()->ymin; int miny = y; // int maxy = y; // UNUSED 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); // maxy = min(maxy, inputBuffer->getRect()->ymax); maxx = min(maxx, inputBuffer->getRect()->xmax); /* *** 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); /* gauss */ float alpha_accum = 0.0f; float multiplier_accum = 0.0f; /* dilate */ 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; float value = finv_test(buffer[bufferindex], do_invert); float multiplier; /* gauss */ { multiplier = this->m_gausstab[index]; alpha_accum += value * multiplier; multiplier_accum += multiplier; } /* dilate - find most extreme color */ if (value > value_max) { multiplier = this->m_distbuf_inv[index]; value *= multiplier; if (value > value_max) { value_max = value; distfacinv_max = multiplier; } } bufferindex += offsetadd; } /* blend between the max value and gauss blue - gives nice feather */ const float value_blur = alpha_accum / multiplier_accum; const float value_final = (value_max * distfacinv_max) + (value_blur * (1.0f - distfacinv_max)); output[0] = finv_test(value_final, do_invert); }
void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data) { float color_accum[4]; float tempBoundingBox[4]; float bokeh[4]; this->m_inputBoundingBoxReader->readSampled(tempBoundingBox, x, y, COM_PS_NEAREST); if (tempBoundingBox[0] > 0.0f) { float multiplier_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; int bufferstarty = inputBuffer->getRect()->ymin; const float max_dim = max(this->getWidth(), this->getHeight()); int pixelSize = this->m_size * max_dim / 100.0f; zero_v4(color_accum); if (pixelSize < 2) { this->m_inputProgram->readSampled(color_accum, x, y, COM_PS_NEAREST); multiplier_accum[0] = 1.0f; multiplier_accum[1] = 1.0f; multiplier_accum[2] = 1.0f; multiplier_accum[3] = 1.0f; } int miny = y - pixelSize; int maxy = y + pixelSize; int minx = x - pixelSize; int maxx = x + pixelSize; miny = max(miny, inputBuffer->getRect()->ymin); minx = max(minx, inputBuffer->getRect()->xmin); maxy = min(maxy, inputBuffer->getRect()->ymax); maxx = min(maxx, inputBuffer->getRect()->xmax); int step = getStep(); int offsetadd = getOffsetAdd() * COM_NUM_CHANNELS_COLOR; float m = this->m_bokehDimension / pixelSize; for (int ny = miny; ny < maxy; ny += step) { int bufferindex = ((minx - bufferstartx) * COM_NUM_CHANNELS_COLOR) + ((ny - bufferstarty) * COM_NUM_CHANNELS_COLOR * bufferwidth); for (int nx = minx; nx < maxx; nx += step) { float u = this->m_bokehMidX - (nx - x) * m; float v = this->m_bokehMidY - (ny - y) * m; this->m_inputBokehProgram->readSampled(bokeh, u, v, COM_PS_NEAREST); madd_v4_v4v4(color_accum, bokeh, &buffer[bufferindex]); add_v4_v4(multiplier_accum, bokeh); bufferindex += offsetadd; } } output[0] = color_accum[0] * (1.0f / multiplier_accum[0]); output[1] = color_accum[1] * (1.0f / multiplier_accum[1]); output[2] = color_accum[2] * (1.0f / multiplier_accum[2]); output[3] = color_accum[3] * (1.0f / multiplier_accum[3]); } else { this->m_inputProgram->readSampled(output, x, y, COM_PS_NEAREST); } }
void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *data) { float color_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float multiplier_accum = 0.0f; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); int bufferwidth = inputBuffer->getWidth(); int bufferstartx = inputBuffer->getRect()->xmin; int bufferstarty = inputBuffer->getRect()->ymin; 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 = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth); #ifdef __SSE2__ __m128 accum_r = _mm_load_ps(color_accum); for (int nx = xmin, index = (xmin - x) + this->m_filtersize; nx < xmax; nx += step, index += step) { __m128 reg_a = _mm_load_ps(&buffer[bufferindex]); reg_a = _mm_mul_ps(reg_a, this->m_gausstab_sse[index]); accum_r = _mm_add_ps(accum_r, reg_a); multiplier_accum += this->m_gausstab[index]; bufferindex += offsetadd; } _mm_store_ps(color_accum, accum_r); #else 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; bufferindex += offsetadd; } #endif mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum); }