⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 convolve.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
                     GLint filterWidth, GLint filterHeight,                     const GLfloat filter[][4],                     GLfloat dest[][4],                     const GLfloat borderColor[4]){   const GLint halfFilterWidth = filterWidth / 2;   const GLint halfFilterHeight = filterHeight / 2;   GLint i, j, n, m;   for (j = 0; j < srcHeight; j++) {      for (i = 0; i < srcWidth; 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++) {               const GLint f = m * filterWidth + n;               const GLint is = i + n - halfFilterWidth;               const GLint js = j + m - halfFilterHeight;               if (is < 0 || is >= srcWidth ||                   js < 0 || js >= srcHeight) {                  sumR += borderColor[RCOMP] * filter[f][RCOMP];                  sumG += borderColor[GCOMP] * filter[f][GCOMP];                  sumB += borderColor[BCOMP] * filter[f][BCOMP];                  sumA += borderColor[ACOMP] * filter[f][ACOMP];               }               else {                  const GLint k = js * srcWidth + is;                  sumR += src[k][RCOMP] * filter[f][RCOMP];                  sumG += src[k][GCOMP] * filter[f][GCOMP];                  sumB += src[k][BCOMP] * filter[f][BCOMP];                  sumA += src[k][ACOMP] * filter[f][ACOMP];               }            }         }         dest[j * srcWidth + i][RCOMP] = sumR;         dest[j * srcWidth + i][GCOMP] = sumG;         dest[j * srcWidth + i][BCOMP] = sumB;         dest[j * srcWidth + i][ACOMP] = sumA;      }   }}static voidconvolve_2d_replicate(GLint srcWidth, GLint srcHeight,                      const GLfloat src[][4],                      GLint filterWidth, GLint filterHeight,                      const GLfloat filter[][4],                      GLfloat dest[][4]){   const GLint halfFilterWidth = filterWidth / 2;   const GLint halfFilterHeight = filterHeight / 2;   GLint i, j, n, m;   for (j = 0; j < srcHeight; j++) {      for (i = 0; i < srcWidth; 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++) {               const GLint f = m * filterWidth + n;               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] * filter[f][RCOMP];               sumG += src[k][GCOMP] * filter[f][GCOMP];               sumB += src[k][BCOMP] * filter[f][BCOMP];               sumA += src[k][ACOMP] * filter[f][ACOMP];            }         }         dest[j * srcWidth + i][RCOMP] = sumR;         dest[j * srcWidth + i][GCOMP] = sumG;         dest[j * srcWidth + i][BCOMP] = sumB;         dest[j * srcWidth + i][ACOMP] = sumA;      }   }}static voidconvolve_sep_reduce(GLint srcWidth, GLint srcHeight,                    const GLfloat src[][4],                    GLint filterWidth, GLint filterHeight,                    const GLfloat rowFilt[][4],                    const GLfloat colFilt[][4],                    GLfloat dest[][4]){   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;   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++) {               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[j * dstWidth + i][RCOMP] = sumR;         dest[j * dstWidth + i][GCOMP] = sumG;         dest[j * dstWidth + i][BCOMP] = sumB;         dest[j * dstWidth + i][ACOMP] = sumA;      }   }}static voidconvolve_sep_constant(GLint srcWidth, GLint srcHeight,                      const GLfloat src[][4],                      GLint filterWidth, GLint filterHeight,                      const GLfloat rowFilt[][4],                      const GLfloat colFilt[][4],                      GLfloat dest[][4],                      const GLfloat borderColor[4]){   const GLint halfFilterWidth = filterWidth / 2;   const GLint halfFilterHeight = filterHeight / 2;   GLint i, j, n, m;   for (j = 0; j < srcHeight; j++) {      for (i = 0; i < srcWidth; 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++) {               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 {                  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[j * srcWidth + i][RCOMP] = sumR;         dest[j * srcWidth + i][GCOMP] = sumG;         dest[j * srcWidth + i][BCOMP] = sumB;         dest[j * srcWidth + i][ACOMP] = sumA;      }   }}static voidconvolve_sep_replicate(GLint srcWidth, GLint srcHeight,                       const GLfloat src[][4],                       GLint filterWidth, GLint filterHeight,                       const GLfloat rowFilt[][4],                       const GLfloat colFilt[][4],                       GLfloat dest[][4]){   const GLint halfFilterWidth = filterWidth / 2;   const GLint halfFilterHeight = filterHeight / 2;   GLint i, j, n, m;   for (j = 0; j < srcHeight; j++) {      for (i = 0; i < srcWidth; 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++) {               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[j * srcWidth + i][RCOMP] = sumR;         dest[j * srcWidth + i][GCOMP] = sumG;         dest[j * srcWidth + i][BCOMP] = sumB;         dest[j * srcWidth + i][ACOMP] = sumA;      }   }}void_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,                        const GLfloat *srcImage, GLfloat *dstImage){   switch (ctx->Pixel.ConvolutionBorderMode[0]) {      case GL_REDUCE:         convolve_1d_reduce(*width, (const GLfloat (*)[4]) srcImage,                            ctx->Convolution1D.Width,                            (const GLfloat (*)[4]) ctx->Convolution1D.Filter,                            (GLfloat (*)[4]) dstImage);         *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1);         break;      case GL_CONSTANT_BORDER:         convolve_1d_constant(*width, (const GLfloat (*)[4]) srcImage,                              ctx->Convolution1D.Width,                              (const GLfloat (*)[4]) ctx->Convolution1D.Filter,                              (GLfloat (*)[4]) dstImage,                              ctx->Pixel.ConvolutionBorderColor[0]);         break;      case GL_REPLICATE_BORDER:         convolve_1d_replicate(*width, (const GLfloat (*)[4]) srcImage,                              ctx->Convolution1D.Width,                              (const GLfloat (*)[4]) ctx->Convolution1D.Filter,                              (GLfloat (*)[4]) dstImage);         break;      default:         ;   }}void_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,                        const GLfloat *srcImage, GLfloat *dstImage){   switch (ctx->Pixel.ConvolutionBorderMode[1]) {      case GL_REDUCE:         convolve_2d_reduce(*width, *height,                            (const GLfloat (*)[4]) srcImage,                            ctx->Convolution2D.Width,                            ctx->Convolution2D.Height,                            (const GLfloat (*)[4]) ctx->Convolution2D.Filter,                            (GLfloat (*)[4]) dstImage);         *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,                              (const GLfloat (*)[4]) srcImage,                              ctx->Convolution2D.Width,                              ctx->Convolution2D.Height,                              (const GLfloat (*)[4]) ctx->Convolution2D.Filter,                              (GLfloat (*)[4]) dstImage,                              ctx->Pixel.ConvolutionBorderColor[1]);         break;      case GL_REPLICATE_BORDER:         convolve_2d_replicate(*width, *height,                               (const GLfloat (*)[4]) srcImage,                               ctx->Convolution2D.Width,                               ctx->Convolution2D.Height,                               (const GLfloat (*)[4])ctx->Convolution2D.Filter,                               (GLfloat (*)[4]) dstImage);         break;      default:         ;      }}void_mesa_convolve_sep_image(const GLcontext *ctx,                         GLsizei *width, GLsizei *height,                         const GLfloat *srcImage, GLfloat *dstImage){   const GLfloat *rowFilter = ctx->Separable2D.Filter;   const GLfloat *colFilter = rowFilter + 4 * MAX_CONVOLUTION_WIDTH;   switch (ctx->Pixel.ConvolutionBorderMode[2]) {      case GL_REDUCE:         convolve_sep_reduce(*width, *height,                             (const GLfloat (*)[4]) srcImage,                             ctx->Separable2D.Width,                             ctx->Separable2D.Height,                             (const GLfloat (*)[4]) rowFilter,                             (const GLfloat (*)[4]) colFilter,                             (GLfloat (*)[4]) dstImage);         *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->Separable2D.Width,                               ctx->Separable2D.Height,                               (const GLfloat (*)[4]) rowFilter,                               (const GLfloat (*)[4]) colFilter,                               (GLfloat (*)[4]) dstImage,                               ctx->Pixel.ConvolutionBorderColor[2]);         break;      case GL_REPLICATE_BORDER:         convolve_sep_replicate(*width, *height,                                (const GLfloat (*)[4]) srcImage,                                ctx->Separable2D.Width,                                ctx->Separable2D.Height,                                (const GLfloat (*)[4]) rowFilter,                                (const GLfloat (*)[4]) colFilter,                                (GLfloat (*)[4]) dstImage);         break;      default:         ;   }}/* * This function computes an image's size after convolution. * If the convolution border mode is GL_REDUCE, the post-convolution * image will be smaller than the original. */void_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions,                                   GLsizei *width, GLsizei *height){   if (ctx->Pixel.Convolution1DEnabled       && dimensions == 1       && ctx->Pixel.ConvolutionBorderMode[0] == GL_REDUCE) {      *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1);   }   else if (ctx->Pixel.Convolution2DEnabled            && dimensions > 1            && ctx->Pixel.ConvolutionBorderMode[1] == GL_REDUCE) {      *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1);      *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1);   }   else if (ctx->Pixel.Separable2DEnabled            && dimensions > 1            && ctx->Pixel.ConvolutionBorderMode[2] == GL_REDUCE) {      *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1);      *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1);   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -