Change to the linux kernel coding style
[wmaker-crm.git] / wrlib / convolve.c
1 /*
2 * Raster graphics library
3 *
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
5 *
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.
10 *
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.
15 *
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.
19 */
20
21 #include <config.h>
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <X11/Xlib.h>
27 #include "wraster.h"
28
29 /*
30 *----------------------------------------------------------------------
31 * RBlurImage--
32 * Apply 3x3 1 1 1 low pass, convolution mask to image.
33 * 1 2 1
34 * 1 1 1 /10
35 *----------------------------------------------------------------------
36 */
37 int RBlurImage(RImage * image)
38 {
39 register int x, y;
40 register int tmp;
41 unsigned char *ptr, *nptr;
42 unsigned char *pptr = NULL, *tmpp;
43 int ch = image->format == RRGBAFormat ? 4 : 3;
44
45 pptr = malloc(image->width * ch);
46 if (!pptr) {
47 RErrorCode = RERR_NOMEMORY;
48 return False;
49 }
50 #define MASK(prev, cur, next, ch)\
51 (*(prev-ch) + *prev + *(prev+ch)\
52 +*(cur-ch) + 2 * *cur + *(cur+ch)\
53 +*(next-ch) + *next + *(next+ch)) / 10
54
55 memcpy(pptr, image->data, image->width * ch);
56
57 ptr = image->data;
58 nptr = ptr + image->width * ch;
59 tmpp = pptr;
60
61 if (ch == 3) {
62 ptr += 3;
63 nptr += 3;
64 pptr += 3;
65
66 for (y = 1; y < image->height - 1; y++) {
67
68 for (x = 1; x < image->width - 1; x++) {
69 tmp = *ptr;
70 *ptr = MASK(pptr, ptr, nptr, 3);
71 *pptr = tmp;
72 ptr++;
73 nptr++;
74 pptr++;
75
76 tmp = *ptr;
77 *ptr = MASK(pptr, ptr, nptr, 3);
78 *pptr = tmp;
79 ptr++;
80 nptr++;
81 pptr++;
82
83 tmp = *ptr;
84 *ptr = MASK(pptr, ptr, nptr, 3);
85 *pptr = tmp;
86 ptr++;
87 nptr++;
88 pptr++;
89 }
90 pptr = tmpp;
91 ptr += 6;
92 nptr += 6;
93 pptr += 6;
94 }
95 } else {
96 ptr += 4;
97 nptr += 4;
98 pptr += 4;
99
100 for (y = 1; y < image->height - 1; y++) {
101 for (x = 1; x < image->width - 1; x++) {
102 tmp = *ptr;
103 *ptr = MASK(pptr, ptr, nptr, 4);
104 *pptr = tmp;
105 ptr++;
106 nptr++;
107 pptr++;
108
109 tmp = *ptr;
110 *ptr = MASK(pptr, ptr, nptr, 4);
111 *pptr = tmp;
112 ptr++;
113 nptr++;
114 pptr++;
115
116 tmp = *ptr;
117 *ptr = MASK(pptr, ptr, nptr, 4);
118 *pptr = tmp;
119 ptr++;
120 nptr++;
121 pptr++;
122
123 tmp = *ptr;
124 *ptr = MASK(pptr, ptr, nptr, 4);
125 *pptr = tmp;
126 ptr++;
127 nptr++;
128 pptr++;
129 }
130 pptr = tmpp;
131 ptr += 8;
132 nptr += 8;
133 pptr += 8;
134 }
135 }
136
137 return True;
138 }
139
140 #if 0
141 int REdgeDetectImage(RImage * image)
142 {
143 register int x, y, d1, d2, d3, d4, rsum;
144 int w;
145 unsigned char *r, *g, *b, *a;
146 unsigned char *dr, *dg, *db, *da;
147 unsigned char *pr = NULL, *pg = NULL, *pb = NULL, *pa = NULL;
148 RImage *image2;
149
150 image2 = RCloneImage(image);
151
152 pr = alloca(image->width * sizeof(char));
153 if (!pr)
154 goto outofmem;
155
156 pg = alloca(image->width * sizeof(char));
157 if (!pg)
158 goto outofmem;
159
160 pb = alloca(image->width * sizeof(char));
161 if (!pb)
162 goto outofmem;
163
164 pa = alloca(image->width * sizeof(char));
165 if (!pa)
166 goto outofmem;
167
168 r = image->data[0];
169 g = image->data[1];
170 b = image->data[2];
171 a = image->data[3];
172
173 dr = image2->data[0];
174 dg = image2->data[1];
175 db = image2->data[2];
176 da = image2->data[3];
177
178 for (x = 0; x < image->width; x++) {
179 *(dr++) = *(r++);
180 *(dg++) = *(g++);
181 *(db++) = *(b++);
182 }
183
184 w = image->width;
185
186 for (y = 1; y < image->height - 1; y++) {
187 dr[w - 1] = r[w - 1];
188 dg[w - 1] = g[w - 1];
189 db[w - 1] = b[w - 1];
190
191 *(dr++) = *(r++);
192 *(dg++) = *(g++);
193 *(db++) = *(b++);
194
195 for (x = 1; x < image->width - 1; x++) {
196 d1 = r[w + 1] - r[-w - 1];
197 d2 = r[1] - r[-1];
198 d3 = r[-w + 1] - r[w - 1];
199 d4 = r[-w] - r[w];
200
201 rsum = d1 + d2 + d3;
202 if (rsum < 0)
203 rsum = -rsum;
204 d1 = d1 - d2 - d4; /* vertical gradient */
205 if (d1 < 0)
206 d1 = -d1;
207 if (d1 > rsum)
208 rsum = d1;
209 rsum /= 3;
210
211 *(dr++) = rsum;
212
213 d1 = g[w + 1] - g[-w - 1];
214 d2 = g[1] - g[-1];
215 d3 = g[-w + 1] - g[w - 1];
216 d4 = g[-w] - g[w];
217
218 rsum = d1 + d2 + d3;
219 if (rsum < 0)
220 rsum = -rsum;
221 d1 = d1 - d2 - d4; /* vertical gradient */
222 if (d1 < 0)
223 d1 = -d1;
224 if (d1 > rsum)
225 rsum = d1;
226 rsum /= 3;
227
228 *(dg++) = rsum;
229
230 d1 = b[w + 1] - b[-w - 1];
231 d2 = b[1] - b[-1];
232 d3 = b[-w + 1] - b[w - 1];
233 d4 = b[-w] - b[w];
234
235 rsum = d1 + d2 + d3;
236 if (rsum < 0)
237 rsum = -rsum;
238 d1 = d1 - d2 - d4; /* vertical gradient */
239 if (d1 < 0)
240 d1 = -d1;
241 if (d1 > rsum)
242 rsum = d1;
243 rsum /= 3;
244
245 *(db++) = rsum;
246
247 r++;
248 g++;
249 b++;
250 }
251 r++;
252 g++;
253 b++;
254
255 dr++;
256 dg++;
257 db++;
258 }
259 {
260 r = image->data[0];
261 image2->data[0] = r;
262 g = image->data[1];
263 image2->data[1] = g;
264 b = image->data[2];
265 image2->data[2] = b;
266 RReleaseImage(image2);
267 }
268
269 #undef MASK
270
271 return True;
272 }
273
274 int RSmoothImage(RImage * image)
275 {
276 register int x, y;
277 register int v, w;
278 unsigned char *ptr;
279 int ch = image->format == RRGBAFormat;
280
281 ptr = image->data;
282
283 w = image->width * ch;
284 for (y = 0; y < image->height - 1; y++) {
285 for (x = 0; x < image->width - 1; x++) {
286 v = *ptr + 2 * *(ptr + ch) + 2 * *(ptr + w) + *(ptr + w + ch);
287 *ptr = v / 6;
288 v = *(ptr + 1) + 2 * *(ptr + 1 + ch) + 2 * *(ptr + 1 + w) + *(ptr + 1 + w + ch);
289 *(ptr + 1) = v / 6;
290 v = *(ptr + 2) + 2 * *(ptr + 2 + ch) + 2 * *(ptr + 2 + w) + *(ptr + 2 + w + ch);
291 *(ptr + 2) = v / 6;
292
293 ptr += ch;
294 }
295 /* last column */
296 v = 3 * *ptr + 3 * *(ptr + w);
297 *ptr = v / 6;
298 v = 3 * *(ptr + 1) + 3 * *(ptr + 1 + w);
299 *(ptr + 1) = v / 6;
300 v = 3 * *(ptr + 2) + 3 * *(ptr + 2 + w);
301 *(ptr + 2) = v / 6;
302
303 ptr += ch;
304 }
305
306 /* last line */
307 for (x = 0; x < image->width - 1; x++) {
308 v = 3 * *ptr + 3 * *(ptr + ch);
309 *ptr = v / 6;
310 v = 3 * *(ptr + 1) + 3 * *(ptr + 1 + ch);
311 *(ptr + 1) = v / 6;
312 v = 3 * *(ptr + 2) + 3 * *(ptr + 2 + ch);
313 *(ptr + 2) = v / 6;
314
315 ptr += ch;
316 }
317
318 return True;
319 }
320 #endif