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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/compositor/operations/COM_DilateErodeOperation.cpp
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/compositor/operations/COM_DilateErodeOperation.cpp')
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cpp852
1 files changed, 432 insertions, 420 deletions
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
index 2e2888052b2..7cf1086dca1 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
@@ -25,532 +25,544 @@
// DilateErode Distance Threshold
DilateErodeThresholdOperation::DilateErodeThresholdOperation() : NodeOperation()
{
- this->addInputSocket(COM_DT_VALUE);
- this->addOutputSocket(COM_DT_VALUE);
- this->setComplex(true);
- this->m_inputProgram = NULL;
- this->m_inset = 0.0f;
- this->m__switch = 0.5f;
- this->m_distance = 0.0f;
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_VALUE);
+ this->setComplex(true);
+ this->m_inputProgram = NULL;
+ this->m_inset = 0.0f;
+ this->m__switch = 0.5f;
+ this->m_distance = 0.0f;
}
void DilateErodeThresholdOperation::initExecution()
{
- this->m_inputProgram = this->getInputSocketReader(0);
- if (this->m_distance < 0.0f) {
- this->m_scope = -this->m_distance + this->m_inset;
- }
- else {
- if (this->m_inset * 2 > this->m_distance) {
- this->m_scope = max(this->m_inset * 2 - this->m_distance, this->m_distance);
- }
- else {
- this->m_scope = this->m_distance;
- }
- }
- if (this->m_scope < 3) {
- this->m_scope = 3;
- }
+ this->m_inputProgram = this->getInputSocketReader(0);
+ if (this->m_distance < 0.0f) {
+ this->m_scope = -this->m_distance + this->m_inset;
+ }
+ else {
+ if (this->m_inset * 2 > this->m_distance) {
+ this->m_scope = max(this->m_inset * 2 - this->m_distance, this->m_distance);
+ }
+ else {
+ this->m_scope = this->m_distance;
+ }
+ }
+ if (this->m_scope < 3) {
+ this->m_scope = 3;
+ }
}
void *DilateErodeThresholdOperation::initializeTileData(rcti * /*rect*/)
{
- void *buffer = this->m_inputProgram->initializeTileData(NULL);
- return buffer;
+ void *buffer = this->m_inputProgram->initializeTileData(NULL);
+ return buffer;
}
void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y, void *data)
{
- float inputValue[4];
- const float sw = this->m__switch;
- const float distance = this->m_distance;
- float pixelvalue;
- const float rd = this->m_scope * this->m_scope;
- const float inset = this->m_inset;
- float mindist = rd * 2;
-
- MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
- float *buffer = inputBuffer->getBuffer();
- rcti *rect = inputBuffer->getRect();
- const int minx = max(x - this->m_scope, rect->xmin);
- const int miny = max(y - this->m_scope, rect->ymin);
- const int maxx = min(x + this->m_scope, rect->xmax);
- const int maxy = min(y + this->m_scope, rect->ymax);
- const int bufferWidth = BLI_rcti_size_x(rect);
- int offset;
-
- inputBuffer->read(inputValue, x, y);
- if (inputValue[0] > sw) {
- for (int yi = miny; yi < maxy; yi++) {
- const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
- for (int xi = minx; xi < maxx; xi++) {
- if (buffer[offset] < sw) {
- const float dx = xi - x;
- const float dis = dx * dx + dy * dy;
- mindist = min(mindist, dis);
- }
- offset ++;
- }
- }
- pixelvalue = -sqrtf(mindist);
- }
- else {
- for (int yi = miny; yi < maxy; yi++) {
- const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
- for (int xi = minx; xi < maxx; xi++) {
- if (buffer[offset] > sw) {
- const float dx = xi - x;
- const float dis = dx * dx + dy * dy;
- mindist = min(mindist, dis);
- }
- offset ++;
- }
- }
- pixelvalue = sqrtf(mindist);
- }
-
- if (distance > 0.0f) {
- const float delta = distance - pixelvalue;
- if (delta >= 0.0f) {
- if (delta >= inset) {
- output[0] = 1.0f;
- }
- else {
- output[0] = delta / inset;
- }
- }
- else {
- output[0] = 0.0f;
- }
- }
- else {
- const float delta = -distance + pixelvalue;
- if (delta < 0.0f) {
- if (delta < -inset) {
- output[0] = 1.0f;
- }
- else {
- output[0] = (-delta) / inset;
- }
- }
- else {
- output[0] = 0.0f;
- }
- }
+ float inputValue[4];
+ const float sw = this->m__switch;
+ const float distance = this->m_distance;
+ float pixelvalue;
+ const float rd = this->m_scope * this->m_scope;
+ const float inset = this->m_inset;
+ float mindist = rd * 2;
+
+ MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
+ float *buffer = inputBuffer->getBuffer();
+ rcti *rect = inputBuffer->getRect();
+ const int minx = max(x - this->m_scope, rect->xmin);
+ const int miny = max(y - this->m_scope, rect->ymin);
+ const int maxx = min(x + this->m_scope, rect->xmax);
+ const int maxy = min(y + this->m_scope, rect->ymax);
+ const int bufferWidth = BLI_rcti_size_x(rect);
+ int offset;
+
+ inputBuffer->read(inputValue, x, y);
+ if (inputValue[0] > sw) {
+ for (int yi = miny; yi < maxy; yi++) {
+ const float dy = yi - y;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
+ for (int xi = minx; xi < maxx; xi++) {
+ if (buffer[offset] < sw) {
+ const float dx = xi - x;
+ const float dis = dx * dx + dy * dy;
+ mindist = min(mindist, dis);
+ }
+ offset++;
+ }
+ }
+ pixelvalue = -sqrtf(mindist);
+ }
+ else {
+ for (int yi = miny; yi < maxy; yi++) {
+ const float dy = yi - y;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
+ for (int xi = minx; xi < maxx; xi++) {
+ if (buffer[offset] > sw) {
+ const float dx = xi - x;
+ const float dis = dx * dx + dy * dy;
+ mindist = min(mindist, dis);
+ }
+ offset++;
+ }
+ }
+ pixelvalue = sqrtf(mindist);
+ }
+
+ if (distance > 0.0f) {
+ const float delta = distance - pixelvalue;
+ if (delta >= 0.0f) {
+ if (delta >= inset) {
+ output[0] = 1.0f;
+ }
+ else {
+ output[0] = delta / inset;
+ }
+ }
+ else {
+ output[0] = 0.0f;
+ }
+ }
+ else {
+ const float delta = -distance + pixelvalue;
+ if (delta < 0.0f) {
+ if (delta < -inset) {
+ output[0] = 1.0f;
+ }
+ else {
+ output[0] = (-delta) / inset;
+ }
+ }
+ else {
+ output[0] = 0.0f;
+ }
+ }
}
void DilateErodeThresholdOperation::deinitExecution()
{
- this->m_inputProgram = NULL;
+ this->m_inputProgram = NULL;
}
-bool DilateErodeThresholdOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+bool DilateErodeThresholdOperation::determineDependingAreaOfInterest(
+ rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- rcti newInput;
+ rcti newInput;
- newInput.xmax = input->xmax + this->m_scope;
- newInput.xmin = input->xmin - this->m_scope;
- newInput.ymax = input->ymax + this->m_scope;
- newInput.ymin = input->ymin - this->m_scope;
+ newInput.xmax = input->xmax + this->m_scope;
+ newInput.xmin = input->xmin - this->m_scope;
+ newInput.ymax = input->ymax + this->m_scope;
+ newInput.ymin = input->ymin - this->m_scope;
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
// Dilate Distance
DilateDistanceOperation::DilateDistanceOperation() : NodeOperation()
{
- this->addInputSocket(COM_DT_VALUE);
- this->addOutputSocket(COM_DT_VALUE);
- this->setComplex(true);
- this->m_inputProgram = NULL;
- this->m_distance = 0.0f;
- this->setOpenCL(true);
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_VALUE);
+ this->setComplex(true);
+ this->m_inputProgram = NULL;
+ this->m_distance = 0.0f;
+ this->setOpenCL(true);
}
void DilateDistanceOperation::initExecution()
{
- this->m_inputProgram = this->getInputSocketReader(0);
- this->m_scope = this->m_distance;
- if (this->m_scope < 3) {
- this->m_scope = 3;
- }
+ this->m_inputProgram = this->getInputSocketReader(0);
+ this->m_scope = this->m_distance;
+ if (this->m_scope < 3) {
+ this->m_scope = 3;
+ }
}
void *DilateDistanceOperation::initializeTileData(rcti * /*rect*/)
{
- void *buffer = this->m_inputProgram->initializeTileData(NULL);
- return buffer;
+ void *buffer = this->m_inputProgram->initializeTileData(NULL);
+ return buffer;
}
void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *data)
{
- const float distance = this->m_distance;
- const float mindist = distance * distance;
-
- MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
- float *buffer = inputBuffer->getBuffer();
- rcti *rect = inputBuffer->getRect();
- const int minx = max(x - this->m_scope, rect->xmin);
- const int miny = max(y - this->m_scope, rect->ymin);
- const int maxx = min(x + this->m_scope, rect->xmax);
- const int maxy = min(y + this->m_scope, rect->ymax);
- const int bufferWidth = BLI_rcti_size_x(rect);
- int offset;
-
- float value = 0.0f;
-
- for (int yi = miny; yi < maxy; yi++) {
- const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
- for (int xi = minx; xi < maxx; xi++) {
- const float dx = xi - x;
- const float dis = dx * dx + dy * dy;
- if (dis <= mindist) {
- value = max(buffer[offset], value);
- }
- offset ++;
- }
- }
- output[0] = value;
+ const float distance = this->m_distance;
+ const float mindist = distance * distance;
+
+ MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
+ float *buffer = inputBuffer->getBuffer();
+ rcti *rect = inputBuffer->getRect();
+ const int minx = max(x - this->m_scope, rect->xmin);
+ const int miny = max(y - this->m_scope, rect->ymin);
+ const int maxx = min(x + this->m_scope, rect->xmax);
+ const int maxy = min(y + this->m_scope, rect->ymax);
+ const int bufferWidth = BLI_rcti_size_x(rect);
+ int offset;
+
+ float value = 0.0f;
+
+ for (int yi = miny; yi < maxy; yi++) {
+ const float dy = yi - y;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
+ for (int xi = minx; xi < maxx; xi++) {
+ const float dx = xi - x;
+ const float dis = dx * dx + dy * dy;
+ if (dis <= mindist) {
+ value = max(buffer[offset], value);
+ }
+ offset++;
+ }
+ }
+ output[0] = value;
}
void DilateDistanceOperation::deinitExecution()
{
- this->m_inputProgram = NULL;
+ this->m_inputProgram = NULL;
}
-bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input,
+ ReadBufferOperation *readOperation,
+ rcti *output)
{
- rcti newInput;
+ rcti newInput;
- newInput.xmax = input->xmax + this->m_scope;
- newInput.xmin = input->xmin - this->m_scope;
- newInput.ymax = input->ymax + this->m_scope;
- newInput.ymin = input->ymin - this->m_scope;
+ newInput.xmax = input->xmax + this->m_scope;
+ newInput.xmin = input->xmin - this->m_scope;
+ newInput.ymax = input->ymax + this->m_scope;
+ newInput.ymin = input->ymin - this->m_scope;
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
void DilateDistanceOperation::executeOpenCL(OpenCLDevice *device,
- MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer,
- MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp,
+ MemoryBuffer *outputMemoryBuffer,
+ cl_mem clOutputBuffer,
+ MemoryBuffer **inputMemoryBuffers,
+ list<cl_mem> *clMemToCleanUp,
list<cl_kernel> * /*clKernelsToCleanUp*/)
{
- cl_kernel dilateKernel = device->COM_clCreateKernel("dilateKernel", NULL);
-
- cl_int distanceSquared = this->m_distance * this->m_distance;
- cl_int scope = this->m_scope;
-
- device->COM_clAttachMemoryBufferToKernelParameter(dilateKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
- device->COM_clAttachOutputMemoryBufferToKernelParameter(dilateKernel, 1, clOutputBuffer);
- device->COM_clAttachMemoryBufferOffsetToKernelParameter(dilateKernel, 3, outputMemoryBuffer);
- clSetKernelArg(dilateKernel, 4, sizeof(cl_int), &scope);
- clSetKernelArg(dilateKernel, 5, sizeof(cl_int), &distanceSquared);
- device->COM_clAttachSizeToKernelParameter(dilateKernel, 6, this);
- device->COM_clEnqueueRange(dilateKernel, outputMemoryBuffer, 7, this);
+ cl_kernel dilateKernel = device->COM_clCreateKernel("dilateKernel", NULL);
+
+ cl_int distanceSquared = this->m_distance * this->m_distance;
+ cl_int scope = this->m_scope;
+
+ device->COM_clAttachMemoryBufferToKernelParameter(
+ dilateKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
+ device->COM_clAttachOutputMemoryBufferToKernelParameter(dilateKernel, 1, clOutputBuffer);
+ device->COM_clAttachMemoryBufferOffsetToKernelParameter(dilateKernel, 3, outputMemoryBuffer);
+ clSetKernelArg(dilateKernel, 4, sizeof(cl_int), &scope);
+ clSetKernelArg(dilateKernel, 5, sizeof(cl_int), &distanceSquared);
+ device->COM_clAttachSizeToKernelParameter(dilateKernel, 6, this);
+ device->COM_clEnqueueRange(dilateKernel, outputMemoryBuffer, 7, this);
}
// Erode Distance
ErodeDistanceOperation::ErodeDistanceOperation() : DilateDistanceOperation()
{
- /* pass */
+ /* pass */
}
void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *data)
{
- const float distance = this->m_distance;
- const float mindist = distance * distance;
-
- MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
- float *buffer = inputBuffer->getBuffer();
- rcti *rect = inputBuffer->getRect();
- const int minx = max(x - this->m_scope, rect->xmin);
- const int miny = max(y - this->m_scope, rect->ymin);
- const int maxx = min(x + this->m_scope, rect->xmax);
- const int maxy = min(y + this->m_scope, rect->ymax);
- const int bufferWidth = BLI_rcti_size_x(rect);
- int offset;
-
- float value = 1.0f;
-
- for (int yi = miny; yi < maxy; yi++) {
- const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
- for (int xi = minx; xi < maxx; xi++) {
- const float dx = xi - x;
- const float dis = dx * dx + dy * dy;
- if (dis <= mindist) {
- value = min(buffer[offset], value);
- }
- offset ++;
- }
- }
- output[0] = value;
+ const float distance = this->m_distance;
+ const float mindist = distance * distance;
+
+ MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
+ float *buffer = inputBuffer->getBuffer();
+ rcti *rect = inputBuffer->getRect();
+ const int minx = max(x - this->m_scope, rect->xmin);
+ const int miny = max(y - this->m_scope, rect->ymin);
+ const int maxx = min(x + this->m_scope, rect->xmax);
+ const int maxy = min(y + this->m_scope, rect->ymax);
+ const int bufferWidth = BLI_rcti_size_x(rect);
+ int offset;
+
+ float value = 1.0f;
+
+ for (int yi = miny; yi < maxy; yi++) {
+ const float dy = yi - y;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
+ for (int xi = minx; xi < maxx; xi++) {
+ const float dx = xi - x;
+ const float dis = dx * dx + dy * dy;
+ if (dis <= mindist) {
+ value = min(buffer[offset], value);
+ }
+ offset++;
+ }
+ }
+ output[0] = value;
}
void ErodeDistanceOperation::executeOpenCL(OpenCLDevice *device,
- MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer,
- MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp,
+ MemoryBuffer *outputMemoryBuffer,
+ cl_mem clOutputBuffer,
+ MemoryBuffer **inputMemoryBuffers,
+ list<cl_mem> *clMemToCleanUp,
list<cl_kernel> * /*clKernelsToCleanUp*/)
{
- cl_kernel erodeKernel = device->COM_clCreateKernel("erodeKernel", NULL);
-
- cl_int distanceSquared = this->m_distance * this->m_distance;
- cl_int scope = this->m_scope;
-
- device->COM_clAttachMemoryBufferToKernelParameter(erodeKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
- device->COM_clAttachOutputMemoryBufferToKernelParameter(erodeKernel, 1, clOutputBuffer);
- device->COM_clAttachMemoryBufferOffsetToKernelParameter(erodeKernel, 3, outputMemoryBuffer);
- clSetKernelArg(erodeKernel, 4, sizeof(cl_int), &scope);
- clSetKernelArg(erodeKernel, 5, sizeof(cl_int), &distanceSquared);
- device->COM_clAttachSizeToKernelParameter(erodeKernel, 6, this);
- device->COM_clEnqueueRange(erodeKernel, outputMemoryBuffer, 7, this);
+ cl_kernel erodeKernel = device->COM_clCreateKernel("erodeKernel", NULL);
+
+ cl_int distanceSquared = this->m_distance * this->m_distance;
+ cl_int scope = this->m_scope;
+
+ device->COM_clAttachMemoryBufferToKernelParameter(
+ erodeKernel, 0, 2, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
+ device->COM_clAttachOutputMemoryBufferToKernelParameter(erodeKernel, 1, clOutputBuffer);
+ device->COM_clAttachMemoryBufferOffsetToKernelParameter(erodeKernel, 3, outputMemoryBuffer);
+ clSetKernelArg(erodeKernel, 4, sizeof(cl_int), &scope);
+ clSetKernelArg(erodeKernel, 5, sizeof(cl_int), &distanceSquared);
+ device->COM_clAttachSizeToKernelParameter(erodeKernel, 6, this);
+ device->COM_clEnqueueRange(erodeKernel, outputMemoryBuffer, 7, this);
}
// Dilate step
DilateStepOperation::DilateStepOperation() : NodeOperation()
{
- this->addInputSocket(COM_DT_VALUE);
- this->addOutputSocket(COM_DT_VALUE);
- this->setComplex(true);
- this->m_inputProgram = NULL;
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_VALUE);
+ this->setComplex(true);
+ this->m_inputProgram = NULL;
}
void DilateStepOperation::initExecution()
{
- this->m_inputProgram = this->getInputSocketReader(0);
+ this->m_inputProgram = this->getInputSocketReader(0);
}
-
// small helper to pass data from initializeTileData to executePixel
typedef struct tile_info {
- rcti rect;
- int width;
- float *buffer;
+ rcti rect;
+ int width;
+ float *buffer;
} tile_info;
static tile_info *create_cache(int xmin, int xmax, int ymin, int ymax)
{
- tile_info *result = (tile_info *)MEM_mallocN(sizeof(tile_info), "dilate erode tile");
- result->rect.xmin = xmin;
- result->rect.xmax = xmax;
- result->rect.ymin = ymin;
- result->rect.ymax = ymax;
- result->width = xmax - xmin;
- result->buffer = (float *)MEM_callocN(sizeof(float) * (ymax - ymin) * result->width, "dilate erode cache");
- return result;
+ tile_info *result = (tile_info *)MEM_mallocN(sizeof(tile_info), "dilate erode tile");
+ result->rect.xmin = xmin;
+ result->rect.xmax = xmax;
+ result->rect.ymin = ymin;
+ result->rect.ymax = ymax;
+ result->width = xmax - xmin;
+ result->buffer = (float *)MEM_callocN(sizeof(float) * (ymax - ymin) * result->width,
+ "dilate erode cache");
+ return result;
}
void *DilateStepOperation::initializeTileData(rcti *rect)
{
- MemoryBuffer *tile = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
- int x, y, i;
- int width = tile->getWidth();
- int height = tile->getHeight();
- float *buffer = tile->getBuffer();
-
- int half_window = this->m_iterations;
- int window = half_window * 2 + 1;
-
- int xmin = max(0, rect->xmin - half_window);
- int ymin = max(0, rect->ymin - half_window);
- int xmax = min(width, rect->xmax + half_window);
- int ymax = min(height, rect->ymax + half_window);
-
- int bwidth = rect->xmax - rect->xmin;
- int bheight = rect->ymax - rect->ymin;
-
- // Note: Cache buffer has original tilesize width, but new height.
- // We have to calculate the additional rows in the first pass,
- // to have valid data available for the second pass.
- tile_info *result = create_cache(rect->xmin, rect->xmax, ymin, ymax);
- float *rectf = result->buffer;
-
- // temp holds maxima for every step in the algorithm, buf holds a
- // single row or column of input values, padded with FLT_MAX's to
- // simplify the logic.
- float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
- float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window), "dilate erode buf");
-
- // The following is based on the van Herk/Gil-Werman algorithm for morphology operations.
- // first pass, horizontal dilate/erode
- for (y = ymin; y < ymax; y++) {
- for (x = 0; x < bwidth + 5 * half_window; x++) {
- buf[x] = -FLT_MAX;
- }
- for (x = xmin; x < xmax; ++x) {
- buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
- }
-
- for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
- int start = (i + 1) * window - 1;
-
- temp[window - 1] = buf[start];
- for (x = 1; x < window; x++) {
- temp[window - 1 - x] = max(temp[window - x], buf[start - x]);
- temp[window - 1 + x] = max(temp[window + x - 2], buf[start + x]);
- }
-
- start = half_window + (i - 1) * window + 1;
- for (x = -min(0, start); x < window - max(0, start + window - bwidth); x++) {
- rectf[bwidth * (y - ymin) + (start + x)] = max(temp[x], temp[x + window - 1]);
- }
- }
- }
-
- // second pass, vertical dilate/erode
- for (x = 0; x < bwidth; x++) {
- for (y = 0; y < bheight + 5 * half_window; y++) {
- buf[y] = -FLT_MAX;
- }
- for (y = ymin; y < ymax; y++) {
- buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
- }
-
- for (i = 0; i < (bheight + 3 * half_window) / window; i++) {
- int start = (i + 1) * window - 1;
-
- temp[window - 1] = buf[start];
- for (y = 1; y < window; y++) {
- temp[window - 1 - y] = max(temp[window - y], buf[start - y]);
- temp[window - 1 + y] = max(temp[window + y - 2], buf[start + y]);
- }
-
- start = half_window + (i - 1) * window + 1;
- for (y = -min(0, start); y < window - max(0, start + window - bheight); y++) {
- rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = max(temp[y], temp[y + window - 1]);
- }
- }
- }
-
- MEM_freeN(temp);
- MEM_freeN(buf);
-
- return result;
+ MemoryBuffer *tile = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
+ int x, y, i;
+ int width = tile->getWidth();
+ int height = tile->getHeight();
+ float *buffer = tile->getBuffer();
+
+ int half_window = this->m_iterations;
+ int window = half_window * 2 + 1;
+
+ int xmin = max(0, rect->xmin - half_window);
+ int ymin = max(0, rect->ymin - half_window);
+ int xmax = min(width, rect->xmax + half_window);
+ int ymax = min(height, rect->ymax + half_window);
+
+ int bwidth = rect->xmax - rect->xmin;
+ int bheight = rect->ymax - rect->ymin;
+
+ // Note: Cache buffer has original tilesize width, but new height.
+ // We have to calculate the additional rows in the first pass,
+ // to have valid data available for the second pass.
+ tile_info *result = create_cache(rect->xmin, rect->xmax, ymin, ymax);
+ float *rectf = result->buffer;
+
+ // temp holds maxima for every step in the algorithm, buf holds a
+ // single row or column of input values, padded with FLT_MAX's to
+ // simplify the logic.
+ float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
+ float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window),
+ "dilate erode buf");
+
+ // The following is based on the van Herk/Gil-Werman algorithm for morphology operations.
+ // first pass, horizontal dilate/erode
+ for (y = ymin; y < ymax; y++) {
+ for (x = 0; x < bwidth + 5 * half_window; x++) {
+ buf[x] = -FLT_MAX;
+ }
+ for (x = xmin; x < xmax; ++x) {
+ buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
+ }
+
+ for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (x = 1; x < window; x++) {
+ temp[window - 1 - x] = max(temp[window - x], buf[start - x]);
+ temp[window - 1 + x] = max(temp[window + x - 2], buf[start + x]);
+ }
+
+ start = half_window + (i - 1) * window + 1;
+ for (x = -min(0, start); x < window - max(0, start + window - bwidth); x++) {
+ rectf[bwidth * (y - ymin) + (start + x)] = max(temp[x], temp[x + window - 1]);
+ }
+ }
+ }
+
+ // second pass, vertical dilate/erode
+ for (x = 0; x < bwidth; x++) {
+ for (y = 0; y < bheight + 5 * half_window; y++) {
+ buf[y] = -FLT_MAX;
+ }
+ for (y = ymin; y < ymax; y++) {
+ buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
+ }
+
+ for (i = 0; i < (bheight + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (y = 1; y < window; y++) {
+ temp[window - 1 - y] = max(temp[window - y], buf[start - y]);
+ temp[window - 1 + y] = max(temp[window + y - 2], buf[start + y]);
+ }
+
+ start = half_window + (i - 1) * window + 1;
+ for (y = -min(0, start); y < window - max(0, start + window - bheight); y++) {
+ rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = max(temp[y], temp[y + window - 1]);
+ }
+ }
+ }
+
+ MEM_freeN(temp);
+ MEM_freeN(buf);
+
+ return result;
}
-
void DilateStepOperation::executePixel(float output[4], int x, int y, void *data)
{
- tile_info *tile = (tile_info *)data;
- int nx = x - tile->rect.xmin;
- int ny = y - tile->rect.ymin;
- output[0] = tile->buffer[tile->width * ny + nx];
+ tile_info *tile = (tile_info *)data;
+ int nx = x - tile->rect.xmin;
+ int ny = y - tile->rect.ymin;
+ output[0] = tile->buffer[tile->width * ny + nx];
}
void DilateStepOperation::deinitExecution()
{
- this->m_inputProgram = NULL;
+ this->m_inputProgram = NULL;
}
void DilateStepOperation::deinitializeTileData(rcti * /*rect*/, void *data)
{
- tile_info *tile = (tile_info *)data;
- MEM_freeN(tile->buffer);
- MEM_freeN(tile);
+ tile_info *tile = (tile_info *)data;
+ MEM_freeN(tile->buffer);
+ MEM_freeN(tile);
}
-bool DilateStepOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+bool DilateStepOperation::determineDependingAreaOfInterest(rcti *input,
+ ReadBufferOperation *readOperation,
+ rcti *output)
{
- rcti newInput;
- int it = this->m_iterations;
- newInput.xmax = input->xmax + it;
- newInput.xmin = input->xmin - it;
- newInput.ymax = input->ymax + it;
- newInput.ymin = input->ymin - it;
-
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+ rcti newInput;
+ int it = this->m_iterations;
+ newInput.xmax = input->xmax + it;
+ newInput.xmin = input->xmin - it;
+ newInput.ymax = input->ymax + it;
+ newInput.ymin = input->ymin - it;
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
// Erode step
ErodeStepOperation::ErodeStepOperation() : DilateStepOperation()
{
- /* pass */
+ /* pass */
}
void *ErodeStepOperation::initializeTileData(rcti *rect)
{
- MemoryBuffer *tile = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
- int x, y, i;
- int width = tile->getWidth();
- int height = tile->getHeight();
- float *buffer = tile->getBuffer();
-
- int half_window = this->m_iterations;
- int window = half_window * 2 + 1;
-
- int xmin = max(0, rect->xmin - half_window);
- int ymin = max(0, rect->ymin - half_window);
- int xmax = min(width, rect->xmax + half_window);
- int ymax = min(height, rect->ymax + half_window);
-
- int bwidth = rect->xmax - rect->xmin;
- int bheight = rect->ymax - rect->ymin;
-
- // Note: Cache buffer has original tilesize width, but new height.
- // We have to calculate the additional rows in the first pass,
- // to have valid data available for the second pass.
- tile_info *result = create_cache(rect->xmin, rect->xmax, ymin, ymax);
- float *rectf = result->buffer;
-
- // temp holds maxima for every step in the algorithm, buf holds a
- // single row or column of input values, padded with FLT_MAX's to
- // simplify the logic.
- float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
- float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window), "dilate erode buf");
-
- // The following is based on the van Herk/Gil-Werman algorithm for morphology operations.
- // first pass, horizontal dilate/erode
- for (y = ymin; y < ymax; y++) {
- for (x = 0; x < bwidth + 5 * half_window; x++) {
- buf[x] = FLT_MAX;
- }
- for (x = xmin; x < xmax; ++x) {
- buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
- }
-
- for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
- int start = (i + 1) * window - 1;
-
- temp[window - 1] = buf[start];
- for (x = 1; x < window; x++) {
- temp[window - 1 - x] = min(temp[window - x], buf[start - x]);
- temp[window - 1 + x] = min(temp[window + x - 2], buf[start + x]);
- }
-
- start = half_window + (i - 1) * window + 1;
- for (x = -min(0, start); x < window - max(0, start + window - bwidth); x++) {
- rectf[bwidth * (y - ymin) + (start + x)] = min(temp[x], temp[x + window - 1]);
- }
- }
- }
-
- // second pass, vertical dilate/erode
- for (x = 0; x < bwidth; x++) {
- for (y = 0; y < bheight + 5 * half_window; y++) {
- buf[y] = FLT_MAX;
- }
- for (y = ymin; y < ymax; y++) {
- buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
- }
-
- for (i = 0; i < (bheight + 3 * half_window) / window; i++) {
- int start = (i + 1) * window - 1;
-
- temp[window - 1] = buf[start];
- for (y = 1; y < window; y++) {
- temp[window - 1 - y] = min(temp[window - y], buf[start - y]);
- temp[window - 1 + y] = min(temp[window + y - 2], buf[start + y]);
- }
-
- start = half_window + (i - 1) * window + 1;
- for (y = -min(0, start); y < window - max(0, start + window - bheight); y++) {
- rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = min(temp[y], temp[y + window - 1]);
- }
- }
- }
-
- MEM_freeN(temp);
- MEM_freeN(buf);
-
- return result;
+ MemoryBuffer *tile = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
+ int x, y, i;
+ int width = tile->getWidth();
+ int height = tile->getHeight();
+ float *buffer = tile->getBuffer();
+
+ int half_window = this->m_iterations;
+ int window = half_window * 2 + 1;
+
+ int xmin = max(0, rect->xmin - half_window);
+ int ymin = max(0, rect->ymin - half_window);
+ int xmax = min(width, rect->xmax + half_window);
+ int ymax = min(height, rect->ymax + half_window);
+
+ int bwidth = rect->xmax - rect->xmin;
+ int bheight = rect->ymax - rect->ymin;
+
+ // Note: Cache buffer has original tilesize width, but new height.
+ // We have to calculate the additional rows in the first pass,
+ // to have valid data available for the second pass.
+ tile_info *result = create_cache(rect->xmin, rect->xmax, ymin, ymax);
+ float *rectf = result->buffer;
+
+ // temp holds maxima for every step in the algorithm, buf holds a
+ // single row or column of input values, padded with FLT_MAX's to
+ // simplify the logic.
+ float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
+ float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window),
+ "dilate erode buf");
+
+ // The following is based on the van Herk/Gil-Werman algorithm for morphology operations.
+ // first pass, horizontal dilate/erode
+ for (y = ymin; y < ymax; y++) {
+ for (x = 0; x < bwidth + 5 * half_window; x++) {
+ buf[x] = FLT_MAX;
+ }
+ for (x = xmin; x < xmax; ++x) {
+ buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
+ }
+
+ for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (x = 1; x < window; x++) {
+ temp[window - 1 - x] = min(temp[window - x], buf[start - x]);
+ temp[window - 1 + x] = min(temp[window + x - 2], buf[start + x]);
+ }
+
+ start = half_window + (i - 1) * window + 1;
+ for (x = -min(0, start); x < window - max(0, start + window - bwidth); x++) {
+ rectf[bwidth * (y - ymin) + (start + x)] = min(temp[x], temp[x + window - 1]);
+ }
+ }
+ }
+
+ // second pass, vertical dilate/erode
+ for (x = 0; x < bwidth; x++) {
+ for (y = 0; y < bheight + 5 * half_window; y++) {
+ buf[y] = FLT_MAX;
+ }
+ for (y = ymin; y < ymax; y++) {
+ buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
+ }
+
+ for (i = 0; i < (bheight + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (y = 1; y < window; y++) {
+ temp[window - 1 - y] = min(temp[window - y], buf[start - y]);
+ temp[window - 1 + y] = min(temp[window + y - 2], buf[start + y]);
+ }
+
+ start = half_window + (i - 1) * window + 1;
+ for (y = -min(0, start); y < window - max(0, start + window - bheight); y++) {
+ rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = min(temp[y], temp[y + window - 1]);
+ }
+ }
+ }
+
+ MEM_freeN(temp);
+ MEM_freeN(buf);
+
+ return result;
}