blob: 541cfb6ce18bac54ab953f5842dd4ed7a7963e1b [file] [log] [blame]
Brian Pauld4b799b2000-08-21 14:24:30 +00001/* $Id: convolve.c,v 1.2 2000/08/21 14:24:30 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{
51 const GLint dstWidth = srcWidth - (filterWidth - 1);
52 GLint i, n;
53
54 if (dstWidth <= 0)
55 return; /* null result */
56
57 for (i = 0; i < dstWidth; i++) {
58 GLfloat sumR = 0.0;
59 GLfloat sumG = 0.0;
60 GLfloat sumB = 0.0;
61 GLfloat sumA = 0.0;
62 for (n = 0; n < filterWidth; n++) {
63 sumR += src[i + n][RCOMP] * filter[n][RCOMP];
64 sumG += src[i + n][GCOMP] * filter[n][GCOMP];
65 sumB += src[i + n][BCOMP] * filter[n][BCOMP];
66 sumA += src[i + n][ACOMP] * filter[n][ACOMP];
67 }
68 dest[i][RCOMP] = sumR;
69 dest[i][GCOMP] = sumG;
70 dest[i][BCOMP] = sumB;
71 dest[i][ACOMP] = sumA;
72 }
73}
74
75
Brian Pauld4b799b2000-08-21 14:24:30 +000076static void
77convolve_1d_constant(GLint srcWidth, const GLfloat src[][4],
78 GLint filterWidth, const GLfloat filter[][4],
79 GLfloat dest[][4],
80 const GLfloat borderColor[4])
Brian Paulcc8e37f2000-07-12 13:00:09 +000081{
82 const GLint halfFilterWidth = filterWidth / 2;
83 GLint i, n;
84
85 for (i = 0; i < srcWidth; i++) {
86 GLfloat sumR = 0.0;
87 GLfloat sumG = 0.0;
88 GLfloat sumB = 0.0;
89 GLfloat sumA = 0.0;
90 for (n = 0; n < filterWidth; n++) {
91 if (i + n < halfFilterWidth || i + n - halfFilterWidth >= srcWidth) {
92 sumR += borderColor[RCOMP] * filter[n][RCOMP];
93 sumG += borderColor[GCOMP] * filter[n][GCOMP];
94 sumB += borderColor[BCOMP] * filter[n][BCOMP];
95 sumA += borderColor[ACOMP] * filter[n][ACOMP];
96 }
97 else {
98 sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
99 sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
100 sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
101 sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
102 }
103 }
104 dest[i][RCOMP] = sumR;
105 dest[i][GCOMP] = sumG;
106 dest[i][BCOMP] = sumB;
107 dest[i][ACOMP] = sumA;
108 }
109}
110
111
Brian Pauld4b799b2000-08-21 14:24:30 +0000112static void
113convolve_1d_replicate(GLint srcWidth, const GLfloat src[][4],
114 GLint filterWidth, const GLfloat filter[][4],
115 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000116{
117 const GLint halfFilterWidth = filterWidth / 2;
118 GLint i, n;
119
120 for (i = 0; i < srcWidth; i++) {
121 GLfloat sumR = 0.0;
122 GLfloat sumG = 0.0;
123 GLfloat sumB = 0.0;
124 GLfloat sumA = 0.0;
125 for (n = 0; n < filterWidth; n++) {
126 if (i + n < halfFilterWidth) {
127 sumR += src[0][RCOMP] * filter[n][RCOMP];
128 sumG += src[0][GCOMP] * filter[n][GCOMP];
129 sumB += src[0][BCOMP] * filter[n][BCOMP];
130 sumA += src[0][ACOMP] * filter[n][ACOMP];
131 }
132 else if (i + n - halfFilterWidth >= srcWidth) {
133 sumR += src[srcWidth - 1][RCOMP] * filter[n][RCOMP];
134 sumG += src[srcWidth - 1][GCOMP] * filter[n][GCOMP];
135 sumB += src[srcWidth - 1][BCOMP] * filter[n][BCOMP];
136 sumA += src[srcWidth - 1][ACOMP] * filter[n][ACOMP];
137 }
138 else {
139 sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP];
140 sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP];
141 sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP];
142 sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP];
143 }
144 }
145 dest[i][RCOMP] = sumR;
146 dest[i][GCOMP] = sumG;
147 dest[i][BCOMP] = sumB;
148 dest[i][ACOMP] = sumA;
149 }
150}
151
152
Brian Pauld4b799b2000-08-21 14:24:30 +0000153static void
154convolve_2d_reduce(GLint srcWidth, GLint srcHeight,
155 const GLfloat src[][4],
156 GLint filterWidth, GLint filterHeight,
157 const GLfloat filter[][4],
158 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000159{
160 const GLint dstWidth = srcWidth - (filterWidth - 1);
Brian Pauld4b799b2000-08-21 14:24:30 +0000161 const GLint dstHeight = srcHeight - (filterHeight - 1);
162 GLint i, j, n, m;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000163
Brian Pauld4b799b2000-08-21 14:24:30 +0000164 if (dstWidth <= 0 || dstHeight <= 0)
165 return;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000166
Brian Pauld4b799b2000-08-21 14:24:30 +0000167 for (j = 0; j < dstHeight; j++) {
168 for (i = 0; i < dstWidth; i++) {
169 GLfloat sumR = 0.0;
170 GLfloat sumG = 0.0;
171 GLfloat sumB = 0.0;
172 GLfloat sumA = 0.0;
173 for (m = 0; m < filterHeight; m++) {
174 for (n = 0; n < filterWidth; n++) {
175 const GLint k = (j + m) * srcWidth + i + n;
176 const GLint f = m * filterWidth + n;
177 sumR += src[k][RCOMP] * filter[f][RCOMP];
178 sumG += src[k][GCOMP] * filter[f][GCOMP];
179 sumB += src[k][BCOMP] * filter[f][BCOMP];
180 sumA += src[k][ACOMP] * filter[f][ACOMP];
181 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000182 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000183 dest[j * dstWidth + i][RCOMP] = sumR;
184 dest[j * dstWidth + i][GCOMP] = sumG;
185 dest[j * dstWidth + i][BCOMP] = sumB;
186 dest[j * dstWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000187 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000188 }
189}
190
191
Brian Pauld4b799b2000-08-21 14:24:30 +0000192static void
193convolve_2d_constant(GLint srcWidth, GLint srcHeight,
194 const GLfloat src[][4],
195 GLint filterWidth, GLint filterHeight,
196 const GLfloat filter[][4],
197 GLfloat dest[][4],
198 const GLfloat borderColor[4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000199{
200 const GLint halfFilterWidth = filterWidth / 2;
Brian Pauld4b799b2000-08-21 14:24:30 +0000201 const GLint halfFilterHeight = filterHeight / 2;
202 GLint i, j, n, m;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000203
Brian Pauld4b799b2000-08-21 14:24:30 +0000204 {
205 for (i=0;i<filterWidth*filterHeight;i++){
206 printf("%d %f %f %f %f\n", i,
207 filter[i][0], filter[i][1], filter[i][2], filter[i][3]);
208 }
209 }
210
211 for (j = 0; j < srcHeight; j++) {
212 for (i = 0; i < srcWidth; i++) {
213 GLfloat sumR = 0.0;
214 GLfloat sumG = 0.0;
215 GLfloat sumB = 0.0;
216 GLfloat sumA = 0.0;
217 for (m = 0; m < filterHeight; m++) {
218 for (n = 0; n < filterWidth; n++) {
219 const GLint f = m * filterWidth + n;
220 const GLint is = i + n - halfFilterWidth;
221 const GLint js = j + m - halfFilterHeight;
222 if (is < 0 || is >= srcWidth ||
223 js < 0 || js >= srcHeight) {
224 sumR += borderColor[RCOMP] * filter[f][RCOMP];
225 sumG += borderColor[GCOMP] * filter[f][GCOMP];
226 sumB += borderColor[BCOMP] * filter[f][BCOMP];
227 sumA += borderColor[ACOMP] * filter[f][ACOMP];
228 }
229 else {
230 const GLint k = js * srcWidth + is;
231 sumR += src[k][RCOMP] * filter[f][RCOMP];
232 sumG += src[k][GCOMP] * filter[f][GCOMP];
233 sumB += src[k][BCOMP] * filter[f][BCOMP];
234 sumA += src[k][ACOMP] * filter[f][ACOMP];
235 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000236 }
237 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000238 dest[j * srcWidth + i][RCOMP] = sumR;
239 dest[j * srcWidth + i][GCOMP] = sumG;
240 dest[j * srcWidth + i][BCOMP] = sumB;
241 dest[j * srcWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000242 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000243 }
244}
245
246
Brian Pauld4b799b2000-08-21 14:24:30 +0000247static void
248convolve_2d_replicate(GLint srcWidth, GLint srcHeight,
249 const GLfloat src[][4],
250 GLint filterWidth, GLint filterHeight,
251 const GLfloat filter[][4],
252 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000253{
254 const GLint halfFilterWidth = filterWidth / 2;
Brian Pauld4b799b2000-08-21 14:24:30 +0000255 const GLint halfFilterHeight = filterHeight / 2;
256 GLint i, j, n, m;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000257
Brian Pauld4b799b2000-08-21 14:24:30 +0000258 for (j = 0; j < srcHeight; j++) {
259 for (i = 0; i < srcWidth; i++) {
260 GLfloat sumR = 0.0;
261 GLfloat sumG = 0.0;
262 GLfloat sumB = 0.0;
263 GLfloat sumA = 0.0;
264 for (m = 0; m < filterHeight; m++) {
265 for (n = 0; n < filterWidth; n++) {
266 const GLint f = m * filterWidth + n;
267 GLint is = i + n - halfFilterWidth;
268 GLint js = j + m - halfFilterHeight;
269 GLint k;
270 if (is < 0)
271 is = 0;
272 else if (is >= srcWidth)
273 is = srcWidth - 1;
274 if (js < 0)
275 js = 0;
276 else if (js >= srcHeight)
277 js = srcHeight - 1;
278 k = js * srcWidth + is;
279 sumR += src[k][RCOMP] * filter[f][RCOMP];
280 sumG += src[k][GCOMP] * filter[f][GCOMP];
281 sumB += src[k][BCOMP] * filter[f][BCOMP];
282 sumA += src[k][ACOMP] * filter[f][ACOMP];
Brian Paulcc8e37f2000-07-12 13:00:09 +0000283 }
284 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000285 dest[j * srcWidth + i][RCOMP] = sumR;
286 dest[j * srcWidth + i][GCOMP] = sumG;
287 dest[j * srcWidth + i][BCOMP] = sumB;
288 dest[j * srcWidth + i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000289 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000290 }
291}
292
293
Brian Pauld4b799b2000-08-21 14:24:30 +0000294static void
295convolve_sep_reduce(GLint srcWidth, GLint srcHeight,
296 const GLfloat src[][4],
297 GLint filterWidth, GLint filterHeight,
298 const GLfloat rowFilt[][4],
299 const GLfloat colFilt[][4],
300 GLfloat dest[][4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000301{
302 const GLint halfFilterWidth = filterWidth / 2;
Brian Pauld4b799b2000-08-21 14:24:30 +0000303 const GLint halfFilterHeight = filterHeight / 2;
304 GLint i, j, n, m;
305#if 0
306 for (j = 0; j < srcHeight; j++) {
307 for (i = 0; i < srcWidth; i++) {
308 GLfloat sumR = 0.0;
309 GLfloat sumG = 0.0;
310 GLfloat sumB = 0.0;
311 GLfloat sumA = 0.0;
312 for (m = 0; m < filterHeight; m++) {
313 for (n = 0; n < filterWidth; n++) {
314 if (i + n < halfFilterWidth ||
315 i + n - halfFilterWidth >= srcWidth) {
316 sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
317 sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
318 sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
319 sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
320 }
321 else {
322 const GLint k = m * srcWidth + i + n - halfFilterWidth;
323 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
324 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
325 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
326 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
327 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000328 }
329 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000330 dest[i][RCOMP] = sumR;
331 dest[i][GCOMP] = sumG;
332 dest[i][BCOMP] = sumB;
333 dest[i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000334 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000335 }
336#endif
337}
338
339
Brian Pauld4b799b2000-08-21 14:24:30 +0000340static void
341convolve_sep_constant(GLint srcWidth, GLint srcHeight,
342 const GLfloat src[][4],
343 GLint filterWidth, GLint filterHeight,
344 const GLfloat rowFilt[][4],
345 const GLfloat colFilt[][4],
346 GLfloat dest[][4],
347 const GLfloat borderColor[4])
Brian Paulcc8e37f2000-07-12 13:00:09 +0000348{
349 const GLint halfFilterWidth = filterWidth / 2;
Brian Pauld4b799b2000-08-21 14:24:30 +0000350 const GLint halfFilterHeight = filterHeight / 2;
351 GLint i, j, n, m;
352#if 0
353 for (j = 0; j < srcHeight; j++) {
354 for (i = 0; i < srcWidth; i++) {
355 GLfloat sumR = 0.0;
356 GLfloat sumG = 0.0;
357 GLfloat sumB = 0.0;
358 GLfloat sumA = 0.0;
359 for (m = 0; m < filterHeight; m++) {
360 for (n = 0; n < filterWidth; n++) {
361 if (i + n < halfFilterWidth ||
362 i + n - halfFilterWidth >= srcWidth) {
363 sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
364 sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
365 sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
366 sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
367 }
368 else {
369 const GLint k = m * srcWidth + i + n - halfFilterWidth;
370 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
371 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
372 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
373 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
374 }
Brian Paulcc8e37f2000-07-12 13:00:09 +0000375 }
376 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000377 dest[i][RCOMP] = sumR;
378 dest[i][GCOMP] = sumG;
379 dest[i][BCOMP] = sumB;
380 dest[i][ACOMP] = sumA;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000381 }
Brian Pauld4b799b2000-08-21 14:24:30 +0000382 }
383#endif
384}
385
386
387static void
388convolve_sep_replicate(GLint srcWidth, GLint srcHeight,
389 const GLfloat src[][4],
390 GLint filterWidth, GLint filterHeight,
391 const GLfloat rowFilt[][4],
392 const GLfloat colFilt[][4],
393 GLfloat dest[][4])
394{
395 const GLint halfFilterWidth = filterWidth / 2;
396 const GLint halfFilterHeight = filterHeight / 2;
397 GLint i, j, n, m;
398
399 for (j = 0; j < srcHeight; j++) {
400 for (i = 0; i < srcWidth; i++) {
401 GLfloat sumR = 0.0;
402 GLfloat sumG = 0.0;
403 GLfloat sumB = 0.0;
404 GLfloat sumA = 0.0;
405 for (m = 0; m < filterHeight; m++) {
406 for (n = 0; n < filterWidth; n++) {
407 if (i + n < halfFilterWidth) {
408 const GLint k = m * srcWidth + 0;
409 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
410 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
411 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
412 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
413 }
414 else if (i + n - halfFilterWidth >= srcWidth) {
415 const GLint k = m * srcWidth + srcWidth - 1;
416 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
417 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
418 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
419 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
420 }
421 else {
422 const GLint k = m * srcWidth + i + n - halfFilterWidth;
423 sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP];
424 sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP];
425 sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP];
426 sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP];
427 }
428 }
429 }
430 dest[i][RCOMP] = sumR;
431 dest[i][GCOMP] = sumG;
432 dest[i][BCOMP] = sumB;
433 dest[i][ACOMP] = sumA;
434 }
435 }
436}
437
438
439
440void
441_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,
442 const GLfloat *srcImage, GLfloat *dstImage)
443{
444 switch (ctx->Pixel.ConvolutionBorderMode[0]) {
445 case GL_REDUCE:
446 convolve_1d_reduce(*width, (const GLfloat (*)[4]) srcImage,
447 ctx->Convolution1D.Width,
448 (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
449 (GLfloat (*)[4]) dstImage);
450 *width -= (ctx->Convolution1D.Width - 1);
451 break;
452 case GL_CONSTANT_BORDER:
453 convolve_1d_constant(*width, (const GLfloat (*)[4]) srcImage,
454 ctx->Convolution1D.Width,
455 (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
456 (GLfloat (*)[4]) dstImage,
457 ctx->Pixel.ConvolutionBorderColor[0]);
458 break;
459 case GL_REPLICATE_BORDER:
460 convolve_1d_replicate(*width, (const GLfloat (*)[4]) srcImage,
461 ctx->Convolution1D.Width,
462 (const GLfloat (*)[4]) ctx->Convolution1D.Filter,
463 (GLfloat (*)[4]) dstImage);
464 break;
465 default:
466 ;
467 }
468}
469
470
471void
472_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,
473 const GLfloat *srcImage, GLfloat *dstImage)
474{
475 switch (ctx->Pixel.ConvolutionBorderMode[1]) {
476 case GL_REDUCE:
477 convolve_2d_reduce(*width, *height,
478 (const GLfloat (*)[4]) srcImage,
479 ctx->Convolution2D.Width,
480 ctx->Convolution2D.Height,
481 (const GLfloat (*)[4]) ctx->Convolution2D.Filter,
482 (GLfloat (*)[4]) dstImage);
483 *width = *width - (ctx->Convolution2D.Width - 1);
484 *height = *height - (ctx->Convolution2D.Height - 1);
485 break;
486 case GL_CONSTANT_BORDER:
487 convolve_2d_constant(*width, *height,
488 (const GLfloat (*)[4]) srcImage,
489 ctx->Convolution2D.Width,
490 ctx->Convolution2D.Height,
491 (const GLfloat (*)[4]) ctx->Convolution2D.Filter,
492 (GLfloat (*)[4]) dstImage,
493 ctx->Pixel.ConvolutionBorderColor[1]);
494 break;
495 case GL_REPLICATE_BORDER:
496 convolve_2d_replicate(*width, *height,
497 (const GLfloat (*)[4]) srcImage,
498 ctx->Convolution2D.Width,
499 ctx->Convolution2D.Height,
500 (const GLfloat (*)[4])ctx->Convolution2D.Filter,
501 (GLfloat (*)[4]) dstImage);
502 break;
503 default:
504 ;
505 }
506}
507
508
509void
510_mesa_convolve_sep_image(const GLcontext *ctx,
511 GLsizei *width, GLsizei *height,
512 const GLfloat *srcImage, GLfloat *dstImage)
513{
514 const GLfloat *rowFilter = ctx->Separable2D.Filter;
515 const GLfloat *colFilter = rowFilter + 4 * MAX_CONVOLUTION_WIDTH;
516
517 switch (ctx->Pixel.ConvolutionBorderMode[2]) {
518 case GL_REDUCE:
519 convolve_sep_reduce(*width, *height,
520 (const GLfloat (*)[4]) srcImage,
521 ctx->Convolution2D.Width,
522 ctx->Convolution2D.Height,
523 (const GLfloat (*)[4]) rowFilter,
524 (const GLfloat (*)[4]) colFilter,
525 (GLfloat (*)[4]) dstImage);
526 *width = *width - (ctx->Convolution2D.Width - 1);
527 *height = *height - (ctx->Convolution2D.Height - 1);
528 break;
529 case GL_CONSTANT_BORDER:
530 convolve_sep_constant(*width, *height,
531 (const GLfloat (*)[4]) srcImage,
532 ctx->Convolution2D.Width,
533 ctx->Convolution2D.Height,
534 (const GLfloat (*)[4]) rowFilter,
535 (const GLfloat (*)[4]) colFilter,
536 (GLfloat (*)[4]) dstImage,
537 ctx->Pixel.ConvolutionBorderColor[2]);
538 break;
539 case GL_REPLICATE_BORDER:
540 convolve_sep_replicate(*width, *height,
541 (const GLfloat (*)[4]) srcImage,
542 ctx->Convolution2D.Width,
543 ctx->Convolution2D.Height,
544 (const GLfloat (*)[4]) rowFilter,
545 (const GLfloat (*)[4]) colFilter,
546 (GLfloat (*)[4]) dstImage);
547 break;
548 default:
549 ;
Brian Paulcc8e37f2000-07-12 13:00:09 +0000550 }
551}