X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fconvolve.c;h=83d590f4a48b43e91e23cd7a03a6e124ba3a3095;hb=0663edf85b8e055dfecf290afab1a15c68da961a;hp=aa4af92e94cd9079f8595ce7ba83a2569b78d023;hpb=b5012e1ee1b0172dda3921bcf12e3605b1be589b;p=mesa.git diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c index aa4af92e94c..83d590f4a48 100644 --- a/src/mesa/main/convolve.c +++ b/src/mesa/main/convolve.c @@ -1,10 +1,7 @@ -/* $Id: convolve.c,v 1.11 2000/11/10 18:31:04 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,9 +16,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ @@ -33,1365 +31,144 @@ */ -#ifdef PC_HEADER -#include "all.h" -#else #include "glheader.h" -#include "colormac.h" -#include "convolve.h" #include "context.h" -#include "image.h" -#include "types.h" -#include "swrast/s_span.h" /* XXX SWRAST hack */ -#endif - - -/* - * Given an internalFormat token passed to glConvolutionFilter - * or glSeparableFilter, return the corresponding base format. - * Return -1 if invalid token. - */ -static GLint -base_filter_format( GLenum format ) -{ - switch (format) { - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - return GL_ALPHA; - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - return GL_LUMINANCE; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - return GL_LUMINANCE_ALPHA; - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - return GL_INTENSITY; - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return GL_RGB; - case 4: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - return GL_RGBA; - default: - return -1; /* error */ - } -} +#include "convolve.h" +#include "main/dispatch.h" -void +void GLAPIENTRY _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) { - GLenum baseFormat; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionFilter1D"); - if (target != GL_CONVOLUTION_1D) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(target)"); - return; - } - - baseFormat = base_filter_format(internalFormat); - if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(internalFormat)"); - return; - } - - if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter1D(width)"); - return; - } - - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || - format == GL_STENCIL_INDEX || - format == GL_DEPTH_COMPONENT || - format == GL_INTENSITY || - type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(format or type)"); - return; - } - - ctx->Convolution1D.Format = format; - ctx->Convolution1D.InternalFormat = internalFormat; - ctx->Convolution1D.Width = width; - ctx->Convolution1D.Height = 1; - - /* unpack filter image */ - _mesa_unpack_float_color_span(ctx, width, GL_RGBA, - ctx->Convolution1D.Filter, - format, type, image, &ctx->Unpack, - 0, GL_FALSE); - - /* apply scale and bias */ - { - const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[0]; - const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[0]; - GLint i; - for (i = 0; i < width; i++) { - GLfloat r = ctx->Convolution1D.Filter[i * 4 + 0]; - GLfloat g = ctx->Convolution1D.Filter[i * 4 + 1]; - GLfloat b = ctx->Convolution1D.Filter[i * 4 + 2]; - GLfloat a = ctx->Convolution1D.Filter[i * 4 + 3]; - r = r * scale[0] + bias[0]; - g = g * scale[1] + bias[1]; - b = b * scale[2] + bias[2]; - a = a * scale[3] + bias[3]; - ctx->Convolution1D.Filter[i * 4 + 0] = r; - ctx->Convolution1D.Filter[i * 4 + 1] = g; - ctx->Convolution1D.Filter[i * 4 + 2] = b; - ctx->Convolution1D.Filter[i * 4 + 3] = a; - } - } - - ctx->NewState |= _NEW_PIXEL; + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter1D"); } - -void +void GLAPIENTRY _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) { - GLenum baseFormat; - GLint i, components; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionFilter2D"); - if (target != GL_CONVOLUTION_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(target)"); - return; - } - - baseFormat = base_filter_format(internalFormat); - if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(internalFormat)"); - return; - } - - if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(width)"); - return; - } - if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { - gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(height)"); - return; - } - - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || - format == GL_STENCIL_INDEX || - format == GL_DEPTH_COMPONENT || - format == GL_INTENSITY || - type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(format or type)"); - return; - } - - components = _mesa_components_in_format(format); - assert(components > 0); /* this should have been caught earlier */ - - ctx->Convolution2D.Format = format; - ctx->Convolution2D.InternalFormat = internalFormat; - ctx->Convolution2D.Width = width; - ctx->Convolution2D.Height = height; - - /* Unpack filter image. We always store filters in RGBA format. */ - for (i = 0; i < height; i++) { - const GLvoid *src = _mesa_image_address(&ctx->Unpack, image, width, - height, format, type, 0, i, 0); - GLfloat *dst = ctx->Convolution2D.Filter + i * width * 4; - _mesa_unpack_float_color_span(ctx, width, GL_RGBA, dst, - format, type, src, &ctx->Unpack, - 0, GL_FALSE); - } - - /* apply scale and bias */ - { - const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[1]; - const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[1]; - for (i = 0; i < width * height * 4; i++) { - GLfloat r = ctx->Convolution2D.Filter[i * 4 + 0]; - GLfloat g = ctx->Convolution2D.Filter[i * 4 + 1]; - GLfloat b = ctx->Convolution2D.Filter[i * 4 + 2]; - GLfloat a = ctx->Convolution2D.Filter[i * 4 + 3]; - r = r * scale[0] + bias[0]; - g = g * scale[1] + bias[1]; - b = b * scale[2] + bias[2]; - a = a * scale[3] + bias[3]; - ctx->Convolution2D.Filter[i * 4 + 0] = r; - ctx->Convolution2D.Filter[i * 4 + 1] = g; - ctx->Convolution2D.Filter[i * 4 + 2] = b; - ctx->Convolution2D.Filter[i * 4 + 3] = a; - } - } - - ctx->NewState |= _NEW_PIXEL; + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter2D"); } -void +void GLAPIENTRY _mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) { GET_CURRENT_CONTEXT(ctx); - GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameterf"); - switch (target) { - case GL_CONVOLUTION_1D: - c = 0; - break; - case GL_CONVOLUTION_2D: - c = 1; - break; - case GL_SEPARABLE_2D: - c = 2; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(target)"); - return; - } - - switch (pname) { - case GL_CONVOLUTION_BORDER_MODE: - if (param == (GLfloat) GL_REDUCE || - param == (GLfloat) GL_CONSTANT_BORDER || - param == (GLfloat) GL_REPLICATE_BORDER) { - ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; - } - else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(params)"); - return; - } - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(pname)"); - return; - } - - ctx->NewState |= _NEW_PIXEL; + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterf"); } -void +void GLAPIENTRY _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - struct gl_convolution_attrib *conv; - GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameterfv"); - - switch (target) { - case GL_CONVOLUTION_1D: - c = 0; - conv = &ctx->Convolution1D; - break; - case GL_CONVOLUTION_2D: - c = 1; - conv = &ctx->Convolution2D; - break; - case GL_SEPARABLE_2D: - c = 2; - conv = &ctx->Separable2D; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(target)"); - return; - } - switch (pname) { - case GL_CONVOLUTION_BORDER_COLOR: - COPY_4V(ctx->Pixel.ConvolutionBorderColor[c], params); - break; - case GL_CONVOLUTION_BORDER_MODE: - if (params[0] == (GLfloat) GL_REDUCE || - params[0] == (GLfloat) GL_CONSTANT_BORDER || - params[0] == (GLfloat) GL_REPLICATE_BORDER) { - ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; - } - else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(params)"); - return; - } - break; - case GL_CONVOLUTION_FILTER_SCALE: - COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params); - break; - case GL_CONVOLUTION_FILTER_BIAS: - COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(pname)"); - return; - } - - ctx->NewState |= _NEW_PIXEL; + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterfv"); } -void +void GLAPIENTRY _mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) { GET_CURRENT_CONTEXT(ctx); - GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameteri"); - - switch (target) { - case GL_CONVOLUTION_1D: - c = 0; - break; - case GL_CONVOLUTION_2D: - c = 1; - break; - case GL_SEPARABLE_2D: - c = 2; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(target)"); - return; - } - - switch (pname) { - case GL_CONVOLUTION_BORDER_MODE: - if (param == (GLint) GL_REDUCE || - param == (GLint) GL_CONSTANT_BORDER || - param == (GLint) GL_REPLICATE_BORDER) { - ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; - } - else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(params)"); - return; - } - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(pname)"); - return; - } - ctx->NewState |= _NEW_PIXEL; + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteri"); } -void +void GLAPIENTRY _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) { GET_CURRENT_CONTEXT(ctx); - struct gl_convolution_attrib *conv; - GLuint c; - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameteriv"); - - switch (target) { - case GL_CONVOLUTION_1D: - c = 0; - conv = &ctx->Convolution1D; - break; - case GL_CONVOLUTION_2D: - c = 1; - conv = &ctx->Convolution2D; - break; - case GL_SEPARABLE_2D: - c = 2; - conv = &ctx->Separable2D; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(target)"); - return; - } - - switch (pname) { - case GL_CONVOLUTION_BORDER_COLOR: - ctx->Pixel.ConvolutionBorderColor[c][0] = INT_TO_FLOAT(params[0]); - ctx->Pixel.ConvolutionBorderColor[c][1] = INT_TO_FLOAT(params[1]); - ctx->Pixel.ConvolutionBorderColor[c][2] = INT_TO_FLOAT(params[2]); - ctx->Pixel.ConvolutionBorderColor[c][3] = INT_TO_FLOAT(params[3]); - break; - case GL_CONVOLUTION_BORDER_MODE: - if (params[0] == (GLint) GL_REDUCE || - params[0] == (GLint) GL_CONSTANT_BORDER || - params[0] == (GLint) GL_REPLICATE_BORDER) { - ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; - } - else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(params)"); - return; - } - break; - case GL_CONVOLUTION_FILTER_SCALE: - COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params); - break; - case GL_CONVOLUTION_FILTER_BIAS: - COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(pname)"); - return; - } - - ctx->NewState |= _NEW_PIXEL; + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteriv"); } -void +void GLAPIENTRY _mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width) { - GLenum baseFormat; - GLfloat rgba[MAX_CONVOLUTION_WIDTH][4]; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyConvolutionFilter1D"); - - if (target != GL_CONVOLUTION_1D) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(target)"); - return; - } - - baseFormat = base_filter_format(internalFormat); - if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(internalFormat)"); - return; - } - if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter1D(width)"); - return; - } - - /* read pixels from framebuffer */ - gl_read_rgba_span(ctx, ctx->ReadBuffer, width, x, y, (GLchan (*)[4]) rgba); - - /* store as convolution filter */ - _mesa_ConvolutionFilter1D(target, internalFormat, width, - GL_RGBA, GL_UNSIGNED_BYTE, rgba); + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter1D"); } -void +void GLAPIENTRY _mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height) { - GLenum baseFormat; - GLint i; - struct gl_pixelstore_attrib packSave; - GLfloat rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4]; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyConvolutionFilter2D"); - - if (target != GL_CONVOLUTION_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(target)"); - return; - } - - baseFormat = base_filter_format(internalFormat); - if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(internalFormat)"); - return; - } - if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(width)"); - return; - } - if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { - gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(height)"); - return; - } - - /* read pixels from framebuffer */ - for (i = 0; i < height; i++) { - gl_read_rgba_span(ctx, ctx->ReadBuffer, width, x, y + i, - (GLchan (*)[4]) rgba[i]); - } - - /* - * store as convolution filter - */ - packSave = ctx->Unpack; /* save pixel packing params */ - - ctx->Unpack.Alignment = 1; - ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH; - ctx->Unpack.SkipPixels = 0; - ctx->Unpack.SkipRows = 0; - ctx->Unpack.ImageHeight = 0; - ctx->Unpack.SkipImages = 0; - ctx->Unpack.SwapBytes = GL_FALSE; - ctx->Unpack.LsbFirst = GL_FALSE; - ctx->NewState |= _NEW_PACKUNPACK; - - _mesa_ConvolutionFilter2D(target, internalFormat, width, height, - GL_RGBA, GL_UNSIGNED_BYTE, rgba); - - ctx->Unpack = packSave; /* restore pixel packing params */ - ctx->NewState |= _NEW_PACKUNPACK; + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter2D"); } -void -_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid *image) +void GLAPIENTRY +_mesa_GetnConvolutionFilterARB(GLenum target, GLenum format, GLenum type, + GLsizei bufSize, GLvoid *image) { - const struct gl_convolution_attrib *filter; - GLint row; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionFilter"); - - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || - format == GL_STENCIL_INDEX || - format == GL_DEPTH_COMPONENT || - format == GL_INTENSITY || - type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); - return; - } - switch (target) { - case GL_CONVOLUTION_1D: - filter = &(ctx->Convolution1D); - break; - case GL_CONVOLUTION_2D: - filter = &(ctx->Convolution2D); - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(target)"); - return; - } - - for (row = 0; row < filter->Height; row++) { - GLvoid *dst = _mesa_image_address( &ctx->Pack, image, filter->Width, - filter->Height, format, type, - 0, row, 0); - const GLfloat *src = filter->Filter + row * filter->Width * 4; - /* XXX apply transfer ops or not? */ - _mesa_pack_float_rgba_span(ctx, filter->Width, - (const GLfloat (*)[4]) src, - format, type, dst, &ctx->Pack, 0); - } + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter"); } -void -_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) +void GLAPIENTRY +_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, + GLvoid *image) { - GET_CURRENT_CONTEXT(ctx); - const struct gl_convolution_attrib *conv; - GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionParameterfv"); - - switch (target) { - case GL_CONVOLUTION_1D: - c = 0; - conv = &ctx->Convolution1D; - break; - case GL_CONVOLUTION_2D: - c = 1; - conv = &ctx->Convolution2D; - break; - case GL_SEPARABLE_2D: - c = 2; - conv = &ctx->Separable2D; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(target)"); - return; - } - - switch (pname) { - case GL_CONVOLUTION_BORDER_COLOR: - COPY_4V(params, ctx->Pixel.ConvolutionBorderColor[c]); - break; - case GL_CONVOLUTION_BORDER_MODE: - *params = (GLfloat) ctx->Pixel.ConvolutionBorderMode[c]; - break; - case GL_CONVOLUTION_FILTER_SCALE: - COPY_4V(params, ctx->Pixel.ConvolutionFilterScale[c]); - break; - case GL_CONVOLUTION_FILTER_BIAS: - COPY_4V(params, ctx->Pixel.ConvolutionFilterBias[c]); - break; - case GL_CONVOLUTION_FORMAT: - *params = (GLfloat) conv->Format; - break; - case GL_CONVOLUTION_WIDTH: - *params = (GLfloat) conv->Width; - break; - case GL_CONVOLUTION_HEIGHT: - *params = (GLfloat) conv->Height; - break; - case GL_MAX_CONVOLUTION_WIDTH: - *params = (GLfloat) ctx->Const.MaxConvolutionWidth; - break; - case GL_MAX_CONVOLUTION_HEIGHT: - *params = (GLfloat) ctx->Const.MaxConvolutionHeight; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(pname)"); - return; - } + _mesa_GetnConvolutionFilterARB(target, format, type, INT_MAX, image); } -void -_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) +void GLAPIENTRY +_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - const struct gl_convolution_attrib *conv; - GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionParameteriv"); - switch (target) { - case GL_CONVOLUTION_1D: - c = 0; - conv = &ctx->Convolution1D; - break; - case GL_CONVOLUTION_2D: - c = 1; - conv = &ctx->Convolution2D; - break; - case GL_SEPARABLE_2D: - c = 2; - conv = &ctx->Separable2D; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(target)"); - return; - } - - switch (pname) { - case GL_CONVOLUTION_BORDER_COLOR: - params[0] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][0]); - params[1] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][1]); - params[2] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][2]); - params[3] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][3]); - break; - case GL_CONVOLUTION_BORDER_MODE: - *params = (GLint) ctx->Pixel.ConvolutionBorderMode[c]; - break; - case GL_CONVOLUTION_FILTER_SCALE: - params[0] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][0]; - params[1] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][1]; - params[2] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][2]; - params[3] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][3]; - break; - case GL_CONVOLUTION_FILTER_BIAS: - params[0] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][0]; - params[1] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][1]; - params[2] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][2]; - params[3] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][3]; - break; - case GL_CONVOLUTION_FORMAT: - *params = (GLint) conv->Format; - break; - case GL_CONVOLUTION_WIDTH: - *params = (GLint) conv->Width; - break; - case GL_CONVOLUTION_HEIGHT: - *params = (GLint) conv->Height; - break; - case GL_MAX_CONVOLUTION_WIDTH: - *params = (GLint) ctx->Const.MaxConvolutionWidth; - break; - case GL_MAX_CONVOLUTION_HEIGHT: - *params = (GLint) ctx->Const.MaxConvolutionHeight; - break; - default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(pname)"); - return; - } + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameterfv"); } -void -_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) +void GLAPIENTRY +_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) { - const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; - const struct gl_convolution_attrib *filter; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetSeparableFilter"); - if (target != GL_SEPARABLE_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter(target)"); - return; - } - - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || - format == GL_STENCIL_INDEX || - format == GL_DEPTH_COMPONENT || - format == GL_INTENSITY || - type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); - return; - } - - filter = &ctx->Separable2D; - - /* Row filter */ - { - GLvoid *dst = _mesa_image_address( &ctx->Pack, row, filter->Width, - filter->Height, format, type, - 0, 0, 0); - _mesa_pack_float_rgba_span(ctx, filter->Width, - (const GLfloat (*)[4]) filter->Filter, - format, type, dst, &ctx->Pack, 0); - } - - /* Column filter */ - { - GLvoid *dst = _mesa_image_address( &ctx->Pack, column, filter->Width, - 1, format, type, - 0, 0, 0); - const GLfloat *src = filter->Filter + colStart; - _mesa_pack_float_rgba_span(ctx, filter->Height, - (const GLfloat (*)[4]) src, - format, type, dst, &ctx->Pack, 0); - } - - (void) span; /* unused at this time */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameteriv"); } -void -_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) +void GLAPIENTRY +_mesa_GetnSeparableFilterARB(GLenum target, GLenum format, GLenum type, + GLsizei rowBufSize, GLvoid *row, + GLsizei columnBufSize, GLvoid *column, + GLvoid *span) { - const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; - GLenum baseFormat; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glSeparableFilter2D"); - - if (target != GL_SEPARABLE_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(target)"); - return; - } - - baseFormat = base_filter_format(internalFormat); - if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(internalFormat)"); - return; - } - if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(width)"); - return; - } - if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { - gl_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(height)"); - return; - } - - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || - format == GL_STENCIL_INDEX || - format == GL_DEPTH_COMPONENT || - format == GL_INTENSITY || - type == GL_BITMAP) { - gl_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; - - /* unpack row filter */ - _mesa_unpack_float_color_span(ctx, width, GL_RGBA, - ctx->Separable2D.Filter, - format, type, row, &ctx->Unpack, - 0, GL_FALSE); - - /* apply scale and bias */ - { - const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[2]; - const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[2]; - GLint i; - for (i = 0; i < width; i++) { - GLfloat r = ctx->Separable2D.Filter[i * 4 + 0]; - GLfloat g = ctx->Separable2D.Filter[i * 4 + 1]; - GLfloat b = ctx->Separable2D.Filter[i * 4 + 2]; - GLfloat a = ctx->Separable2D.Filter[i * 4 + 3]; - r = r * scale[0] + bias[0]; - g = g * scale[1] + bias[1]; - b = b * scale[2] + bias[2]; - a = a * scale[3] + bias[3]; - ctx->Separable2D.Filter[i * 4 + 0] = r; - ctx->Separable2D.Filter[i * 4 + 1] = g; - ctx->Separable2D.Filter[i * 4 + 2] = b; - ctx->Separable2D.Filter[i * 4 + 3] = a; - } - } - - /* unpack column filter */ - _mesa_unpack_float_color_span(ctx, width, GL_RGBA, - &ctx->Separable2D.Filter[colStart], - format, type, column, &ctx->Unpack, - 0, GL_FALSE); - - /* apply scale and bias */ - { - const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[2]; - const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[2]; - GLint i; - for (i = 0; i < width; i++) { - GLfloat r = ctx->Separable2D.Filter[i * 4 + 0 + colStart]; - GLfloat g = ctx->Separable2D.Filter[i * 4 + 1 + colStart]; - GLfloat b = ctx->Separable2D.Filter[i * 4 + 2 + colStart]; - GLfloat a = ctx->Separable2D.Filter[i * 4 + 3 + colStart]; - r = r * scale[0] + bias[0]; - g = g * scale[1] + bias[1]; - b = b * scale[2] + bias[2]; - a = a * scale[3] + bias[3]; - ctx->Separable2D.Filter[i * 4 + 0 + colStart] = r; - ctx->Separable2D.Filter[i * 4 + 1 + colStart] = g; - ctx->Separable2D.Filter[i * 4 + 2 + colStart] = b; - ctx->Separable2D.Filter[i * 4 + 3 + colStart] = a; - } - } - - ctx->NewState |= _NEW_PIXEL; -} - - -/**********************************************************************/ -/*** image convolution functions ***/ -/**********************************************************************/ - -static void -convolve_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 void -convolve_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 void -convolve_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 void -convolve_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 void -convolve_2d_constant(GLint srcWidth, GLint srcHeight, - const GLfloat src[][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 void -convolve_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 void -convolve_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 void -convolve_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; - } - } + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSeparableFilter"); } -static void -convolve_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]) +void GLAPIENTRY +_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, + GLvoid *row, GLvoid *column, GLvoid *span) { - 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; - } - } + _mesa_GetnSeparableFilterARB(target, format, type, INT_MAX, row, + INT_MAX, column, span); } - -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) +void GLAPIENTRY +_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) { - const GLfloat *rowFilter = ctx->Separable2D.Filter; - const GLfloat *colFilter = rowFilter + 4 * MAX_CONVOLUTION_WIDTH; + GET_CURRENT_CONTEXT(ctx); - 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: - ; - } + _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D"); }