Code update for Window Maker version 0.50.0
[wmaker-crm.git] / wrlib / convolve.c
blobfb2b45d66ba37c5f4216e2d6398f0e022da65324
1 /*
2 * Raster graphics library
3 *
4 * Copyright (c) 1997 Alfredo K. Kojima
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <config.h>
23 /* AIX requires this to be the first thing in the file. */
24 #ifdef __GNUC__
25 # define alloca __builtin_alloca
26 #else
27 # if HAVE_ALLOCA_H
28 # include <alloca.h>
29 # else
30 # ifdef _AIX
31 # pragma alloca
32 # else
33 # ifndef alloca /* predefined by HP cc +Olibcalls */
34 char *alloca ();
35 # endif
36 # endif
37 # endif
38 #endif
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <X11/Xlib.h>
45 #include "wraster.h"
49 *----------------------------------------------------------------------
50 * RBlurImage--
51 * Apply 3x3 1 1 1 low pass, convolution mask to image.
52 * 1 2 1
53 * 1 1 1 /10
54 *----------------------------------------------------------------------
56 int
57 RBlurImage(RImage *image)
59 register int x, y;
60 register int w, tmp;
61 unsigned char *r, *g, *b, *a;
62 unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
64 #define MASK(c,pc,p) ((*c+ *c + *(c-1) + *(c+1) + pc[p] + pc[p-1] + pc[p+1] \
65 + *(c+w) + *(c+w-1) + *(c+w+1))/10)
67 pr = (unsigned char*)alloca(image->width*sizeof(char));
68 if (!pr)
69 goto outofmem;
71 pg = (unsigned char*)alloca(image->width*sizeof(char));
72 if (!pg)
73 goto outofmem;
75 pb = (unsigned char*)alloca(image->width*sizeof(char));
76 if (!pb)
77 goto outofmem;
79 pa = (unsigned char*)alloca(image->width*sizeof(char));
80 if (!pa)
81 goto outofmem;
84 r = image->data[0];
85 g = image->data[1];
86 b = image->data[2];
87 a = image->data[3];
90 for (x=0; x<image->width; x++) {
91 pr[x] = *(r++);
92 pg[x] = *(g++);
93 pb[x] = *(b++);
96 w = image->width;
98 for (y=1; y<image->height-1; y++) {
99 pr[w-1] = r[w-1];
100 pg[w-1] = g[w-1];
101 pb[w-1] = b[w-1];
103 pr[0] = *(r++);
104 pg[0] = *(g++);
105 pb[0] = *(b++);
107 for (x=1; x<image->width-1; x++) {
108 tmp = *r;
109 *(r++) = MASK(r,pr,x);
110 pr[x] = tmp;
112 tmp = *g;
113 *(g++) = MASK(g,pg,x);
114 pg[x] = tmp;
116 tmp = *b;
117 *(b++) = MASK(b,pb,x);
118 pb[x] = tmp;
120 r++;
121 g++;
122 b++;
125 #undef MASK
127 #ifdef C_ALLOCA
128 alloca(0);
129 #endif
130 return True;
132 outofmem:
133 RErrorCode = RERR_NOMEMORY;
134 #ifdef C_ALLOCA
135 alloca(0);
136 #endif
137 return False;
141 #if 0
143 REdgeDetectImage(RImage *image)
145 register int x, y, d1, d2, d3, d4, rsum;
146 int w;
147 unsigned char *r, *g, *b, *a;
148 unsigned char *dr, *dg, *db, *da;
149 unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
150 RImage *image2;
153 image2 = RCloneImage(image);
155 pr = alloca(image->width*sizeof(char));
156 if (!pr)
157 goto outofmem;
159 pg = alloca(image->width*sizeof(char));
160 if (!pg)
161 goto outofmem;
163 pb = alloca(image->width*sizeof(char));
164 if (!pb)
165 goto outofmem;
167 pa = alloca(image->width*sizeof(char));
168 if (!pa)
169 goto outofmem;
172 r = image->data[0];
173 g = image->data[1];
174 b = image->data[2];
175 a = image->data[3];
177 dr = image2->data[0];
178 dg = image2->data[1];
179 db = image2->data[2];
180 da = image2->data[3];
183 for (x=0; x<image->width; x++) {
184 *(dr++) = *(r++);
185 *(dg++) = *(g++);
186 *(db++) = *(b++);
189 w = image->width;
191 for (y=1; y<image->height-1; y++) {
192 dr[w-1] = r[w-1];
193 dg[w-1] = g[w-1];
194 db[w-1] = b[w-1];
196 *(dr++) = *(r++);
197 *(dg++) = *(g++);
198 *(db++) = *(b++);
200 for (x=1; x<image->width-1; x++) {
201 d1 = r[w+1] - r[-w-1];
202 d2 = r[1] - r[-1];
203 d3 = r[-w+1] - r[w-1];
204 d4 = r[-w] - r[w];
206 rsum = d1 + d2 + d3;
207 if (rsum < 0) rsum = -rsum;
208 d1 = d1 - d2 - d4; /* vertical gradient */
209 if (d1 < 0) d1 = -d1;
210 if (d1 > rsum) rsum = d1;
211 rsum /= 3;
213 *(dr++) = rsum;
215 d1 = g[w+1] - g[-w-1];
216 d2 = g[1] - g[-1];
217 d3 = g[-w+1] - g[w-1];
218 d4 = g[-w] - g[w];
220 rsum = d1 + d2 + d3;
221 if (rsum < 0) rsum = -rsum;
222 d1 = d1 - d2 - d4; /* vertical gradient */
223 if (d1 < 0) d1 = -d1;
224 if (d1 > rsum) rsum = d1;
225 rsum /= 3;
227 *(dg++) = rsum;
229 d1 = b[w+1] - b[-w-1];
230 d2 = b[1] - b[-1];
231 d3 = b[-w+1] - b[w-1];
232 d4 = b[-w] - b[w];
234 rsum = d1 + d2 + d3;
235 if (rsum < 0) rsum = -rsum;
236 d1 = d1 - d2 - d4; /* vertical gradient */
237 if (d1 < 0) d1 = -d1;
238 if (d1 > rsum) rsum = d1;
239 rsum /= 3;
241 *(db++) = rsum;
243 r++;
244 g++;
245 b++;
247 r++;
248 g++;
249 b++;
251 dr++;
252 dg++;
253 db++;
256 r = image->data[0];
257 image2->data[0] = r;
258 g = image->data[1];
259 image2->data[1] = g;
260 b = image->data[2];
261 image2->data[2] = b;
262 RDestroyImage(image2);
265 #undef MASK
267 return True;
272 RSmoothImage(RImage *image)
274 register int x, y;
275 register int v, w;
276 unsigned char *r, *g, *b, *a;
278 r = image->data[0];
279 g = image->data[1];
280 b = image->data[2];
281 a = image->data[3];
283 w = image->width;
284 for (y=0; y<image->height - 1; y++) {
285 for (x=0; x<image->width - 1; x++) {
286 v = *r + 2 * *(r + 1) + 2 * *(r + w) + *(r + w + 1);
287 *(r++) = v/6;
289 v = *g + 2 * *(g + 1) + 2 * *(g + w) + *(g + w + 1);
290 *(g++) = v/6;
292 v = *b + 2 * *(b + 1) + 2 * *(b + w) + *(b + w + 1);
293 *(b++) = v/6;
296 /* last column */
297 v = 3 * *r + 3 * *(r + w);
298 *(r++) = v/6;
300 v = 3 * *g + 3 * *(g + w);
301 *(g++) = v/6;
303 v = 3 * *b + 3 * *(b + w);
304 *(b++) = v/6;
307 /* last line */
308 for (x=0; x<image->width - 1; x++) {
309 v = 3 * *r + 3 * *(r + 1);
310 *(r++) = v/6;
312 v = 3 * *g + 3 * *(g + 1);
313 *(g++) = v/6;
315 v = 3 * *b + 3 * *(b + 1);
316 *(b++) = v/6;
319 return True;
321 #endif