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

📄 convolve.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
}void GLAPIENTRY_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,                         GLvoid *row, GLvoid *column, GLvoid *span){   const GLint colStart = MAX_CONVOLUTION_WIDTH * 4;   struct gl_convolution_attrib *filter;   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END(ctx);   if (ctx->NewState) {      _mesa_update_state(ctx);   }   if (target != GL_SEPARABLE_2D) {      _mesa_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter(target)");      return;   }   if (!_mesa_is_legal_format_and_type(ctx, format, type)) {      _mesa_error(ctx, GL_INVALID_OPERATION,                  "glGetConvolutionFilter(format or type)");      return;   }   if (format == GL_COLOR_INDEX ||       format == GL_STENCIL_INDEX ||       format == GL_DEPTH_COMPONENT ||       format == GL_INTENSITY ||       type == GL_BITMAP) {      _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)");      return;   }   filter = &ctx->Separable2D;   if (ctx->Pack.BufferObj->Name) {      /* Pack filter into PBO */      GLubyte *buf;      if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Width, 1, 1,                                     format, type, row)) {         _mesa_error(ctx, GL_INVALID_OPERATION,                     "glGetSeparableFilter(invalid PBO access, width)");         return;      }      if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Height, 1, 1,                                     format, type, column)) {         _mesa_error(ctx, GL_INVALID_OPERATION,                     "glGetSeparableFilter(invalid PBO access, height)");         return;      }      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,                                              GL_WRITE_ONLY_ARB,                                              ctx->Pack.BufferObj);      if (!buf) {         /* buffer is already mapped - that's an error */         _mesa_error(ctx, GL_INVALID_OPERATION,                     "glGetSeparableFilter(PBO is mapped)");         return;      }      row = ADD_POINTERS(buf, row);      column = ADD_POINTERS(buf, column);   }   /* Row filter */   if (row) {      GLvoid *dst = _mesa_image_address1d(&ctx->Pack, row, filter->Width,                                          format, type, 0);      _mesa_pack_rgba_span_float(ctx, filter->Width,                                 (GLfloat (*)[4]) filter->Filter,                                 format, type, dst, &ctx->Pack, 0x0);   }   /* Column filter */   if (column) {      GLvoid *dst = _mesa_image_address1d(&ctx->Pack, column, filter->Height,                                          format, type, 0);      GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + colStart);      _mesa_pack_rgba_span_float(ctx, filter->Height, src,                                 format, type, dst, &ctx->Pack, 0x0);   }   (void) span;  /* unused at this time */   if (ctx->Pack.BufferObj->Name) {      /* Pack filter into PBO */      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,                              ctx->Unpack.BufferObj);   }}void GLAPIENTRY_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column){   const GLint colStart = MAX_CONVOLUTION_WIDTH * 4;   GLint baseFormat;   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);   if (target != GL_SEPARABLE_2D) {      _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(target)");      return;   }   baseFormat = base_filter_format(internalFormat);   if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) {      _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(internalFormat)");      return;   }   if (width < 0 || width > MAX_CONVOLUTION_WIDTH) {      _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(width)");      return;   }   if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) {      _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(height)");      return;   }   if (!_mesa_is_legal_format_and_type(ctx, format, type)) {      _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D(format or type)");      return;   }   if (format == GL_COLOR_INDEX ||       format == GL_STENCIL_INDEX ||       format == GL_DEPTH_COMPONENT ||       format == GL_INTENSITY ||       type == GL_BITMAP) {      _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(format or type)");      return;   }   ctx->Separable2D.Format = format;   ctx->Separable2D.InternalFormat = internalFormat;   ctx->Separable2D.Width = width;   ctx->Separable2D.Height = height;   if (ctx->Unpack.BufferObj->Name) {      /* unpack filter from PBO */      GLubyte *buf;      if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,                                     format, type, row)) {         _mesa_error(ctx, GL_INVALID_OPERATION,                     "glSeparableFilter2D(invalid PBO access, width)");         return;      }      if (!_mesa_validate_pbo_access(1, &ctx->Unpack, height, 1, 1,                                     format, type, column)) {         _mesa_error(ctx, GL_INVALID_OPERATION,                     "glSeparableFilter2D(invalid PBO access, height)");         return;      }      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,                                              GL_READ_ONLY_ARB,                                              ctx->Unpack.BufferObj);      if (!buf) {         /* buffer is already mapped - that's an error */         _mesa_error(ctx, GL_INVALID_OPERATION,                     "glSeparableFilter2D(PBO is mapped)");         return;      }      row = ADD_POINTERS(buf, row);      column = ADD_POINTERS(buf, column);   }   /* unpack row filter */   if (row) {      _mesa_unpack_color_span_float(ctx, width, GL_RGBA,                                    ctx->Separable2D.Filter,                                    format, type, row, &ctx->Unpack,                                    0);  /* transferOps */      _mesa_scale_and_bias_rgba(width,                             (GLfloat (*)[4]) ctx->Separable2D.Filter,                             ctx->Pixel.ConvolutionFilterScale[2][0],                             ctx->Pixel.ConvolutionFilterScale[2][1],                             ctx->Pixel.ConvolutionFilterScale[2][2],                             ctx->Pixel.ConvolutionFilterScale[2][3],                             ctx->Pixel.ConvolutionFilterBias[2][0],                             ctx->Pixel.ConvolutionFilterBias[2][1],                             ctx->Pixel.ConvolutionFilterBias[2][2],                             ctx->Pixel.ConvolutionFilterBias[2][3]);   }   /* unpack column filter */   if (column) {      _mesa_unpack_color_span_float(ctx, height, GL_RGBA,                                    &ctx->Separable2D.Filter[colStart],                                    format, type, column, &ctx->Unpack,                                    0); /* transferOps */      _mesa_scale_and_bias_rgba(height,                       (GLfloat (*)[4]) (ctx->Separable2D.Filter + colStart),                       ctx->Pixel.ConvolutionFilterScale[2][0],                       ctx->Pixel.ConvolutionFilterScale[2][1],                       ctx->Pixel.ConvolutionFilterScale[2][2],                       ctx->Pixel.ConvolutionFilterScale[2][3],                       ctx->Pixel.ConvolutionFilterBias[2][0],                       ctx->Pixel.ConvolutionFilterBias[2][1],                       ctx->Pixel.ConvolutionFilterBias[2][2],                       ctx->Pixel.ConvolutionFilterBias[2][3]);   }   if (ctx->Unpack.BufferObj->Name) {      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,                              ctx->Unpack.BufferObj);   }   ctx->NewState |= _NEW_PIXEL;}/**********************************************************************//***                   image convolution functions                  ***//**********************************************************************/static voidconvolve_1d_reduce(GLint srcWidth, const GLfloat src[][4],                   GLint filterWidth, const GLfloat filter[][4],                   GLfloat dest[][4]){   GLint dstWidth;   GLint i, n;   if (filterWidth >= 1)      dstWidth = srcWidth - (filterWidth - 1);   else      dstWidth = srcWidth;   if (dstWidth <= 0)      return;  /* null result */   for (i = 0; i < dstWidth; i++) {      GLfloat sumR = 0.0;      GLfloat sumG = 0.0;      GLfloat sumB = 0.0;      GLfloat sumA = 0.0;      for (n = 0; n < filterWidth; n++) {         sumR += src[i + n][RCOMP] * filter[n][RCOMP];         sumG += src[i + n][GCOMP] * filter[n][GCOMP];         sumB += src[i + n][BCOMP] * filter[n][BCOMP];         sumA += src[i + n][ACOMP] * filter[n][ACOMP];      }      dest[i][RCOMP] = sumR;      dest[i][GCOMP] = sumG;      dest[i][BCOMP] = sumB;      dest[i][ACOMP] = sumA;   }}static voidconvolve_1d_constant(GLint srcWidth, const GLfloat src[][4],                     GLint filterWidth, const GLfloat filter[][4],                     GLfloat dest[][4],                     const GLfloat borderColor[4]){   const GLint halfFilterWidth = filterWidth / 2;   GLint i, n;   for (i = 0; i < srcWidth; i++) {      GLfloat sumR = 0.0;      GLfloat sumG = 0.0;      GLfloat sumB = 0.0;      GLfloat sumA = 0.0;      for (n = 0; n < filterWidth; n++) {         if (i + n < halfFilterWidth || i + n - halfFilterWidth >= srcWidth) {            sumR += borderColor[RCOMP] * filter[n][RCOMP];            sumG += borderColor[GCOMP] * filter[n][GCOMP];            sumB += borderColor[BCOMP] * filter[n][BCOMP];            sumA += borderColor[ACOMP] * filter[n][ACOMP];         }         else {            sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];            sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];            sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];            sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];         }      }      dest[i][RCOMP] = sumR;      dest[i][GCOMP] = sumG;      dest[i][BCOMP] = sumB;      dest[i][ACOMP] = sumA;   }}static voidconvolve_1d_replicate(GLint srcWidth, const GLfloat src[][4],                      GLint filterWidth, const GLfloat filter[][4],                      GLfloat dest[][4]){   const GLint halfFilterWidth = filterWidth / 2;   GLint i, n;   for (i = 0; i < srcWidth; i++) {      GLfloat sumR = 0.0;      GLfloat sumG = 0.0;      GLfloat sumB = 0.0;      GLfloat sumA = 0.0;      for (n = 0; n < filterWidth; n++) {         if (i + n < halfFilterWidth) {            sumR += src[0][RCOMP] * filter[n][RCOMP];            sumG += src[0][GCOMP] * filter[n][GCOMP];            sumB += src[0][BCOMP] * filter[n][BCOMP];            sumA += src[0][ACOMP] * filter[n][ACOMP];         }         else if (i + n - halfFilterWidth >= srcWidth) {            sumR += src[srcWidth - 1][RCOMP] * filter[n][RCOMP];            sumG += src[srcWidth - 1][GCOMP] * filter[n][GCOMP];            sumB += src[srcWidth - 1][BCOMP] * filter[n][BCOMP];            sumA += src[srcWidth - 1][ACOMP] * filter[n][ACOMP];         }         else {            sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];            sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];            sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];            sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];         }      }      dest[i][RCOMP] = sumR;      dest[i][GCOMP] = sumG;      dest[i][BCOMP] = sumB;      dest[i][ACOMP] = sumA;   }}static voidconvolve_2d_reduce(GLint srcWidth, GLint srcHeight,                   const GLfloat src[][4],                   GLint filterWidth, GLint filterHeight,                   const GLfloat filter[][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++) {               const GLint k = (j + m) * srcWidth + i + n;               const GLint f = m * filterWidth + n;               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 * dstWidth + i][RCOMP] = sumR;         dest[j * dstWidth + i][GCOMP] = sumG;         dest[j * dstWidth + i][BCOMP] = sumB;         dest[j * dstWidth + i][ACOMP] = sumA;      }   }}static voidconvolve_2d_constant(GLint srcWidth, GLint srcHeight,                     const GLfloat src[][4],

⌨️ 快捷键说明

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