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:
authorMonique Dewanchand <m.dewanchand@atmind.nl>2013-01-25 13:47:28 +0400
committerMonique Dewanchand <m.dewanchand@atmind.nl>2013-01-25 13:47:28 +0400
commit5d385b9a9a6f6981f849706397fd63d1511803ae (patch)
treee2af37cc53209efcc86ead60ef2042f16679d842 /source/blender/compositor/operations
parent204ec89bff751092f0ca97320456e49107b6e15f (diff)
committed patch [#33972] dilate/erode optimization
this patch optimizes the dilate/erode step method (hopefully without any functional change), making its speed not depend on the distance anymore. Couldn't detect funtional changes so committing. Haven't tested for speed gain. * credits to erwin94 David M
Diffstat (limited to 'source/blender/compositor/operations')
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cpp155
1 files changed, 111 insertions, 44 deletions
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
index f0fffa770f8..07b958cc335 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
@@ -337,38 +337,73 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
float *rectf = buffer->convertToValueBuffer();
int x, y, i;
- float *p;
int bwidth = buffer->getWidth();
int bheight = buffer->getHeight();
- for (i = 0; i < this->m_iterations; i++) {
- for (y = 0; y < bheight; y++) {
- for (x = 0; x < bwidth - 1; x++) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p + 1));
+
+ /*
+ The following is based on the van Herk/Gil-Werman algorithm for morphology operations.
+ */
+ int half_window = this->m_iterations;
+ int window = half_window * 2 + 1;
+ float *temp = (float *)MEM_mallocN((2*window - 1) * sizeof(float), "dilate erode temp");
+ float *buf = (float *)MEM_mallocN((max(bwidth, bheight) + 5*half_window) * sizeof(float), "dilate erode buf");
+
+ for (y = 0; y < bheight; y++) {
+ for (x = 0; x < window - 1; x++) {
+ buf[x] = -MAXFLOAT;
+ }
+ for (x = 0; x < bwidth; x++) {
+ buf[x + window - 1] = rectf[bwidth * y + x];
+ }
+ for (x = bwidth + window - 1; x < bwidth + 5*half_window; x++) {
+ buf[x] = -MAXFLOAT;
+ }
+
+ 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 + (start + x)] = max(temp[x], temp[x + window - 1]);
}
}
-
+ }
+
+ for (x = 0; x < bwidth; x++) {
+ for (y = 0; y < window - 1; y++) {
+ buf[y] = -MAXFLOAT;
+ }
for (y = 0; y < bheight; y++) {
- for (x = bwidth - 1; x >= 1; x--) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p - 1));
- }
+ buf[y + window - 1] = rectf[bwidth * y + x];
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = 0; y < bheight - 1; y++) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p + bwidth));
- }
+ for (y = bheight + window - 1; y < bheight + 5*half_window; y++) {
+ buf[y] = -MAXFLOAT;
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = bheight - 1; y >= 1; y--) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p - bwidth));
+
+ 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) + x] = max(temp[y], temp[y + window - 1]);
}
}
}
+
+ MEM_freeN(temp);
+ MEM_freeN(buf);
this->m_cached_buffer = rectf;
}
unlockMutex();
@@ -424,38 +459,70 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
float *rectf = buffer->convertToValueBuffer();
int x, y, i;
- float *p;
int bwidth = buffer->getWidth();
int bheight = buffer->getHeight();
- for (i = 0; i < this->m_iterations; i++) {
- for (y = 0; y < bheight; y++) {
- for (x = 0; x < bwidth - 1; x++) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p + 1));
+
+ int half_window = this->m_iterations;
+ int window = half_window * 2 + 1;
+ float *temp = (float *)MEM_mallocN((2*window - 1) * sizeof(float), "dilate erode temp");
+ float *buf = (float *)MEM_mallocN((max(bwidth, bheight) + 5*half_window) * sizeof(float), "dilate erode buf");
+
+ for (y = 0; y < bheight; y++) {
+ for (x = 0; x < window - 1; x++) {
+ buf[x] = MAXFLOAT;
+ }
+ for (x = 0; x < bwidth; x++) {
+ buf[x + window - 1] = rectf[bwidth * y + x];
+ }
+ for (x = bwidth + window - 1; x < bwidth + 5*half_window; x++) {
+ buf[x] = MAXFLOAT;
+ }
+
+ 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 + (start + x)] = min(temp[x], temp[x + window - 1]);
+ }
+ }
+ }
+
+ for (x = 0; x < bwidth; x++) {
+ for (y = 0; y < window - 1; y++) {
+ buf[y] = MAXFLOAT;
}
-
for (y = 0; y < bheight; y++) {
- for (x = bwidth - 1; x >= 1; x--) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p - 1));
- }
+ buf[y + window - 1] = rectf[bwidth * y + x];
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = 0; y < bheight - 1; y++) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p + bwidth));
- }
+ for (y = bheight + window - 1; y < bheight + 5*half_window; y++) {
+ buf[y] = MAXFLOAT;
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = bheight - 1; y >= 1; y--) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p - bwidth));
+
+ 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) + x] = min(temp[y], temp[y + window - 1]);
}
}
}
+
+ MEM_freeN(temp);
+ MEM_freeN(buf);
this->m_cached_buffer = rectf;
}
unlockMutex();