blob: 3471220dc75d12866ffecf473a0a5d2bde81c1fc [file] [log] [blame]
Brian Paul7e708742000-08-22 18:54:25 +00001/* $Id: convolve.c,v 1.3 2000/08/22 18:54:25 brianp Exp $ */
Brian Paulcc8e37f2000-07-12 13:00:09 +00002
3/*
4 * Mesa 3-D graphics library
Brian Pauld4b799b2000-08-21 14:24:30 +00005 * Version: 3.5
Brian Paulcc8e37f2000-07-12 13:00:09 +00006 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * Image convolution functions.
30 *
31 * Notes: filter kernel elements are indexed by <n> and <m> as in
32 * the GL spec.
33 */
34
35
36#ifdef PC_HEADER
37#include "all.h"
38#else
39#include "glheader.h"
Brian Pauld4b799b2000-08-21 14:24:30 +000040#include "convolve.h"
41#include "context.h"
Brian Paulcc8e37f2000-07-12 13:00:09 +000042#include "types.h"
43#endif
44
45
Brian Pauld4b799b2000-08-21 14:24:30 +000046static void
47convolve_1d_reduce(GLint srcWidth, const GLfloat src[][4],
48 GLint filterWidth, const GLfloat filter[][4],
49 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +000050{
Brian Paul7e708742000-08-22 18:54:25 +000051 GLint dstWidth;
Brian Paulcc8e37f2000-07-12 13:00:09 +000052 GLint i, n;
53
Brian Paul7e708742000-08-22 18:54:25 +000054 if (filterWidth >= 1)
55 dstWidth = srcWidth - (filterWidth - 1);
56 else
57 dstWidth = srcWidth;
58
Brian Paulcc8e37f2000-07-12 13:00:09 +000059 if (dstWidth <= 0)
60 return; /* null result */
61
62 for (i = 0; i < dstWidth; i++) {
63 GLfloat sumR = 0.0;
64 GLfloat sumG = 0.0;
65 GLfloat sumB = 0.0;
66 GLfloat sumA = 0.0;
67 for (n = 0; n < filterWidth; n++) {
68 sumR += src[i + n][RCOMP] * filter[n][RCOMP];
69 sumG += src[i + n][GCOMP] * filter[n][GCOMP];
70 sumB += src[i + n][BCOMP] * filter[n][BCOMP];
71 sumA += src[i + n][ACOMP] * filter[n][ACOMP];
72 }
73 dest[i][RCOMP] = sumR;
74 dest[i][GCOMP] = sumG;
75 dest[i][BCOMP] = sumB;
76 dest[i][ACOMP] = sumA;
77 }
78}
79
80
Brian Pauld4b799b2000-08-21 14:24:30 +000081static void
82convolve_1d_constant(GLint srcWidth, const GLfloat src[][4],
83 GLint filterWidth, const GLfloat filter[][4],
84 GLfloat dest[][4],
85 const GLfloat borderColor[4])
Brian Paulcc8e37f2000-07-12 13:00:09 +000086{
87 const GLint halfFilterWidth = filterWidth / 2;
88 GLint i, n;
89
90 for (i = 0; i < srcWidth; i++) {
91 GLfloat sumR = 0.0;
92 GLfloat sumG = 0.0;
93 GLfloat sumB = 0.0;
94 GLfloat sumA = 0.0;
95 for (n = 0; n < filterWidth; n++) {
96 if (i + n < halfFilterWidth || i + n - halfFilterWidth >= srcWidth) {
97 sumR += borderColor[RCOMP] * filter[n][RCOMP];
98 sumG += borderColor[GCOMP] * filter[n][GCOMP];
99 sumB += borderColor[BCOMP] * filter[n][BCOMP];
100 sumA += borderColor[ACOMP] * filter[n][ACOMP];
101 }
102 else {
103 sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
104 sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
105 sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
106 sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
107 }
108 }
109 dest[i][RCOMP] = sumR;
110 dest[i][GCOMP] = sumG;
111 dest[i][BCOMP] = sumB;
112 dest[i][ACOMP] = sumA;
113 }
114}
115
116
Brian Pauld4b799b2000-08-21 14:24:30 +0000117static void
118convolve_1d_replicate(GLint srcWidth, const GLfloat src[][4],
119 GLint filterWidth, const GLfloat filter[][4],
120 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000121{
122 const GLint halfFilterWidth = filterWidth / 2;
123 GLint i, n;
124
125 for (i = 0; i < srcWidth; i++) {
126 GLfloat sumR = 0.0;
127 GLfloat sumG = 0.0;
128 GLfloat sumB = 0.0;
129 GLfloat sumA = 0.0;
130 for (n = 0; n < filterWidth; n++) {
131 if (i + n < halfFilterWidth) {
132 sumR += src[0][RCOMP] * filter[n][RCOMP];
133 sumG += src[0][GCOMP] * filter[n][GCOMP];
134 sumB += src[0][BCOMP] * filter[n][BCOMP];
135 sumA += src[0][ACOMP] * filter[n][ACOMP];
136 }
137 else if (i + n - halfFilterWidth >= srcWidth) {
138 sumR += src[srcWidth - 1][RCOMP] * filter[n][RCOMP];
139 sumG += src[srcWidth - 1][GCOMP] * filter[n][GCOMP];
140 sumB += src[srcWidth - 1][BCOMP] * filter[n][BCOMP];
141 sumA += src[srcWidth - 1][ACOMP] * filter[n][ACOMP];
142 }
143 else {
144 sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
145 sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
146 sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
147 sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
148 }
149 }
150 dest[i][RCOMP] = sumR;
151 dest[i][GCOMP] = sumG;
152 dest[i][BCOMP] = sumB;
153 dest[i][ACOMP] = sumA;
154 }
155}
156
157
Brian Pauld4b799b2000-08-21 14:24:30 +0000158static void
159convolve_2d_reduce(GLint srcWidth, GLint srcHeight,
160 const GLfloat src[][4],
161 GLint filterWidth, GLint filterHeight,
162 const GLfloat filter[][4],
163 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000164{
Brian Paul7e708742000-08-22 18:54:25 +0000165 GLint dstWidth, dstHeight;
Brian Pauld4b799b2000-08-21 14:24:30 +0000166 GLint i, j, n, m;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000167
Brian Paul7e708742000-08-22 18:54:25 +0000168 if (filterWidth >= 1)
169 dstWidth = srcWidth - (filterWidth - 1);
170 else
171 dstWidth = srcWidth;
172
173 if (filterHeight >= 1)
174 dstHeight = srcHeight - (filterHeight - 1);
175 else
176 dstHeight = srcHeight;
177
Brian Pauld4b799b2000-08-21 14:24:30 +0000178 if (dstWidth <= 0 || dstHeight <= 0)
179 return;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000180
Brian Pauld4b799b2000-08-21 14:24:30 +0000181 for (j = 0; j < dstHeight; j++) {
182 for (i = 0; i < dstWidth; i++) {
183 GLfloat sumR = 0.0;
184 GLfloat sumG = 0.0;
185 GLfloat sumB = 0.0;
186 GLfloat sumA = 0.0;
187 for (m = 0; m < filterHeight; m++) {
188 for (n = 0; n < filterWidth; n++) {
189 const GLint k = (j + m) * srcWidth + i + n;
190 const GLint f = m * filterWidth + n;
191 sumR += src[k][RCOMP] * filter[f][RCOMP];
192 sumG += src[k][GCOMP] * filter[f][GCOMP];
193 sumB += src[k][BCOMP] * filter[f][BCOMP];
194 sumA += src[k][ACOMP] * filter[f][ACOMP];
195 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000196 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000197 dest[j * dstWidth + i][RCOMP] = sumR;
198 dest[j * dstWidth + i][GCOMP] = sumG;
199 dest[j * dstWidth + i][BCOMP] = sumB;
200 dest[j * dstWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000201 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000202 }
203}
204
205
Brian Pauld4b799b2000-08-21 14:24:30 +0000206static void
207convolve_2d_constant(GLint srcWidth, GLint srcHeight,
208 const GLfloat src[][4],
209 GLint filterWidth, GLint filterHeight,
210 const GLfloat filter[][4],
211 GLfloat dest[][4],
212 const GLfloat borderColor[4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000213{
214 const GLint halfFilterWidth = filterWidth / 2;
Brian Pauld4b799b2000-08-21 14:24:30 +0000215 const GLint halfFilterHeight = filterHeight / 2;
216 GLint i, j, n, m;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000217
Brian Pauld4b799b2000-08-21 14:24:30 +0000218 for (j = 0; j < srcHeight; j++) {
219 for (i = 0; i < srcWidth; i++) {
220 GLfloat sumR = 0.0;
221 GLfloat sumG = 0.0;
222 GLfloat sumB = 0.0;
223 GLfloat sumA = 0.0;
224 for (m = 0; m < filterHeight; m++) {
225 for (n = 0; n < filterWidth; n++) {
226 const GLint f = m * filterWidth + n;
227 const GLint is = i + n - halfFilterWidth;
228 const GLint js = j + m - halfFilterHeight;
229 if (is < 0 || is >= srcWidth ||
230 js < 0 || js >= srcHeight) {
231 sumR += borderColor[RCOMP] * filter[f][RCOMP];
232 sumG += borderColor[GCOMP] * filter[f][GCOMP];
233 sumB += borderColor[BCOMP] * filter[f][BCOMP];
234 sumA += borderColor[ACOMP] * filter[f][ACOMP];
235 }
236 else {
237 const GLint k = js * srcWidth + is;
238 sumR += src[k][RCOMP] * filter[f][RCOMP];
239 sumG += src[k][GCOMP] * filter[f][GCOMP];
240 sumB += src[k][BCOMP] * filter[f][BCOMP];
241 sumA += src[k][ACOMP] * filter[f][ACOMP];
242 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000243 }
244 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000245 dest[j * srcWidth + i][RCOMP] = sumR;
246 dest[j * srcWidth + i][GCOMP] = sumG;
247 dest[j * srcWidth + i][BCOMP] = sumB;
248 dest[j * srcWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000249 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000250 }
251}
252
253
Brian Pauld4b799b2000-08-21 14:24:30 +0000254static void
255convolve_2d_replicate(GLint srcWidth, GLint srcHeight,
256 const GLfloat src[][4],
257 GLint filterWidth, GLint filterHeight,
258 const GLfloat filter[][4],
259 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000260{
261 const GLint halfFilterWidth = filterWidth / 2;
Brian Pauld4b799b2000-08-21 14:24:30 +0000262 const GLint halfFilterHeight = filterHeight / 2;
263 GLint i, j, n, m;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000264
Brian Pauld4b799b2000-08-21 14:24:30 +0000265 for (j = 0; j < srcHeight; j++) {
266 for (i = 0; i < srcWidth; i++) {
267 GLfloat sumR = 0.0;
268 GLfloat sumG = 0.0;
269 GLfloat sumB = 0.0;
270 GLfloat sumA = 0.0;
271 for (m = 0; m < filterHeight; m++) {
272 for (n = 0; n < filterWidth; n++) {
273 const GLint f = m * filterWidth + n;
274 GLint is = i + n - halfFilterWidth;
275 GLint js = j + m - halfFilterHeight;
276 GLint k;
277 if (is < 0)
278 is = 0;
279 else if (is >= srcWidth)
280 is = srcWidth - 1;
281 if (js < 0)
282 js = 0;
283 else if (js >= srcHeight)
284 js = srcHeight - 1;
285 k = js * srcWidth + is;
286 sumR += src[k][RCOMP] * filter[f][RCOMP];
287 sumG += src[k][GCOMP] * filter[f][GCOMP];
288 sumB += src[k][BCOMP] * filter[f][BCOMP];
289 sumA += src[k][ACOMP] * filter[f][ACOMP];
Brian Paulcc8e37f2000-07-12 13:00:09 +0000290 }
291 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000292 dest[j * srcWidth + i][RCOMP] = sumR;
293 dest[j * srcWidth + i][GCOMP] = sumG;
294 dest[j * srcWidth + i][BCOMP] = sumB;
295 dest[j * srcWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000296 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000297 }
298}
299
300
Brian Pauld4b799b2000-08-21 14:24:30 +0000301static void
302convolve_sep_reduce(GLint srcWidth, GLint srcHeight,
303 const GLfloat src[][4],
304 GLint filterWidth, GLint filterHeight,
305 const GLfloat rowFilt[][4],
306 const GLfloat colFilt[][4],
307 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000308{
Brian Paul7e708742000-08-22 18:54:25 +0000309 GLint dstWidth, dstHeight;
Brian Pauld4b799b2000-08-21 14:24:30 +0000310 GLint i, j, n, m;
Brian Paul7e708742000-08-22 18:54:25 +0000311
312 if (filterWidth >= 1)
313 dstWidth = srcWidth - (filterWidth - 1);
314 else
315 dstWidth = srcWidth;
316
317 if (filterHeight >= 1)
318 dstHeight = srcHeight - (filterHeight - 1);
319 else
320 dstHeight = srcHeight;
321
322 if (dstWidth <= 0 || dstHeight <= 0)
323 return;
324
325 for (j = 0; j < dstHeight; j++) {
326 for (i = 0; i < dstWidth; i++) {
Brian Pauld4b799b2000-08-21 14:24:30 +0000327 GLfloat sumR = 0.0;
328 GLfloat sumG = 0.0;
329 GLfloat sumB = 0.0;
330 GLfloat sumA = 0.0;
331 for (m = 0; m < filterHeight; m++) {
332 for (n = 0; n < filterWidth; n++) {
Brian Paul7e708742000-08-22 18:54:25 +0000333 GLint k = (j + m) * srcWidth + i + n;
334 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
335 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
336 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
337 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
Brian Paulcc8e37f2000-07-12 13:00:09 +0000338 }
339 }
Brian Paul7e708742000-08-22 18:54:25 +0000340 dest[j * dstWidth + i][RCOMP] = sumR;
341 dest[j * dstWidth + i][GCOMP] = sumG;
342 dest[j * dstWidth + i][BCOMP] = sumB;
343 dest[j * dstWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000344 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000345 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000346}
347
348
Brian Pauld4b799b2000-08-21 14:24:30 +0000349static void
350convolve_sep_constant(GLint srcWidth, GLint srcHeight,
351 const GLfloat src[][4],
352 GLint filterWidth, GLint filterHeight,
353 const GLfloat rowFilt[][4],
354 const GLfloat colFilt[][4],
355 GLfloat dest[][4],
356 const GLfloat borderColor[4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000357{
358 const GLint halfFilterWidth = filterWidth / 2;
Brian Pauld4b799b2000-08-21 14:24:30 +0000359 const GLint halfFilterHeight = filterHeight / 2;
360 GLint i, j, n, m;
Brian Paul7e708742000-08-22 18:54:25 +0000361
Brian Pauld4b799b2000-08-21 14:24:30 +0000362 for (j = 0; j < srcHeight; j++) {
363 for (i = 0; i < srcWidth; i++) {
364 GLfloat sumR = 0.0;
365 GLfloat sumG = 0.0;
366 GLfloat sumB = 0.0;
367 GLfloat sumA = 0.0;
368 for (m = 0; m < filterHeight; m++) {
369 for (n = 0; n < filterWidth; n++) {
Brian Paul7e708742000-08-22 18:54:25 +0000370 const GLint is = i + n - halfFilterWidth;
371 const GLint js = j + m - halfFilterHeight;
372 if (is < 0 || is >= srcWidth ||
373 js < 0 || js >= srcHeight) {
Brian Pauld4b799b2000-08-21 14:24:30 +0000374 sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
375 sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
376 sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
377 sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
378 }
379 else {
Brian Paul7e708742000-08-22 18:54:25 +0000380 GLint k = js * srcWidth + is;
Brian Pauld4b799b2000-08-21 14:24:30 +0000381 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
382 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
383 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
384 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
385 }
Brian Paul7e708742000-08-22 18:54:25 +0000386
Brian Paulcc8e37f2000-07-12 13:00:09 +0000387 }
388 }
Brian Paul7e708742000-08-22 18:54:25 +0000389 dest[j * srcWidth + i][RCOMP] = sumR;
390 dest[j * srcWidth + i][GCOMP] = sumG;
391 dest[j * srcWidth + i][BCOMP] = sumB;
392 dest[j * srcWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000393 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000394 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000395}
396
397
398static void
399convolve_sep_replicate(GLint srcWidth, GLint srcHeight,
400 const GLfloat src[][4],
401 GLint filterWidth, GLint filterHeight,
402 const GLfloat rowFilt[][4],
403 const GLfloat colFilt[][4],
404 GLfloat dest[][4])
405{
406 const GLint halfFilterWidth = filterWidth / 2;
407 const GLint halfFilterHeight = filterHeight / 2;
408 GLint i, j, n, m;
409
410 for (j = 0; j < srcHeight; j++) {
411 for (i = 0; i < srcWidth; i++) {
412 GLfloat sumR = 0.0;
413 GLfloat sumG = 0.0;
414 GLfloat sumB = 0.0;
415 GLfloat sumA = 0.0;
416 for (m = 0; m < filterHeight; m++) {
417 for (n = 0; n < filterWidth; n++) {
Brian Paul7e708742000-08-22 18:54:25 +0000418 GLint is = i + n - halfFilterWidth;
419 GLint js = j + m - halfFilterHeight;
420 GLint k;
421 if (is < 0)
422 is = 0;
423 else if (is >= srcWidth)
424 is = srcWidth - 1;
425 if (js < 0)
426 js = 0;
427 else if (js >= srcHeight)
428 js = srcHeight - 1;
429 k = js * srcWidth + is;
430 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
431 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
432 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
433 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
Brian Pauld4b799b2000-08-21 14:24:30 +0000434 }
435 }
Brian Paul7e708742000-08-22 18:54:25 +0000436 dest[j * srcWidth + i][RCOMP] = sumR;
437 dest[j * srcWidth + i][GCOMP] = sumG;
438 dest[j * srcWidth + i][BCOMP] = sumB;
439 dest[j * srcWidth + i][ACOMP] = sumA;
Brian Pauld4b799b2000-08-21 14:24:30 +0000440 }
441 }
442}
443
444
445
446void
447_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,
448 const GLfloat *srcImage, GLfloat *dstImage)
449{
450 switch (ctx->Pixel.ConvolutionBorderMode[0]) {
451 case GL_REDUCE:
452 convolve_1d_reduce(*width, (const GLfloat (*)[4]) srcImage,
453 ctx->Convolution1D.Width,
454 (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
455 (GLfloat (*)[4]) dstImage);
Brian Paul7e708742000-08-22 18:54:25 +0000456 *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1);
Brian Pauld4b799b2000-08-21 14:24:30 +0000457 break;
458 case GL_CONSTANT_BORDER:
459 convolve_1d_constant(*width, (const GLfloat (*)[4]) srcImage,
460 ctx->Convolution1D.Width,
461 (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
462 (GLfloat (*)[4]) dstImage,
463 ctx->Pixel.ConvolutionBorderColor[0]);
464 break;
465 case GL_REPLICATE_BORDER:
466 convolve_1d_replicate(*width, (const GLfloat (*)[4]) srcImage,
467 ctx->Convolution1D.Width,
468 (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
469 (GLfloat (*)[4]) dstImage);
470 break;
471 default:
472 ;
473 }
474}
475
476
477void
478_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,
479 const GLfloat *srcImage, GLfloat *dstImage)
480{
481 switch (ctx->Pixel.ConvolutionBorderMode[1]) {
482 case GL_REDUCE:
483 convolve_2d_reduce(*width, *height,
484 (const GLfloat (*)[4]) srcImage,
485 ctx->Convolution2D.Width,
486 ctx->Convolution2D.Height,
487 (const GLfloat (*)[4]) ctx->Convolution2D.Filter,
488 (GLfloat (*)[4]) dstImage);
Brian Paul7e708742000-08-22 18:54:25 +0000489 *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1);
490 *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1);
Brian Pauld4b799b2000-08-21 14:24:30 +0000491 break;
492 case GL_CONSTANT_BORDER:
493 convolve_2d_constant(*width, *height,
494 (const GLfloat (*)[4]) srcImage,
495 ctx->Convolution2D.Width,
496 ctx->Convolution2D.Height,
497 (const GLfloat (*)[4]) ctx->Convolution2D.Filter,
498 (GLfloat (*)[4]) dstImage,
499 ctx->Pixel.ConvolutionBorderColor[1]);
500 break;
501 case GL_REPLICATE_BORDER:
502 convolve_2d_replicate(*width, *height,
503 (const GLfloat (*)[4]) srcImage,
504 ctx->Convolution2D.Width,
505 ctx->Convolution2D.Height,
506 (const GLfloat (*)[4])ctx->Convolution2D.Filter,
507 (GLfloat (*)[4]) dstImage);
508 break;
509 default:
510 ;
511 }
512}
513
514
515void
516_mesa_convolve_sep_image(const GLcontext *ctx,
517 GLsizei *width, GLsizei *height,
518 const GLfloat *srcImage, GLfloat *dstImage)
519{
520 const GLfloat *rowFilter = ctx->Separable2D.Filter;
521 const GLfloat *colFilter = rowFilter + 4 * MAX_CONVOLUTION_WIDTH;
522
523 switch (ctx->Pixel.ConvolutionBorderMode[2]) {
524 case GL_REDUCE:
525 convolve_sep_reduce(*width, *height,
526 (const GLfloat (*)[4]) srcImage,
Brian Paul7e708742000-08-22 18:54:25 +0000527 ctx->Separable2D.Width,
528 ctx->Separable2D.Height,
Brian Pauld4b799b2000-08-21 14:24:30 +0000529 (const GLfloat (*)[4]) rowFilter,
530 (const GLfloat (*)[4]) colFilter,
531 (GLfloat (*)[4]) dstImage);
Brian Paul7e708742000-08-22 18:54:25 +0000532 *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1);
533 *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1);
Brian Pauld4b799b2000-08-21 14:24:30 +0000534 break;
535 case GL_CONSTANT_BORDER:
536 convolve_sep_constant(*width, *height,
537 (const GLfloat (*)[4]) srcImage,
Brian Paul7e708742000-08-22 18:54:25 +0000538 ctx->Separable2D.Width,
539 ctx->Separable2D.Height,
Brian Pauld4b799b2000-08-21 14:24:30 +0000540 (const GLfloat (*)[4]) rowFilter,
541 (const GLfloat (*)[4]) colFilter,
542 (GLfloat (*)[4]) dstImage,
543 ctx->Pixel.ConvolutionBorderColor[2]);
544 break;
545 case GL_REPLICATE_BORDER:
546 convolve_sep_replicate(*width, *height,
547 (const GLfloat (*)[4]) srcImage,
Brian Paul7e708742000-08-22 18:54:25 +0000548 ctx->Separable2D.Width,
549 ctx->Separable2D.Height,
Brian Pauld4b799b2000-08-21 14:24:30 +0000550 (const GLfloat (*)[4]) rowFilter,
551 (const GLfloat (*)[4]) colFilter,
552 (GLfloat (*)[4]) dstImage);
553 break;
554 default:
555 ;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000556 }
557}