convolve.c revision c893a015d8a50a38cd3f727d99835e7e7e2ccea9
1c893a015d8a50a38cd3f727d99835e7e7e2ccea9Brian Paul/* $Id: convolve.c,v 1.7 2000/10/28 20:41:13 brianp Exp $ */ 2cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 3cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul/* 4cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Mesa 3-D graphics library 5d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul * Version: 3.5 6cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * 7cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. 8cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * 9cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 10cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * copy of this software and associated documentation files (the "Software"), 11cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * to deal in the Software without restriction, including without limitation 12cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 14cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Software is furnished to do so, subject to the following conditions: 15cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * 16cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * The above copyright notice and this permission notice shall be included 17cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * in all copies or substantial portions of the Software. 18cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * 19cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul */ 26cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 27cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 28cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul/* 29cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Image convolution functions. 30cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * 31cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Notes: filter kernel elements are indexed by <n> and <m> as in 32cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * the GL spec. 33cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul */ 34cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 35cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 36cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#ifdef PC_HEADER 37cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#include "all.h" 38cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#else 39cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#include "glheader.h" 40c893a015d8a50a38cd3f727d99835e7e7e2ccea9Brian Paul#include "colormac.h" 41d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul#include "convolve.h" 42d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul#include "context.h" 43147b08328a2ccb0c1150feaf7871037683236e33Brian Paul#include "image.h" 44147b08328a2ccb0c1150feaf7871037683236e33Brian Paul#include "span.h" 45cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#include "types.h" 46cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#endif 47cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 48cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 49147b08328a2ccb0c1150feaf7871037683236e33Brian Paul/* 50147b08328a2ccb0c1150feaf7871037683236e33Brian Paul * Given an internalFormat token passed to glConvolutionFilter 51147b08328a2ccb0c1150feaf7871037683236e33Brian Paul * or glSeparableFilter, return the corresponding base format. 52147b08328a2ccb0c1150feaf7871037683236e33Brian Paul * Return -1 if invalid token. 53147b08328a2ccb0c1150feaf7871037683236e33Brian Paul */ 54147b08328a2ccb0c1150feaf7871037683236e33Brian Paulstatic GLint 55147b08328a2ccb0c1150feaf7871037683236e33Brian Paulbase_filter_format( GLenum format ) 56147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 57147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (format) { 58147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_ALPHA: 59147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_ALPHA4: 60147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_ALPHA8: 61147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_ALPHA12: 62147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_ALPHA16: 63147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return GL_ALPHA; 64147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE: 65147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE4: 66147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE8: 67147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE12: 68147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE16: 69147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return GL_LUMINANCE; 70147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE_ALPHA: 71147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE4_ALPHA4: 72147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE6_ALPHA2: 73147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE8_ALPHA8: 74147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE12_ALPHA4: 75147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE12_ALPHA12: 76147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_LUMINANCE16_ALPHA16: 77147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return GL_LUMINANCE_ALPHA; 78147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_INTENSITY: 79147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_INTENSITY4: 80147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_INTENSITY8: 81147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_INTENSITY12: 82147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_INTENSITY16: 83147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return GL_INTENSITY; 84147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB: 85147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_R3_G3_B2: 86147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB4: 87147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB5: 88147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB8: 89147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB10: 90147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB12: 91147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB16: 92147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return GL_RGB; 93147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case 4: 94147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGBA: 95147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGBA2: 96147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGBA4: 97147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB5_A1: 98147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGBA8: 99147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGB10_A2: 100147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGBA12: 101147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_RGBA16: 102147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return GL_RGBA; 103147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 104147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return -1; /* error */ 105147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 106147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 107147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 108147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 109147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 110147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) 111147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 112147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLenum baseFormat; 113147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 114147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionFilter1D"); 115147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 116147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (target != GL_CONVOLUTION_1D) { 117147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(target)"); 118147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 119147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 120147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 121147b08328a2ccb0c1150feaf7871037683236e33Brian Paul baseFormat = base_filter_format(internalFormat); 122147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { 123147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(internalFormat)"); 124147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 125147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 126147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 127147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { 128147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter1D(width)"); 129147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 130147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 131147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 132147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (!_mesa_is_legal_format_and_type(format, type) || 133147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_COLOR_INDEX || 134147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_STENCIL_INDEX || 135147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_DEPTH_COMPONENT || 136147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_INTENSITY || 137147b08328a2ccb0c1150feaf7871037683236e33Brian Paul type == GL_BITMAP) { 138147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(format or type)"); 139147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 140147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 141147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 142147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Format = format; 143147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.InternalFormat = internalFormat; 144147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Width = width; 145147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Height = 1; 146147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 147147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* unpack filter image */ 148147b08328a2ccb0c1150feaf7871037683236e33Brian Paul _mesa_unpack_float_color_span(ctx, width, GL_RGBA, 149147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Filter, 150147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format, type, image, &ctx->Unpack, 151147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 0, GL_FALSE); 152147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 153147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* apply scale and bias */ 154147b08328a2ccb0c1150feaf7871037683236e33Brian Paul { 155147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[0]; 156147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[0]; 157147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLint i; 158147b08328a2ccb0c1150feaf7871037683236e33Brian Paul for (i = 0; i < width; i++) { 159147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat r = ctx->Convolution1D.Filter[i * 4 + 0]; 160147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat g = ctx->Convolution1D.Filter[i * 4 + 1]; 161147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat b = ctx->Convolution1D.Filter[i * 4 + 2]; 162147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat a = ctx->Convolution1D.Filter[i * 4 + 3]; 163147b08328a2ccb0c1150feaf7871037683236e33Brian Paul r = r * scale[0] + bias[0]; 164147b08328a2ccb0c1150feaf7871037683236e33Brian Paul g = g * scale[1] + bias[1]; 165147b08328a2ccb0c1150feaf7871037683236e33Brian Paul b = b * scale[2] + bias[2]; 166147b08328a2ccb0c1150feaf7871037683236e33Brian Paul a = a * scale[3] + bias[3]; 167147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Filter[i * 4 + 0] = r; 168147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Filter[i * 4 + 1] = g; 169147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Filter[i * 4 + 2] = b; 170147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution1D.Filter[i * 4 + 3] = a; 171147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 172147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 173147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 174147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 175147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 176147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 177147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) 178147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 179147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLenum baseFormat; 180147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLint i, components; 181147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 182147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionFilter2D"); 183147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 184147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (target != GL_CONVOLUTION_2D) { 185147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(target)"); 186147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 187147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 188147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 189147b08328a2ccb0c1150feaf7871037683236e33Brian Paul baseFormat = base_filter_format(internalFormat); 190147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { 191147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(internalFormat)"); 192147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 193147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 194147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 195147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { 196147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(width)"); 197147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 198147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 199147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { 200147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(height)"); 201147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 202147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 203147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 204147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (!_mesa_is_legal_format_and_type(format, type) || 205147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_COLOR_INDEX || 206147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_STENCIL_INDEX || 207147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_DEPTH_COMPONENT || 208147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_INTENSITY || 209147b08328a2ccb0c1150feaf7871037683236e33Brian Paul type == GL_BITMAP) { 210147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(format or type)"); 211147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 212147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 213147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 214147b08328a2ccb0c1150feaf7871037683236e33Brian Paul components = _mesa_components_in_format(format); 215147b08328a2ccb0c1150feaf7871037683236e33Brian Paul assert(components > 0); /* this should have been caught earlier */ 216147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 217147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.Format = format; 218147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.InternalFormat = internalFormat; 219147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.Width = width; 220147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.Height = height; 221147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 222147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* Unpack filter image. We always store filters in RGBA format. */ 223147b08328a2ccb0c1150feaf7871037683236e33Brian Paul for (i = 0; i < height; i++) { 224147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLvoid *src = _mesa_image_address(&ctx->Unpack, image, width, 225147b08328a2ccb0c1150feaf7871037683236e33Brian Paul height, format, type, 0, i, 0); 226147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat *dst = ctx->Convolution2D.Filter + i * width * 4; 227147b08328a2ccb0c1150feaf7871037683236e33Brian Paul _mesa_unpack_float_color_span(ctx, width, GL_RGBA, dst, 228147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format, type, src, &ctx->Unpack, 229147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 0, GL_FALSE); 230147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 231147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 232147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* apply scale and bias */ 233147b08328a2ccb0c1150feaf7871037683236e33Brian Paul { 234147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[1]; 235147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[1]; 236147b08328a2ccb0c1150feaf7871037683236e33Brian Paul for (i = 0; i < width * height * 4; i++) { 237147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat r = ctx->Convolution2D.Filter[i * 4 + 0]; 238147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat g = ctx->Convolution2D.Filter[i * 4 + 1]; 239147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat b = ctx->Convolution2D.Filter[i * 4 + 2]; 240147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat a = ctx->Convolution2D.Filter[i * 4 + 3]; 241147b08328a2ccb0c1150feaf7871037683236e33Brian Paul r = r * scale[0] + bias[0]; 242147b08328a2ccb0c1150feaf7871037683236e33Brian Paul g = g * scale[1] + bias[1]; 243147b08328a2ccb0c1150feaf7871037683236e33Brian Paul b = b * scale[2] + bias[2]; 244147b08328a2ccb0c1150feaf7871037683236e33Brian Paul a = a * scale[3] + bias[3]; 245147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.Filter[i * 4 + 0] = r; 246147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.Filter[i * 4 + 1] = g; 247147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.Filter[i * 4 + 2] = b; 248147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Convolution2D.Filter[i * 4 + 3] = a; 249147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 250147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 251147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 252147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 253147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 254147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 255147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) 256147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 257147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 258147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLuint c; 259147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 260147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameterf"); 261147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 262147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (target) { 263147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_1D: 264147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 0; 265147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 266147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_2D: 267147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 1; 268147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 269147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_SEPARABLE_2D: 270147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 2; 271147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 272147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 273147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(target)"); 274147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 275147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 276147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 277147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (pname) { 278147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_MODE: 279147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (param == (GLfloat) GL_REDUCE || 280147b08328a2ccb0c1150feaf7871037683236e33Brian Paul param == (GLfloat) GL_CONSTANT_BORDER || 281147b08328a2ccb0c1150feaf7871037683236e33Brian Paul param == (GLfloat) GL_REPLICATE_BORDER) { 282147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; 283147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 284147b08328a2ccb0c1150feaf7871037683236e33Brian Paul else { 285147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(params)"); 286147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 287147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 288147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 289147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 290147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(pname)"); 291147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 292147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 293147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 294147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 295147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 296147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 297147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) 298147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 299147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 300147b08328a2ccb0c1150feaf7871037683236e33Brian Paul struct gl_convolution_attrib *conv; 301147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLuint c; 302147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 303147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameterfv"); 304147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 305147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (target) { 306147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_1D: 307147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 0; 308147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution1D; 309147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 310147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_2D: 311147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 1; 312147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution2D; 313147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 314147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_SEPARABLE_2D: 315147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 2; 316147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Separable2D; 317147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 318147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 319147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(target)"); 320147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 321147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 322147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 323147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (pname) { 324147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_COLOR: 325147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(ctx->Pixel.ConvolutionBorderColor[c], params); 326147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 327147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_MODE: 328147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (params[0] == (GLfloat) GL_REDUCE || 329147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[0] == (GLfloat) GL_CONSTANT_BORDER || 330147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[0] == (GLfloat) GL_REPLICATE_BORDER) { 331147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; 332147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 333147b08328a2ccb0c1150feaf7871037683236e33Brian Paul else { 334147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(params)"); 335147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 336147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 337147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 338147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_SCALE: 339147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params); 340147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 341147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_BIAS: 342147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); 343147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 344147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 345147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(pname)"); 346147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 347147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 348147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 349147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 350147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 351147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 352147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) 353147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 354147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 355147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLuint c; 356147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 357147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameteri"); 358147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 359147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (target) { 360147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_1D: 361147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 0; 362147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 363147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_2D: 364147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 1; 365147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 366147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_SEPARABLE_2D: 367147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 2; 368147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 369147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 370147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(target)"); 371147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 372147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 373147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 374147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (pname) { 375147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_MODE: 376147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (param == (GLint) GL_REDUCE || 377147b08328a2ccb0c1150feaf7871037683236e33Brian Paul param == (GLint) GL_CONSTANT_BORDER || 378147b08328a2ccb0c1150feaf7871037683236e33Brian Paul param == (GLint) GL_REPLICATE_BORDER) { 379147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; 380147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 381147b08328a2ccb0c1150feaf7871037683236e33Brian Paul else { 382147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(params)"); 383147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 384147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 385147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 386147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 387147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(pname)"); 388147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 389147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 390147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 391147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 392147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 393147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 394147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) 395147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 396147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 397147b08328a2ccb0c1150feaf7871037683236e33Brian Paul struct gl_convolution_attrib *conv; 398147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLuint c; 399147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 400147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameteriv"); 401147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 402147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (target) { 403147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_1D: 404147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 0; 405147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution1D; 406147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 407147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_2D: 408147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 1; 409147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution2D; 410147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 411147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_SEPARABLE_2D: 412147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 2; 413147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Separable2D; 414147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 415147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 416147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(target)"); 417147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 418147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 419147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 420147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (pname) { 421147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_COLOR: 422147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderColor[c][0] = INT_TO_FLOAT(params[0]); 423147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderColor[c][1] = INT_TO_FLOAT(params[1]); 424147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderColor[c][2] = INT_TO_FLOAT(params[2]); 425147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderColor[c][3] = INT_TO_FLOAT(params[3]); 426147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 427147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_MODE: 428147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (params[0] == (GLint) GL_REDUCE || 429147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[0] == (GLint) GL_CONSTANT_BORDER || 430147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[0] == (GLint) GL_REPLICATE_BORDER) { 431147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; 432147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 433147b08328a2ccb0c1150feaf7871037683236e33Brian Paul else { 434147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(params)"); 435147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 436147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 437147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 438147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_SCALE: 439147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params); 440147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 441147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_BIAS: 442147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); 443147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 444147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 445147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(pname)"); 446147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 447147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 448147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 449147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 450147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 451147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 452147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width) 453147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 454147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLenum baseFormat; 455147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat rgba[MAX_CONVOLUTION_WIDTH][4]; 456147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 457147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyConvolutionFilter1D"); 458147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 459147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (target != GL_CONVOLUTION_1D) { 460147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(target)"); 461147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 462147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 463147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 464147b08328a2ccb0c1150feaf7871037683236e33Brian Paul baseFormat = base_filter_format(internalFormat); 465147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { 466147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(internalFormat)"); 467147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 468147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 469147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 470147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { 471147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter1D(width)"); 472147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 473147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 474147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 475147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* read pixels from framebuffer */ 476ba643a2094a1e844b6ce60f468057057557859ceBrian Paul gl_read_rgba_span(ctx, ctx->ReadBuffer, width, x, y, (GLchan (*)[4]) rgba); 477147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 478147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* store as convolution filter */ 479147b08328a2ccb0c1150feaf7871037683236e33Brian Paul _mesa_ConvolutionFilter1D(target, internalFormat, width, 480147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GL_RGBA, GL_UNSIGNED_BYTE, rgba); 481147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 482147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 483147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 484147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 485147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height) 486147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 487147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLenum baseFormat; 488147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLint i; 489147b08328a2ccb0c1150feaf7871037683236e33Brian Paul struct gl_pixelstore_attrib packSave; 490147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4]; 491147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 492147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyConvolutionFilter2D"); 493147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 494147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (target != GL_CONVOLUTION_2D) { 495147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(target)"); 496147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 497147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 498147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 499147b08328a2ccb0c1150feaf7871037683236e33Brian Paul baseFormat = base_filter_format(internalFormat); 500147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { 501147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(internalFormat)"); 502147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 503147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 504147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 505147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { 506147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(width)"); 507147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 508147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 509147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { 510147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(height)"); 511147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 512147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 513147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 514147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* read pixels from framebuffer */ 515147b08328a2ccb0c1150feaf7871037683236e33Brian Paul for (i = 0; i < height; i++) { 516147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_read_rgba_span(ctx, ctx->ReadBuffer, width, x, y + i, 517ba643a2094a1e844b6ce60f468057057557859ceBrian Paul (GLchan (*)[4]) rgba[i]); 518147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 519147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 520147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* 521147b08328a2ccb0c1150feaf7871037683236e33Brian Paul * store as convolution filter 522147b08328a2ccb0c1150feaf7871037683236e33Brian Paul */ 523147b08328a2ccb0c1150feaf7871037683236e33Brian Paul packSave = ctx->Unpack; /* save pixel packing params */ 524147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 525147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.Alignment = 1; 526147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH; 527147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.SkipPixels = 0; 528147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.SkipRows = 0; 529147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.ImageHeight = 0; 530147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.SkipImages = 0; 531147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.SwapBytes = GL_FALSE; 532147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack.LsbFirst = GL_FALSE; 533147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 534147b08328a2ccb0c1150feaf7871037683236e33Brian Paul _mesa_ConvolutionFilter2D(target, internalFormat, width, height, 535147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GL_RGBA, GL_UNSIGNED_BYTE, rgba); 536147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 537147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Unpack = packSave; /* restore pixel packing params */ 538147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 539147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 540147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 541147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 542147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid *image) 543147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 544f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul const struct gl_convolution_attrib *filter; 545f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul GLint row; 546147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 547147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionFilter"); 548147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 549147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (!_mesa_is_legal_format_and_type(format, type) || 550147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_COLOR_INDEX || 551147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_STENCIL_INDEX || 552147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_DEPTH_COMPONENT || 553147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_INTENSITY || 554147b08328a2ccb0c1150feaf7871037683236e33Brian Paul type == GL_BITMAP) { 555147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); 556147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 557147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 558147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 559f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul switch (target) { 560f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul case GL_CONVOLUTION_1D: 561f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul filter = &(ctx->Convolution1D); 562f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul break; 563f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul case GL_CONVOLUTION_2D: 564f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul filter = &(ctx->Convolution2D); 565f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul break; 566f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul default: 567f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(target)"); 568f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul return; 569f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul } 570f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 571f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul for (row = 0; row < filter->Height; row++) { 572f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul GLvoid *dst = _mesa_image_address( &ctx->Pack, image, filter->Width, 573f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul filter->Height, format, type, 574f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 0, row, 0); 575f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul const GLfloat *src = filter->Filter + row * filter->Width * 4; 576f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul /* XXX apply transfer ops or not? */ 577f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul _mesa_pack_float_rgba_span(ctx, filter->Width, 578f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul (const GLfloat (*)[4]) src, 579f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul format, type, dst, &ctx->Pack, 0); 580f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul } 581147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 582147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 583147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 584147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 585147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) 586147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 587147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 588147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const struct gl_convolution_attrib *conv; 589147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLuint c; 590147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 591147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionParameterfv"); 592147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 593147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (target) { 594147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_1D: 595147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 0; 596147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution1D; 597147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 598147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_2D: 599147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 1; 600147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution2D; 601147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 602147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_SEPARABLE_2D: 603147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 2; 604147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Separable2D; 605147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 606147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 607147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(target)"); 608147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 609147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 610147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 611147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (pname) { 612147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_COLOR: 613147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(params, ctx->Pixel.ConvolutionBorderColor[c]); 614147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 615147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_MODE: 616147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLfloat) ctx->Pixel.ConvolutionBorderMode[c]; 617147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 618147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_SCALE: 619147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(params, ctx->Pixel.ConvolutionFilterScale[c]); 620147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 621147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_BIAS: 622147b08328a2ccb0c1150feaf7871037683236e33Brian Paul COPY_4V(params, ctx->Pixel.ConvolutionFilterBias[c]); 623147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 624147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FORMAT: 625147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLfloat) conv->Format; 626147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 627147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_WIDTH: 628147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLfloat) conv->Width; 629147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 630147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_HEIGHT: 631147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLfloat) conv->Height; 632147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 633147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_MAX_CONVOLUTION_WIDTH: 634147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLfloat) ctx->Const.MaxConvolutionWidth; 635147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 636147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_MAX_CONVOLUTION_HEIGHT: 637147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLfloat) ctx->Const.MaxConvolutionHeight; 638147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 639147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 640147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(pname)"); 641147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 642147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 643147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 644147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 645147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 646147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 647147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) 648147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 649147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 650147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const struct gl_convolution_attrib *conv; 651147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLuint c; 652147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 653147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionParameteriv"); 654147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 655147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (target) { 656147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_1D: 657147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 0; 658147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution1D; 659147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 660147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_2D: 661147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 1; 662147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Convolution2D; 663147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 664147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_SEPARABLE_2D: 665147b08328a2ccb0c1150feaf7871037683236e33Brian Paul c = 2; 666147b08328a2ccb0c1150feaf7871037683236e33Brian Paul conv = &ctx->Separable2D; 667147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 668147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 669147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(target)"); 670147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 671147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 672147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 673147b08328a2ccb0c1150feaf7871037683236e33Brian Paul switch (pname) { 674147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_COLOR: 675147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[0] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][0]); 676147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[1] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][1]); 677147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[2] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][2]); 678147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[3] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][3]); 679147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 680147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_BORDER_MODE: 681147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLint) ctx->Pixel.ConvolutionBorderMode[c]; 682147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 683147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_SCALE: 684147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[0] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][0]; 685147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[1] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][1]; 686147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[2] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][2]; 687147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[3] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][3]; 688147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 689147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FILTER_BIAS: 690147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[0] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][0]; 691147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[1] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][1]; 692147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[2] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][2]; 693147b08328a2ccb0c1150feaf7871037683236e33Brian Paul params[3] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][3]; 694147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 695147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_FORMAT: 696147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLint) conv->Format; 697147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 698147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_WIDTH: 699147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLint) conv->Width; 700147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 701147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_CONVOLUTION_HEIGHT: 702147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLint) conv->Height; 703147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 704147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_MAX_CONVOLUTION_WIDTH: 705147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLint) ctx->Const.MaxConvolutionWidth; 706147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 707147b08328a2ccb0c1150feaf7871037683236e33Brian Paul case GL_MAX_CONVOLUTION_HEIGHT: 708147b08328a2ccb0c1150feaf7871037683236e33Brian Paul *params = (GLint) ctx->Const.MaxConvolutionHeight; 709147b08328a2ccb0c1150feaf7871037683236e33Brian Paul break; 710147b08328a2ccb0c1150feaf7871037683236e33Brian Paul default: 711147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(pname)"); 712147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 713147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 714147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 715147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 716147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 717147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 718147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) 719147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 720f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; 721f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul const struct gl_convolution_attrib *filter; 722147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 723147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetSeparableFilter"); 724147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 725147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (target != GL_SEPARABLE_2D) { 726147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter(target)"); 727147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 728147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 729147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 730147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (!_mesa_is_legal_format_and_type(format, type) || 731147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_COLOR_INDEX || 732147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_STENCIL_INDEX || 733147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_DEPTH_COMPONENT || 734147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_INTENSITY || 735147b08328a2ccb0c1150feaf7871037683236e33Brian Paul type == GL_BITMAP) { 736147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); 737147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 738147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 739147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 740f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul filter = &ctx->Separable2D; 741f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 742f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul /* Row filter */ 743f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul { 744f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul GLvoid *dst = _mesa_image_address( &ctx->Pack, row, filter->Width, 745f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul filter->Height, format, type, 746f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 0, 0, 0); 747f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul _mesa_pack_float_rgba_span(ctx, filter->Width, 748f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul (const GLfloat (*)[4]) filter->Filter, 749f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul format, type, dst, &ctx->Pack, 0); 750f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul } 751f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 752f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul /* Column filter */ 753f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul { 754f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul GLvoid *dst = _mesa_image_address( &ctx->Pack, column, filter->Width, 755f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 1, format, type, 756f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 0, 0, 0); 757f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul const GLfloat *src = filter->Filter + colStart; 758f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul _mesa_pack_float_rgba_span(ctx, filter->Height, 759f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul (const GLfloat (*)[4]) src, 760f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul format, type, dst, &ctx->Pack, 0); 761f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul } 762f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul 763f75d697c0319e43ac15b42c8bbd5e956286c7005Brian Paul (void) span; /* unused at this time */ 764147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 765147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 766147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 767147b08328a2ccb0c1150feaf7871037683236e33Brian Paulvoid 768147b08328a2ccb0c1150feaf7871037683236e33Brian Paul_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) 769147b08328a2ccb0c1150feaf7871037683236e33Brian Paul{ 770147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; 771147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLenum baseFormat; 772147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GET_CURRENT_CONTEXT(ctx); 773147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glSeparableFilter2D"); 774147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 775147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (target != GL_SEPARABLE_2D) { 776147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(target)"); 777147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 778147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 779147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 780147b08328a2ccb0c1150feaf7871037683236e33Brian Paul baseFormat = base_filter_format(internalFormat); 781147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { 782147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(internalFormat)"); 783147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 784147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 785147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 786147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { 787147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(width)"); 788147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 789147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 790147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { 791147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(height)"); 792147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 793147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 794147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 795147b08328a2ccb0c1150feaf7871037683236e33Brian Paul if (!_mesa_is_legal_format_and_type(format, type) || 796147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_COLOR_INDEX || 797147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_STENCIL_INDEX || 798147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_DEPTH_COMPONENT || 799147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format == GL_INTENSITY || 800147b08328a2ccb0c1150feaf7871037683236e33Brian Paul type == GL_BITMAP) { 801147b08328a2ccb0c1150feaf7871037683236e33Brian Paul gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(format or type)"); 802147b08328a2ccb0c1150feaf7871037683236e33Brian Paul return; 803147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 804147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 805147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Format = format; 806147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.InternalFormat = internalFormat; 807147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Width = width; 808147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Height = height; 809147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 810147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* unpack row filter */ 811147b08328a2ccb0c1150feaf7871037683236e33Brian Paul _mesa_unpack_float_color_span(ctx, width, GL_RGBA, 812147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter, 813147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format, type, row, &ctx->Unpack, 814147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 0, GL_FALSE); 815147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 816147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* apply scale and bias */ 817147b08328a2ccb0c1150feaf7871037683236e33Brian Paul { 818147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[2]; 819147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[2]; 820147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLint i; 821147b08328a2ccb0c1150feaf7871037683236e33Brian Paul for (i = 0; i < width; i++) { 822147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat r = ctx->Separable2D.Filter[i * 4 + 0]; 823147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat g = ctx->Separable2D.Filter[i * 4 + 1]; 824147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat b = ctx->Separable2D.Filter[i * 4 + 2]; 825147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat a = ctx->Separable2D.Filter[i * 4 + 3]; 826147b08328a2ccb0c1150feaf7871037683236e33Brian Paul r = r * scale[0] + bias[0]; 827147b08328a2ccb0c1150feaf7871037683236e33Brian Paul g = g * scale[1] + bias[1]; 828147b08328a2ccb0c1150feaf7871037683236e33Brian Paul b = b * scale[2] + bias[2]; 829147b08328a2ccb0c1150feaf7871037683236e33Brian Paul a = a * scale[3] + bias[3]; 830147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 0] = r; 831147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 1] = g; 832147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 2] = b; 833147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 3] = a; 834147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 835147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 836147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 837147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* unpack column filter */ 838147b08328a2ccb0c1150feaf7871037683236e33Brian Paul _mesa_unpack_float_color_span(ctx, width, GL_RGBA, 839147b08328a2ccb0c1150feaf7871037683236e33Brian Paul &ctx->Separable2D.Filter[colStart], 840147b08328a2ccb0c1150feaf7871037683236e33Brian Paul format, type, column, &ctx->Unpack, 841147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 0, GL_FALSE); 842147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 843147b08328a2ccb0c1150feaf7871037683236e33Brian Paul /* apply scale and bias */ 844147b08328a2ccb0c1150feaf7871037683236e33Brian Paul { 845147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[2]; 846147b08328a2ccb0c1150feaf7871037683236e33Brian Paul const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[2]; 847147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLint i; 848147b08328a2ccb0c1150feaf7871037683236e33Brian Paul for (i = 0; i < width; i++) { 849147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat r = ctx->Separable2D.Filter[i * 4 + 0 + colStart]; 850147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat g = ctx->Separable2D.Filter[i * 4 + 1 + colStart]; 851147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat b = ctx->Separable2D.Filter[i * 4 + 2 + colStart]; 852147b08328a2ccb0c1150feaf7871037683236e33Brian Paul GLfloat a = ctx->Separable2D.Filter[i * 4 + 3 + colStart]; 853147b08328a2ccb0c1150feaf7871037683236e33Brian Paul r = r * scale[0] + bias[0]; 854147b08328a2ccb0c1150feaf7871037683236e33Brian Paul g = g * scale[1] + bias[1]; 855147b08328a2ccb0c1150feaf7871037683236e33Brian Paul b = b * scale[2] + bias[2]; 856147b08328a2ccb0c1150feaf7871037683236e33Brian Paul a = a * scale[3] + bias[3]; 857147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 0 + colStart] = r; 858147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 1 + colStart] = g; 859147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 2 + colStart] = b; 860147b08328a2ccb0c1150feaf7871037683236e33Brian Paul ctx->Separable2D.Filter[i * 4 + 3 + colStart] = a; 861147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 862147b08328a2ccb0c1150feaf7871037683236e33Brian Paul } 863147b08328a2ccb0c1150feaf7871037683236e33Brian Paul} 864147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 865147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 866147b08328a2ccb0c1150feaf7871037683236e33Brian Paul/**********************************************************************/ 867147b08328a2ccb0c1150feaf7871037683236e33Brian Paul/*** image convolution functions ***/ 868147b08328a2ccb0c1150feaf7871037683236e33Brian Paul/**********************************************************************/ 869147b08328a2ccb0c1150feaf7871037683236e33Brian Paul 870d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 871d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_1d_reduce(GLint srcWidth, const GLfloat src[][4], 872d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, const GLfloat filter[][4], 873d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4]) 874cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 8757e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint dstWidth; 876cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLint i, n; 877cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 8787e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (filterWidth >= 1) 8797e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstWidth = srcWidth - (filterWidth - 1); 8807e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul else 8817e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstWidth = srcWidth; 8827e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 883cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul if (dstWidth <= 0) 884cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul return; /* null result */ 885cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 886cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul for (i = 0; i < dstWidth; i++) { 887cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumR = 0.0; 888cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumG = 0.0; 889cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumB = 0.0; 890cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumA = 0.0; 891cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul for (n = 0; n < filterWidth; n++) { 892cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumR += src[i + n][RCOMP] * filter[n][RCOMP]; 893cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumG += src[i + n][GCOMP] * filter[n][GCOMP]; 894cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumB += src[i + n][BCOMP] * filter[n][BCOMP]; 895cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumA += src[i + n][ACOMP] * filter[n][ACOMP]; 896cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 897cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][RCOMP] = sumR; 898cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][GCOMP] = sumG; 899cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][BCOMP] = sumB; 900cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][ACOMP] = sumA; 901cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 902cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 903cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 904cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 905d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 906d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_1d_constant(GLint srcWidth, const GLfloat src[][4], 907d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, const GLfloat filter[][4], 908d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4], 909d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat borderColor[4]) 910cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 911cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul const GLint halfFilterWidth = filterWidth / 2; 912cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLint i, n; 913cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 914cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul for (i = 0; i < srcWidth; i++) { 915cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumR = 0.0; 916cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumG = 0.0; 917cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumB = 0.0; 918cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumA = 0.0; 919cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul for (n = 0; n < filterWidth; n++) { 920cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul if (i + n < halfFilterWidth || i + n - halfFilterWidth >= srcWidth) { 921cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumR += borderColor[RCOMP] * filter[n][RCOMP]; 922cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumG += borderColor[GCOMP] * filter[n][GCOMP]; 923cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumB += borderColor[BCOMP] * filter[n][BCOMP]; 924cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumA += borderColor[ACOMP] * filter[n][ACOMP]; 925cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 926cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul else { 927cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP]; 928cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP]; 929cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP]; 930cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP]; 931cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 932cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 933cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][RCOMP] = sumR; 934cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][GCOMP] = sumG; 935cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][BCOMP] = sumB; 936cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][ACOMP] = sumA; 937cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 938cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 939cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 940cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 941d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 942d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_1d_replicate(GLint srcWidth, const GLfloat src[][4], 943d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, const GLfloat filter[][4], 944d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4]) 945cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 946cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul const GLint halfFilterWidth = filterWidth / 2; 947cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLint i, n; 948cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 949cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul for (i = 0; i < srcWidth; i++) { 950cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumR = 0.0; 951cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumG = 0.0; 952cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumB = 0.0; 953cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul GLfloat sumA = 0.0; 954cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul for (n = 0; n < filterWidth; n++) { 955cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul if (i + n < halfFilterWidth) { 956cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumR += src[0][RCOMP] * filter[n][RCOMP]; 957cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumG += src[0][GCOMP] * filter[n][GCOMP]; 958cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumB += src[0][BCOMP] * filter[n][BCOMP]; 959cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumA += src[0][ACOMP] * filter[n][ACOMP]; 960cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 961cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul else if (i + n - halfFilterWidth >= srcWidth) { 962cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumR += src[srcWidth - 1][RCOMP] * filter[n][RCOMP]; 963cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumG += src[srcWidth - 1][GCOMP] * filter[n][GCOMP]; 964cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumB += src[srcWidth - 1][BCOMP] * filter[n][BCOMP]; 965cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumA += src[srcWidth - 1][ACOMP] * filter[n][ACOMP]; 966cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 967cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul else { 968cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP]; 969cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP]; 970cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP]; 971cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP]; 972cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 973cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 974cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][RCOMP] = sumR; 975cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][GCOMP] = sumG; 976cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][BCOMP] = sumB; 977cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul dest[i][ACOMP] = sumA; 978cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 979cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 980cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 981cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 982d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 983d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_2d_reduce(GLint srcWidth, GLint srcHeight, 984d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat src[][4], 985d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, GLint filterHeight, 986d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat filter[][4], 987d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4]) 988cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 9897e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint dstWidth, dstHeight; 990d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint i, j, n, m; 991d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 9927e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (filterWidth >= 1) 9937e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstWidth = srcWidth - (filterWidth - 1); 9947e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul else 9957e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstWidth = srcWidth; 9967e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 9977e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (filterHeight >= 1) 9987e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstHeight = srcHeight - (filterHeight - 1); 9997e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul else 10007e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstHeight = srcHeight; 10017e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 1002d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul if (dstWidth <= 0 || dstHeight <= 0) 1003d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul return; 1004d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1005d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (j = 0; j < dstHeight; j++) { 1006d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (i = 0; i < dstWidth; i++) { 1007d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumR = 0.0; 1008d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumG = 0.0; 1009d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumB = 0.0; 1010d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumA = 0.0; 1011d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (m = 0; m < filterHeight; m++) { 1012d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (n = 0; n < filterWidth; n++) { 1013d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint k = (j + m) * srcWidth + i + n; 1014d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint f = m * filterWidth + n; 1015d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumR += src[k][RCOMP] * filter[f][RCOMP]; 1016d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumG += src[k][GCOMP] * filter[f][GCOMP]; 1017d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumB += src[k][BCOMP] * filter[f][BCOMP]; 1018d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumA += src[k][ACOMP] * filter[f][ACOMP]; 1019d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 1020cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1021d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * dstWidth + i][RCOMP] = sumR; 1022d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * dstWidth + i][GCOMP] = sumG; 1023d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * dstWidth + i][BCOMP] = sumB; 1024d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * dstWidth + i][ACOMP] = sumA; 1025cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1026cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1027cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 1028cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1029cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1030d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 1031d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_2d_constant(GLint srcWidth, GLint srcHeight, 1032d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat src[][4], 1033d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, GLint filterHeight, 1034d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat filter[][4], 1035d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4], 1036d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat borderColor[4]) 1037cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 1038cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul const GLint halfFilterWidth = filterWidth / 2; 1039d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint halfFilterHeight = filterHeight / 2; 1040d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint i, j, n, m; 1041cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1042d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (j = 0; j < srcHeight; j++) { 1043d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (i = 0; i < srcWidth; i++) { 1044d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumR = 0.0; 1045d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumG = 0.0; 1046d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumB = 0.0; 1047d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumA = 0.0; 1048d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (m = 0; m < filterHeight; m++) { 1049d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (n = 0; n < filterWidth; n++) { 1050d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint f = m * filterWidth + n; 1051d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint is = i + n - halfFilterWidth; 1052d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint js = j + m - halfFilterHeight; 1053d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul if (is < 0 || is >= srcWidth || 1054d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul js < 0 || js >= srcHeight) { 1055d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumR += borderColor[RCOMP] * filter[f][RCOMP]; 1056d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumG += borderColor[GCOMP] * filter[f][GCOMP]; 1057d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumB += borderColor[BCOMP] * filter[f][BCOMP]; 1058d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumA += borderColor[ACOMP] * filter[f][ACOMP]; 1059d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 1060d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul else { 1061d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint k = js * srcWidth + is; 1062d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumR += src[k][RCOMP] * filter[f][RCOMP]; 1063d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumG += src[k][GCOMP] * filter[f][GCOMP]; 1064d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumB += src[k][BCOMP] * filter[f][BCOMP]; 1065d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumA += src[k][ACOMP] * filter[f][ACOMP]; 1066d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 1067cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1068cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1069d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][RCOMP] = sumR; 1070d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][GCOMP] = sumG; 1071d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][BCOMP] = sumB; 1072d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][ACOMP] = sumA; 1073cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1074cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1075cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 1076cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1077cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1078d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 1079d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_2d_replicate(GLint srcWidth, GLint srcHeight, 1080d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat src[][4], 1081d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, GLint filterHeight, 1082d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat filter[][4], 1083d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4]) 1084cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 1085cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul const GLint halfFilterWidth = filterWidth / 2; 1086d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint halfFilterHeight = filterHeight / 2; 1087d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint i, j, n, m; 1088d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1089d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (j = 0; j < srcHeight; j++) { 1090d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (i = 0; i < srcWidth; i++) { 1091d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumR = 0.0; 1092d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumG = 0.0; 1093d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumB = 0.0; 1094d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumA = 0.0; 1095d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (m = 0; m < filterHeight; m++) { 1096d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (n = 0; n < filterWidth; n++) { 1097d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint f = m * filterWidth + n; 1098d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint is = i + n - halfFilterWidth; 1099d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint js = j + m - halfFilterHeight; 1100d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint k; 1101d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul if (is < 0) 1102d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul is = 0; 1103d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul else if (is >= srcWidth) 1104d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul is = srcWidth - 1; 1105d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul if (js < 0) 1106d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul js = 0; 1107d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul else if (js >= srcHeight) 1108d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul js = srcHeight - 1; 1109d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul k = js * srcWidth + is; 1110d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumR += src[k][RCOMP] * filter[f][RCOMP]; 1111d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumG += src[k][GCOMP] * filter[f][GCOMP]; 1112d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumB += src[k][BCOMP] * filter[f][BCOMP]; 1113d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumA += src[k][ACOMP] * filter[f][ACOMP]; 1114cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1115cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1116d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][RCOMP] = sumR; 1117d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][GCOMP] = sumG; 1118d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][BCOMP] = sumB; 1119d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul dest[j * srcWidth + i][ACOMP] = sumA; 1120cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1121cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1122cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 1123cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1124cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1125d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 1126d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_sep_reduce(GLint srcWidth, GLint srcHeight, 1127d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat src[][4], 1128d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, GLint filterHeight, 1129d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat rowFilt[][4], 1130d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat colFilt[][4], 1131d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4]) 1132cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 11337e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint dstWidth, dstHeight; 1134d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint i, j, n, m; 11357e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 11367e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (filterWidth >= 1) 11377e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstWidth = srcWidth - (filterWidth - 1); 11387e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul else 11397e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstWidth = srcWidth; 11407e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 11417e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (filterHeight >= 1) 11427e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstHeight = srcHeight - (filterHeight - 1); 11437e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul else 11447e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dstHeight = srcHeight; 11457e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 11467e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (dstWidth <= 0 || dstHeight <= 0) 11477e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul return; 11487e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 11497e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul for (j = 0; j < dstHeight; j++) { 11507e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul for (i = 0; i < dstWidth; i++) { 1151d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumR = 0.0; 1152d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumG = 0.0; 1153d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumB = 0.0; 1154d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumA = 0.0; 1155d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (m = 0; m < filterHeight; m++) { 1156d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (n = 0; n < filterWidth; n++) { 11577e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint k = (j + m) * srcWidth + i + n; 11587e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; 11597e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; 11607e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; 11617e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; 1162cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1163cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 11647e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * dstWidth + i][RCOMP] = sumR; 11657e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * dstWidth + i][GCOMP] = sumG; 11667e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * dstWidth + i][BCOMP] = sumB; 11677e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * dstWidth + i][ACOMP] = sumA; 1168cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1169cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1170cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 1171cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1172cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1173d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 1174d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_sep_constant(GLint srcWidth, GLint srcHeight, 1175d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat src[][4], 1176d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, GLint filterHeight, 1177d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat rowFilt[][4], 1178d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat colFilt[][4], 1179d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4], 1180d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat borderColor[4]) 1181cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 1182cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul const GLint halfFilterWidth = filterWidth / 2; 1183d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint halfFilterHeight = filterHeight / 2; 1184d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint i, j, n, m; 11857e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 1186d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (j = 0; j < srcHeight; j++) { 1187d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (i = 0; i < srcWidth; i++) { 1188d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumR = 0.0; 1189d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumG = 0.0; 1190d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumB = 0.0; 1191d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumA = 0.0; 1192d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (m = 0; m < filterHeight; m++) { 1193d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (n = 0; n < filterWidth; n++) { 11947e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul const GLint is = i + n - halfFilterWidth; 11957e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul const GLint js = j + m - halfFilterHeight; 11967e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (is < 0 || is >= srcWidth || 11977e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul js < 0 || js >= srcHeight) { 1198d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; 1199d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; 1200d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; 1201d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; 1202d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 1203d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul else { 12047e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint k = js * srcWidth + is; 1205d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; 1206d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; 1207d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; 1208d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; 1209d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 12107e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul 1211cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1212cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 12137e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][RCOMP] = sumR; 12147e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][GCOMP] = sumG; 12157e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][BCOMP] = sumB; 12167e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][ACOMP] = sumA; 1217cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1218cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1219cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 1220cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1221cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul 1222d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulstatic void 1223d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulconvolve_sep_replicate(GLint srcWidth, GLint srcHeight, 1224d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat src[][4], 1225d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint filterWidth, GLint filterHeight, 1226d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat rowFilt[][4], 1227d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat colFilt[][4], 1228d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat dest[][4]) 1229cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{ 1230cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul const GLint halfFilterWidth = filterWidth / 2; 1231d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLint halfFilterHeight = filterHeight / 2; 1232d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLint i, j, n, m; 1233d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1234d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (j = 0; j < srcHeight; j++) { 1235d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (i = 0; i < srcWidth; i++) { 1236d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumR = 0.0; 1237d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumG = 0.0; 1238d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumB = 0.0; 1239d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLfloat sumA = 0.0; 1240d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (m = 0; m < filterHeight; m++) { 1241d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul for (n = 0; n < filterWidth; n++) { 12427e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint is = i + n - halfFilterWidth; 12437e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint js = j + m - halfFilterHeight; 12447e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul GLint k; 12457e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (is < 0) 12467e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul is = 0; 12477e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul else if (is >= srcWidth) 12487e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul is = srcWidth - 1; 12497e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul if (js < 0) 12507e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul js = 0; 12517e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul else if (js >= srcHeight) 12527e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul js = srcHeight - 1; 12537e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul k = js * srcWidth + is; 12547e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; 12557e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; 12567e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; 12577e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; 1258cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1259cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 12607e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][RCOMP] = sumR; 12617e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][GCOMP] = sumG; 12627e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][BCOMP] = sumB; 12637e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul dest[j * srcWidth + i][ACOMP] = sumA; 1264cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1265d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 1266d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul} 1267d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1268d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1269d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1270d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulvoid 1271d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width, 1272d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat *srcImage, GLfloat *dstImage) 1273d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul{ 1274d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul switch (ctx->Pixel.ConvolutionBorderMode[0]) { 1275d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_REDUCE: 1276d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_1d_reduce(*width, (const GLfloat (*)[4]) srcImage, 1277d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution1D.Width, 1278d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) ctx->Convolution1D.Filter, 1279d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage); 12807e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1); 1281d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1282d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_CONSTANT_BORDER: 1283d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_1d_constant(*width, (const GLfloat (*)[4]) srcImage, 1284d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution1D.Width, 1285d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) ctx->Convolution1D.Filter, 1286d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage, 1287d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Pixel.ConvolutionBorderColor[0]); 1288d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1289d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_REPLICATE_BORDER: 1290d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_1d_replicate(*width, (const GLfloat (*)[4]) srcImage, 1291d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution1D.Width, 1292d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) ctx->Convolution1D.Filter, 1293d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage); 1294d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1295d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul default: 1296d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ; 1297d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 1298d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul} 1299d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1300d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1301d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulvoid 1302d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height, 1303d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat *srcImage, GLfloat *dstImage) 1304d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul{ 1305d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul switch (ctx->Pixel.ConvolutionBorderMode[1]) { 1306d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_REDUCE: 1307d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_2d_reduce(*width, *height, 1308d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) srcImage, 1309d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution2D.Width, 1310d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution2D.Height, 1311d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) ctx->Convolution2D.Filter, 1312d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage); 13137e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1); 13147e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1); 1315d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1316d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_CONSTANT_BORDER: 1317d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_2d_constant(*width, *height, 1318d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) srcImage, 1319d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution2D.Width, 1320d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution2D.Height, 1321d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) ctx->Convolution2D.Filter, 1322d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage, 1323d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Pixel.ConvolutionBorderColor[1]); 1324d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1325d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_REPLICATE_BORDER: 1326d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_2d_replicate(*width, *height, 1327d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) srcImage, 1328d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution2D.Width, 1329d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Convolution2D.Height, 1330d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4])ctx->Convolution2D.Filter, 1331d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage); 1332d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1333d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul default: 1334d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ; 1335d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul } 1336d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul} 1337d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1338d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1339d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paulvoid 1340d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul_mesa_convolve_sep_image(const GLcontext *ctx, 1341d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul GLsizei *width, GLsizei *height, 1342d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat *srcImage, GLfloat *dstImage) 1343d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul{ 1344d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat *rowFilter = ctx->Separable2D.Filter; 1345d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul const GLfloat *colFilter = rowFilter + 4 * MAX_CONVOLUTION_WIDTH; 1346d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul 1347d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul switch (ctx->Pixel.ConvolutionBorderMode[2]) { 1348d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_REDUCE: 1349d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_sep_reduce(*width, *height, 1350d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) srcImage, 13517e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul ctx->Separable2D.Width, 13527e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul ctx->Separable2D.Height, 1353d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) rowFilter, 1354d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) colFilter, 1355d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage); 13567e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1); 13577e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1); 1358d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1359d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_CONSTANT_BORDER: 1360d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_sep_constant(*width, *height, 1361d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) srcImage, 13627e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul ctx->Separable2D.Width, 13637e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul ctx->Separable2D.Height, 1364d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) rowFilter, 1365d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) colFilter, 1366d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage, 1367d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ctx->Pixel.ConvolutionBorderColor[2]); 1368d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1369d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul case GL_REPLICATE_BORDER: 1370d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul convolve_sep_replicate(*width, *height, 1371d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) srcImage, 13727e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul ctx->Separable2D.Width, 13737e70874420266fb81bed13c8464ee4c0309d75b2Brian Paul ctx->Separable2D.Height, 1374d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) rowFilter, 1375d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (const GLfloat (*)[4]) colFilter, 1376d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul (GLfloat (*)[4]) dstImage); 1377d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul break; 1378d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul default: 1379d4b799b60c693ecebbbdcdb3fd6931a78b7a0e30Brian Paul ; 1380cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul } 1381cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul} 1382