convolve.c revision cc8e37ffb393c892bbbf8850fef0e208c71d00f4
1cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul/* $Id: convolve.c,v 1.1 2000/07/12 13:00:09 brianp Exp $ */
2cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
3cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul/*
4cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Mesa 3-D graphics library
5cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * Version:  3.3
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"
40cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#include "types.h"
41cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#endif
42cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
43cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
44cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
45cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_1d_reduce(GLint srcWidth, const GLfloat src[][4],
46cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                         GLint filterWidth, const GLfloat filter[][4],
47cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                         GLfloat dest[][4])
48cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
49cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint dstWidth = srcWidth - (filterWidth - 1);
50cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n;
51cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
52cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   if (dstWidth <= 0)
53cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      return;  /* null result */
54cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
55cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < dstWidth; i++) {
56cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
57cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
58cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
59cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
60cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (n = 0; n < filterWidth; n++) {
61cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         sumR += src[i + n][RCOMP] * filter[n][RCOMP];
62cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         sumG += src[i + n][GCOMP] * filter[n][GCOMP];
63cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         sumB += src[i + n][BCOMP] * filter[n][BCOMP];
64cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         sumA += src[i + n][ACOMP] * filter[n][ACOMP];
65cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
66cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
67cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
68cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
69cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
70cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
71cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
72cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
73cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
74cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
75cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_1d_constant(GLint srcWidth, const GLfloat src[][4],
76cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                           GLint filterWidth, const GLfloat filter[][4],
77cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                           const GLfloat borderColor[4], GLfloat dest[][4])
78cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
79cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint halfFilterWidth = filterWidth / 2;
80cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n;
81cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
82cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < srcWidth; i++) {
83cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
84cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
85cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
86cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
87cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (n = 0; n < filterWidth; n++) {
88cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         if (i + n < halfFilterWidth || i + n - halfFilterWidth >= srcWidth) {
89cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumR += borderColor[RCOMP] * filter[n][RCOMP];
90cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumG += borderColor[GCOMP] * filter[n][GCOMP];
91cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumB += borderColor[BCOMP] * filter[n][BCOMP];
92cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumA += borderColor[ACOMP] * filter[n][ACOMP];
93cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
94cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         else {
95cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
96cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
97cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
98cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
99cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
100cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
101cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
102cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
103cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
104cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
105cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
106cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
107cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
108cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
109cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
110cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_1d_replicate(GLint srcWidth, const GLfloat src[][4],
111cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            GLint filterWidth, const GLfloat filter[][4],
112cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            GLfloat dest[][4])
113cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
114cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint halfFilterWidth = filterWidth / 2;
115cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n;
116cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
117cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < srcWidth; i++) {
118cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
119cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
120cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
121cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
122cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (n = 0; n < filterWidth; n++) {
123cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         if (i + n < halfFilterWidth) {
124cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumR += src[0][RCOMP] * filter[n][RCOMP];
125cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumG += src[0][GCOMP] * filter[n][GCOMP];
126cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumB += src[0][BCOMP] * filter[n][BCOMP];
127cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumA += src[0][ACOMP] * filter[n][ACOMP];
128cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
129cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         else if (i + n - halfFilterWidth >= srcWidth) {
130cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumR += src[srcWidth - 1][RCOMP] * filter[n][RCOMP];
131cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumG += src[srcWidth - 1][GCOMP] * filter[n][GCOMP];
132cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumB += src[srcWidth - 1][BCOMP] * filter[n][BCOMP];
133cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumA += src[srcWidth - 1][ACOMP] * filter[n][ACOMP];
134cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
135cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         else {
136cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
137cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
138cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
139cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
140cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
141cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
142cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
143cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
144cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
145cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
146cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
147cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
148cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
149cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
150cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul/*
151cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * <src> is the source image width width = srcWidth, height = filterHeight.
152cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * <filter> has width <filterWidth> and height <filterHeight>.
153cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul * <dst> is a 1-D image span of width <srcWidth> - (<filterWidth> - 1).
154cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul */
155cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
156cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_2d_reduce(GLint srcWidth, GLint srcHeight,
157cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                         const GLfloat src[][4],
158cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                         GLint filterWidth, GLint filterHeight,
159cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                         const GLfloat filter[][4],
160cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                         GLfloat dest[][4])
161cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
162cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint dstWidth = srcWidth - (filterWidth - 1);
163cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n, m;
164cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
165cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   if (dstWidth <= 0)
166cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      return;  /* null result */
167cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
168cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   /* XXX todo */
169cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < dstWidth; i++) {
170cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
171cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
172cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
173cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
174cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (n = 0; n < filterHeight; n++) {
175cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         for (m = 0; m < filterWidth; m++) {
176cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            const GLint k = n * srcWidth + i + m;
177cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumR += src[k][RCOMP] * filter[n][RCOMP];
178cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumG += src[k][GCOMP] * filter[n][GCOMP];
179cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumB += src[k][BCOMP] * filter[n][BCOMP];
180cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            sumA += src[k][ACOMP] * filter[n][ACOMP];
181cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
182cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
183cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
184cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
185cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
186cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
187cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
188cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
189cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
190cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
191cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
192cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_2d_constant(GLint srcWidth, GLint srcHeight,
193cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                           const GLfloat src[][4],
194cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                           GLint filterWidth, GLint filterHeight,
195cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                           const GLfloat filter[][4],
196cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                           GLfloat dest[][4],
197cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                           const GLfloat borderColor[4])
198cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
199cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint halfFilterWidth = filterWidth / 2;
200cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n, m;
201cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
202cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < srcWidth; i++) {
203cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
204cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
205cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
206cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
207cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (m = 0; m < filterHeight; m++) {
208cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         const GLfloat (*filterRow)[4] = filter + m * filterWidth;
209cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         for (n = 0; n < filterWidth; n++) {
210cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            if (i + n < halfFilterWidth ||
211cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                i + n - halfFilterWidth >= srcWidth) {
212cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += borderColor[RCOMP] * filterRow[n][RCOMP];
213cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += borderColor[GCOMP] * filterRow[n][GCOMP];
214cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += borderColor[BCOMP] * filterRow[n][BCOMP];
215cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += borderColor[ACOMP] * filterRow[n][ACOMP];
216cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
217cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            else {
218cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + i + n - halfFilterWidth;
219cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * filterRow[n][RCOMP];
220cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * filterRow[n][GCOMP];
221cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * filterRow[n][BCOMP];
222cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * filterRow[n][ACOMP];
223cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
224cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
225cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
226cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
227cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
228cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
229cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
230cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
231cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
232cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
233cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
234cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
235cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_2d_replicate(GLint srcWidth, GLint srcHeight,
236cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            const GLfloat src[][4],
237cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            GLint filterWidth, GLint filterHeight,
238cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            const GLfloat filter[][4],
239cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            GLfloat dest[][4])
240cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
241cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint halfFilterWidth = filterWidth / 2;
242cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n, m;
243cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
244cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < srcWidth; i++) {
245cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
246cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
247cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
248cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
249cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (m = 0; m < filterHeight; m++) {
250cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         const GLfloat (*filterRow)[4] = filter + m * filterWidth;
251cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         for (n = 0; n < filterWidth; n++) {
252cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            if (i + n < halfFilterWidth) {
253cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + 0;
254cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * filterRow[n][RCOMP];
255cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * filterRow[n][GCOMP];
256cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * filterRow[n][BCOMP];
257cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * filterRow[n][ACOMP];
258cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
259cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            else if (i + n - halfFilterWidth >= srcWidth) {
260cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + srcWidth - 1;
261cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * filterRow[n][RCOMP];
262cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * filterRow[n][GCOMP];
263cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * filterRow[n][BCOMP];
264cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * filterRow[n][ACOMP];
265cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
266cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            else {
267cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + i + n - halfFilterWidth;
268cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * filterRow[n][RCOMP];
269cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * filterRow[n][GCOMP];
270cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * filterRow[n][BCOMP];
271cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * filterRow[n][ACOMP];
272cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
273cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
274cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
275cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
276cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
277cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
278cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
279cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
280cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
281cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
282cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
283cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
284cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_sep_constant(GLint srcWidth, GLint srcHeight,
285cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            const GLfloat src[][4],
286cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            GLint filterWidth, GLint filterHeight,
287cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            const GLfloat rowFilt[][4],
288cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            const GLfloat colFilt[][4],
289cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            GLfloat dest[][4],
290cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                            const GLfloat borderColor[4])
291cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
292cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint halfFilterWidth = filterWidth / 2;
293cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n, m;
294cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
295cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < srcWidth; i++) {
296cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
297cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
298cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
299cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
300cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (m = 0; m < filterHeight; m++) {
301cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         for (n = 0; n < filterWidth; n++) {
302cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            if (i + n < halfFilterWidth ||
303cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                i + n - halfFilterWidth >= srcWidth) {
304cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
305cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
306cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
307cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
308cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
309cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            else {
310cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + i + n - halfFilterWidth;
311cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
312cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
313cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
314cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
315cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
316cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
317cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
318cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
319cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
320cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
321cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
322cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
323cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
324cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
325cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
326cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
327cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_sep_reduce(GLint srcWidth, GLint srcHeight,
328cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                          const GLfloat src[][4],
329cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                          GLint filterWidth, GLint filterHeight,
330cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                          const GLfloat rowFilt[][4],
331cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                          const GLfloat colFilt[][4],
332cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                          GLfloat dest[][4])
333cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
334cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#if 00
335cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint halfFilterWidth = filterWidth / 2;
336cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n, m;
337cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
338cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < srcWidth; i++) {
339cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
340cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
341cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
342cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
343cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (m = 0; m < filterHeight; m++) {
344cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         for (n = 0; n < filterWidth; n++) {
345cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            if (i + n < halfFilterWidth ||
346cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                i + n - halfFilterWidth >= srcWidth) {
347cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
348cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
349cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
350cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
351cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
352cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            else {
353cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + i + n - halfFilterWidth;
354cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
355cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
356cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
357cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
358cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
359cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
360cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
361cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
362cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
363cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
364cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
365cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
366cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul#endif
367cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
368cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
369cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
370cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paulvoid
371cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul_mesa_convolve_sep_replicate(GLint srcWidth, GLint srcHeight,
372cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                             const GLfloat src[][4],
373cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                             GLint filterWidth, GLint filterHeight,
374cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                             const GLfloat rowFilt[][4],
375cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                             const GLfloat colFilt[][4],
376cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul                             GLfloat dest[][4])
377cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul{
378cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   const GLint halfFilterWidth = filterWidth / 2;
379cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   GLint i, n, m;
380cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul
381cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   for (i = 0; i < srcWidth; i++) {
382cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumR = 0.0;
383cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumG = 0.0;
384cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumB = 0.0;
385cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      GLfloat sumA = 0.0;
386cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      for (m = 0; m < filterHeight; m++) {
387cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         for (n = 0; n < filterWidth; n++) {
388cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            if (i + n < halfFilterWidth) {
389cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + 0;
390cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
391cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
392cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
393cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
394cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
395cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            else if (i + n - halfFilterWidth >= srcWidth) {
396cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + srcWidth - 1;
397cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
398cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
399cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
400cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
401cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
402cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            else {
403cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               const GLint k = m * srcWidth + i + n - halfFilterWidth;
404cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
405cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
406cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
407cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul               sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
408cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul            }
409cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul         }
410cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      }
411cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][RCOMP] = sumR;
412cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][GCOMP] = sumG;
413cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][BCOMP] = sumB;
414cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul      dest[i][ACOMP] = sumA;
415cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul   }
416cc8e37ffb393c892bbbf8850fef0e208c71d00f4Brian Paul}
417