summaryrefslogtreecommitdiff
path: root/src/mesa/main/convolve.c
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2000-08-22 18:54:25 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2000-08-22 18:54:25 +0000
commit7e70874420266fb81bed13c8464ee4c0309d75b2 (patch)
tree449b8783c51813fdb283ec44ed8b6ad3a7e24d4e /src/mesa/main/convolve.c
parentb5b5c52034840dbfcd3f76a9e7cde8b379e7d517 (diff)
finished separable filter functions
Diffstat (limited to 'src/mesa/main/convolve.c')
-rw-r--r--src/mesa/main/convolve.c166
1 files changed, 86 insertions, 80 deletions
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
index 541cfb6ce1..3471220dc7 100644
--- a/src/mesa/main/convolve.c
+++ b/src/mesa/main/convolve.c
@@ -1,4 +1,4 @@
-/* $Id: convolve.c,v 1.2 2000/08/21 14:24:30 brianp Exp $ */
+/* $Id: convolve.c,v 1.3 2000/08/22 18:54:25 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -48,9 +48,14 @@ convolve_1d_reduce(GLint srcWidth, const GLfloat src[][4],
GLint filterWidth, const GLfloat filter[][4],
GLfloat dest[][4])
{
- const GLint dstWidth = srcWidth - (filterWidth - 1);
+ GLint dstWidth;
GLint i, n;
+ if (filterWidth >= 1)
+ dstWidth = srcWidth - (filterWidth - 1);
+ else
+ dstWidth = srcWidth;
+
if (dstWidth <= 0)
return; /* null result */
@@ -157,10 +162,19 @@ convolve_2d_reduce(GLint srcWidth, GLint srcHeight,
const GLfloat filter[][4],
GLfloat dest[][4])
{
- const GLint dstWidth = srcWidth - (filterWidth - 1);
- const GLint dstHeight = srcHeight - (filterHeight - 1);
+ GLint dstWidth, dstHeight;
GLint i, j, n, m;
+ if (filterWidth >= 1)
+ dstWidth = srcWidth - (filterWidth - 1);
+ else
+ dstWidth = srcWidth;
+
+ if (filterHeight >= 1)
+ dstHeight = srcHeight - (filterHeight - 1);
+ else
+ dstHeight = srcHeight;
+
if (dstWidth <= 0 || dstHeight <= 0)
return;
@@ -201,13 +215,6 @@ convolve_2d_constant(GLint srcWidth, GLint srcHeight,
const GLint halfFilterHeight = filterHeight / 2;
GLint i, j, n, m;
- {
- for (i=0;i<filterWidth*filterHeight;i++){
- printf("%d %f %f %f %f\n", i,
- filter[i][0], filter[i][1], filter[i][2], filter[i][3]);
- }
- }
-
for (j = 0; j < srcHeight; j++) {
for (i = 0; i < srcWidth; i++) {
GLfloat sumR = 0.0;
@@ -299,41 +306,43 @@ convolve_sep_reduce(GLint srcWidth, GLint srcHeight,
const GLfloat colFilt[][4],
GLfloat dest[][4])
{
- const GLint halfFilterWidth = filterWidth / 2;
- const GLint halfFilterHeight = filterHeight / 2;
+ GLint dstWidth, dstHeight;
GLint i, j, n, m;
-#if 0
- for (j = 0; j < srcHeight; j++) {
- for (i = 0; i < srcWidth; i++) {
+
+ if (filterWidth >= 1)
+ dstWidth = srcWidth - (filterWidth - 1);
+ else
+ dstWidth = srcWidth;
+
+ if (filterHeight >= 1)
+ dstHeight = srcHeight - (filterHeight - 1);
+ else
+ dstHeight = srcHeight;
+
+ if (dstWidth <= 0 || dstHeight <= 0)
+ return;
+
+ for (j = 0; j < dstHeight; j++) {
+ for (i = 0; i < dstWidth; i++) {
GLfloat sumR = 0.0;
GLfloat sumG = 0.0;
GLfloat sumB = 0.0;
GLfloat sumA = 0.0;
for (m = 0; m < filterHeight; m++) {
for (n = 0; n < filterWidth; n++) {
- if (i + n < halfFilterWidth ||
- i + n - halfFilterWidth >= srcWidth) {
- sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
- sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
- sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
- sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
- }
- else {
- const GLint k = m * srcWidth + i + n - halfFilterWidth;
- sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
- sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
- sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
- sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
- }
+ GLint k = (j + m) * srcWidth + i + n;
+ sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
+ sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
+ sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
+ sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
}
}
- dest[i][RCOMP] = sumR;
- dest[i][GCOMP] = sumG;
- dest[i][BCOMP] = sumB;
- dest[i][ACOMP] = sumA;
+ dest[j * dstWidth + i][RCOMP] = sumR;
+ dest[j * dstWidth + i][GCOMP] = sumG;
+ dest[j * dstWidth + i][BCOMP] = sumB;
+ dest[j * dstWidth + i][ACOMP] = sumA;
}
}
-#endif
}
@@ -349,7 +358,7 @@ convolve_sep_constant(GLint srcWidth, GLint srcHeight,
const GLint halfFilterWidth = filterWidth / 2;
const GLint halfFilterHeight = filterHeight / 2;
GLint i, j, n, m;
-#if 0
+
for (j = 0; j < srcHeight; j++) {
for (i = 0; i < srcWidth; i++) {
GLfloat sumR = 0.0;
@@ -358,29 +367,31 @@ convolve_sep_constant(GLint srcWidth, GLint srcHeight,
GLfloat sumA = 0.0;
for (m = 0; m < filterHeight; m++) {
for (n = 0; n < filterWidth; n++) {
- if (i + n < halfFilterWidth ||
- i + n - halfFilterWidth >= srcWidth) {
+ const GLint is = i + n - halfFilterWidth;
+ const GLint js = j + m - halfFilterHeight;
+ if (is < 0 || is >= srcWidth ||
+ js < 0 || js >= srcHeight) {
sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
}
else {
- const GLint k = m * srcWidth + i + n - halfFilterWidth;
+ GLint k = js * srcWidth + is;
sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
}
+
}
}
- dest[i][RCOMP] = sumR;
- dest[i][GCOMP] = sumG;
- dest[i][BCOMP] = sumB;
- dest[i][ACOMP] = sumA;
+ dest[j * srcWidth + i][RCOMP] = sumR;
+ dest[j * srcWidth + i][GCOMP] = sumG;
+ dest[j * srcWidth + i][BCOMP] = sumB;
+ dest[j * srcWidth + i][ACOMP] = sumA;
}
}
-#endif
}
@@ -404,33 +415,28 @@ convolve_sep_replicate(GLint srcWidth, GLint srcHeight,
GLfloat sumA = 0.0;
for (m = 0; m < filterHeight; m++) {
for (n = 0; n < filterWidth; n++) {
- if (i + n < halfFilterWidth) {
- const GLint k = m * srcWidth + 0;
- sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
- sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
- sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
- sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
- }
- else if (i + n - halfFilterWidth >= srcWidth) {
- const GLint k = m * srcWidth + srcWidth - 1;
- sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
- sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
- sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
- sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
- }
- else {
- const GLint k = m * srcWidth + i + n - halfFilterWidth;
- sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
- sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
- sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
- sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
- }
+ GLint is = i + n - halfFilterWidth;
+ GLint js = j + m - halfFilterHeight;
+ GLint k;
+ if (is < 0)
+ is = 0;
+ else if (is >= srcWidth)
+ is = srcWidth - 1;
+ if (js < 0)
+ js = 0;
+ else if (js >= srcHeight)
+ js = srcHeight - 1;
+ k = js * srcWidth + is;
+ sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
+ sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
+ sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
+ sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
}
}
- dest[i][RCOMP] = sumR;
- dest[i][GCOMP] = sumG;
- dest[i][BCOMP] = sumB;
- dest[i][ACOMP] = sumA;
+ dest[j * srcWidth + i][RCOMP] = sumR;
+ dest[j * srcWidth + i][GCOMP] = sumG;
+ dest[j * srcWidth + i][BCOMP] = sumB;
+ dest[j * srcWidth + i][ACOMP] = sumA;
}
}
}
@@ -447,7 +453,7 @@ _mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,
ctx->Convolution1D.Width,
(const GLfloat (*)[4]) ctx->Convolution1D.Filter,
(GLfloat (*)[4]) dstImage);
- *width -= (ctx->Convolution1D.Width - 1);
+ *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1);
break;
case GL_CONSTANT_BORDER:
convolve_1d_constant(*width, (const GLfloat (*)[4]) srcImage,
@@ -480,8 +486,8 @@ _mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,
ctx->Convolution2D.Height,
(const GLfloat (*)[4]) ctx->Convolution2D.Filter,
(GLfloat (*)[4]) dstImage);
- *width = *width - (ctx->Convolution2D.Width - 1);
- *height = *height - (ctx->Convolution2D.Height - 1);
+ *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1);
+ *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1);
break;
case GL_CONSTANT_BORDER:
convolve_2d_constant(*width, *height,
@@ -518,19 +524,19 @@ _mesa_convolve_sep_image(const GLcontext *ctx,
case GL_REDUCE:
convolve_sep_reduce(*width, *height,
(const GLfloat (*)[4]) srcImage,
- ctx->Convolution2D.Width,
- ctx->Convolution2D.Height,
+ ctx->Separable2D.Width,
+ ctx->Separable2D.Height,
(const GLfloat (*)[4]) rowFilter,
(const GLfloat (*)[4]) colFilter,
(GLfloat (*)[4]) dstImage);
- *width = *width - (ctx->Convolution2D.Width - 1);
- *height = *height - (ctx->Convolution2D.Height - 1);
+ *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1);
+ *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1);
break;
case GL_CONSTANT_BORDER:
convolve_sep_constant(*width, *height,
(const GLfloat (*)[4]) srcImage,
- ctx->Convolution2D.Width,
- ctx->Convolution2D.Height,
+ ctx->Separable2D.Width,
+ ctx->Separable2D.Height,
(const GLfloat (*)[4]) rowFilter,
(const GLfloat (*)[4]) colFilter,
(GLfloat (*)[4]) dstImage,
@@ -539,8 +545,8 @@ _mesa_convolve_sep_image(const GLcontext *ctx,
case GL_REPLICATE_BORDER:
convolve_sep_replicate(*width, *height,
(const GLfloat (*)[4]) srcImage,
- ctx->Convolution2D.Width,
- ctx->Convolution2D.Height,
+ ctx->Separable2D.Width,
+ ctx->Separable2D.Height,
(const GLfloat (*)[4]) rowFilter,
(const GLfloat (*)[4]) colFilter,
(GLfloat (*)[4]) dstImage);