/* * Raster graphics library * * Copyright (c) 1997-2003 Alfredo K. Kojima * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "wraster.h" /* *---------------------------------------------------------------------- * RBlurImage-- * Apply 3x3 1 1 1 low pass, convolution mask to image. * 1 2 1 * 1 1 1 /10 *---------------------------------------------------------------------- */ int RBlurImage(RImage * image) { register int x, y; register int tmp; unsigned char *ptr, *nptr; unsigned char *pptr = NULL, *tmpp; int ch = image->format == RRGBAFormat ? 4 : 3; pptr = malloc(image->width * ch); if (!pptr) { RErrorCode = RERR_NOMEMORY; return False; } #define MASK(prev, cur, next, ch)\ (*(prev-ch) + *prev + *(prev+ch)\ +*(cur-ch) + 2 * *cur + *(cur+ch)\ +*(next-ch) + *next + *(next+ch)) / 10 memcpy(pptr, image->data, image->width * ch); ptr = image->data; nptr = ptr + image->width * ch; tmpp = pptr; if (ch == 3) { ptr += 3; nptr += 3; pptr += 3; for (y = 1; y < image->height - 1; y++) { for (x = 1; x < image->width - 1; x++) { tmp = *ptr; *ptr = MASK(pptr, ptr, nptr, 3); *pptr = tmp; ptr++; nptr++; pptr++; tmp = *ptr; *ptr = MASK(pptr, ptr, nptr, 3); *pptr = tmp; ptr++; nptr++; pptr++; tmp = *ptr; *ptr = MASK(pptr, ptr, nptr, 3); *pptr = tmp; ptr++; nptr++; pptr++; } pptr = tmpp; ptr += 6; nptr += 6; pptr += 6; } } else { ptr += 4; nptr += 4; pptr += 4; for (y = 1; y < image->height - 1; y++) { for (x = 1; x < image->width - 1; x++) { tmp = *ptr; *ptr = MASK(pptr, ptr, nptr, 4); *pptr = tmp; ptr++; nptr++; pptr++; tmp = *ptr; *ptr = MASK(pptr, ptr, nptr, 4); *pptr = tmp; ptr++; nptr++; pptr++; tmp = *ptr; *ptr = MASK(pptr, ptr, nptr, 4); *pptr = tmp; ptr++; nptr++; pptr++; tmp = *ptr; *ptr = MASK(pptr, ptr, nptr, 4); *pptr = tmp; ptr++; nptr++; pptr++; } pptr = tmpp; ptr += 8; nptr += 8; pptr += 8; } } return True; } #if 0 int REdgeDetectImage(RImage * image) { register int x, y, d1, d2, d3, d4, rsum; int w; unsigned char *r, *g, *b, *a; unsigned char *dr, *dg, *db, *da; unsigned char *pr = NULL, *pg = NULL, *pb = NULL, *pa = NULL; RImage *image2; image2 = RCloneImage(image); pr = alloca(image->width * sizeof(char)); if (!pr) goto outofmem; pg = alloca(image->width * sizeof(char)); if (!pg) goto outofmem; pb = alloca(image->width * sizeof(char)); if (!pb) goto outofmem; pa = alloca(image->width * sizeof(char)); if (!pa) goto outofmem; r = image->data[0]; g = image->data[1]; b = image->data[2]; a = image->data[3]; dr = image2->data[0]; dg = image2->data[1]; db = image2->data[2]; da = image2->data[3]; for (x = 0; x < image->width; x++) { *(dr++) = *(r++); *(dg++) = *(g++); *(db++) = *(b++); } w = image->width; for (y = 1; y < image->height - 1; y++) { dr[w - 1] = r[w - 1]; dg[w - 1] = g[w - 1]; db[w - 1] = b[w - 1]; *(dr++) = *(r++); *(dg++) = *(g++); *(db++) = *(b++); for (x = 1; x < image->width - 1; x++) { d1 = r[w + 1] - r[-w - 1]; d2 = r[1] - r[-1]; d3 = r[-w + 1] - r[w - 1]; d4 = r[-w] - r[w]; rsum = d1 + d2 + d3; if (rsum < 0) rsum = -rsum; d1 = d1 - d2 - d4; /* vertical gradient */ if (d1 < 0) d1 = -d1; if (d1 > rsum) rsum = d1; rsum /= 3; *(dr++) = rsum; d1 = g[w + 1] - g[-w - 1]; d2 = g[1] - g[-1]; d3 = g[-w + 1] - g[w - 1]; d4 = g[-w] - g[w]; rsum = d1 + d2 + d3; if (rsum < 0) rsum = -rsum; d1 = d1 - d2 - d4; /* vertical gradient */ if (d1 < 0) d1 = -d1; if (d1 > rsum) rsum = d1; rsum /= 3; *(dg++) = rsum; d1 = b[w + 1] - b[-w - 1]; d2 = b[1] - b[-1]; d3 = b[-w + 1] - b[w - 1]; d4 = b[-w] - b[w]; rsum = d1 + d2 + d3; if (rsum < 0) rsum = -rsum; d1 = d1 - d2 - d4; /* vertical gradient */ if (d1 < 0) d1 = -d1; if (d1 > rsum) rsum = d1; rsum /= 3; *(db++) = rsum; r++; g++; b++; } r++; g++; b++; dr++; dg++; db++; } { r = image->data[0]; image2->data[0] = r; g = image->data[1]; image2->data[1] = g; b = image->data[2]; image2->data[2] = b; RReleaseImage(image2); } #undef MASK return True; } int RSmoothImage(RImage * image) { register int x, y; register int v, w; unsigned char *ptr; int ch = image->format == RRGBAFormat; ptr = image->data; w = image->width * ch; for (y = 0; y < image->height - 1; y++) { for (x = 0; x < image->width - 1; x++) { v = *ptr + 2 * *(ptr + ch) + 2 * *(ptr + w) + *(ptr + w + ch); *ptr = v / 6; v = *(ptr + 1) + 2 * *(ptr + 1 + ch) + 2 * *(ptr + 1 + w) + *(ptr + 1 + w + ch); *(ptr + 1) = v / 6; v = *(ptr + 2) + 2 * *(ptr + 2 + ch) + 2 * *(ptr + 2 + w) + *(ptr + 2 + w + ch); *(ptr + 2) = v / 6; ptr += ch; } /* last column */ v = 3 * *ptr + 3 * *(ptr + w); *ptr = v / 6; v = 3 * *(ptr + 1) + 3 * *(ptr + 1 + w); *(ptr + 1) = v / 6; v = 3 * *(ptr + 2) + 3 * *(ptr + 2 + w); *(ptr + 2) = v / 6; ptr += ch; } /* last line */ for (x = 0; x < image->width - 1; x++) { v = 3 * *ptr + 3 * *(ptr + ch); *ptr = v / 6; v = 3 * *(ptr + 1) + 3 * *(ptr + 1 + ch); *(ptr + 1) = v / 6; v = 3 * *(ptr + 2) + 3 * *(ptr + 2 + ch); *(ptr + 2) = v / 6; ptr += ch; } return True; } #endif