mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 12:28:22 +01:00
322 lines
6.3 KiB
C
322 lines
6.3 KiB
C
/*
|
|
* Raster graphics library
|
|
*
|
|
* Copyright (c) 1997 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 <config.h>
|
|
|
|
/* AIX requires this to be the first thing in the file. */
|
|
#ifdef __GNUC__
|
|
# define alloca __builtin_alloca
|
|
#else
|
|
# if HAVE_ALLOCA_H
|
|
# include <alloca.h>
|
|
# else
|
|
# ifdef _AIX
|
|
# pragma alloca
|
|
# else
|
|
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
|
char *alloca ();
|
|
# endif
|
|
# endif
|
|
# endif
|
|
#endif
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <X11/Xlib.h>
|
|
#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 w, tmp;
|
|
unsigned char *r, *g, *b, *a;
|
|
unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
|
|
|
|
#define MASK(c,pc,p) ((*c+ *c + *(c-1) + *(c+1) + pc[p] + pc[p-1] + pc[p+1] \
|
|
+ *(c+w) + *(c+w-1) + *(c+w+1))/10)
|
|
|
|
pr = (unsigned char*)alloca(image->width*sizeof(char));
|
|
if (!pr)
|
|
goto outofmem;
|
|
|
|
pg = (unsigned char*)alloca(image->width*sizeof(char));
|
|
if (!pg)
|
|
goto outofmem;
|
|
|
|
pb = (unsigned char*)alloca(image->width*sizeof(char));
|
|
if (!pb)
|
|
goto outofmem;
|
|
|
|
pa = (unsigned char*)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];
|
|
|
|
|
|
for (x=0; x<image->width; x++) {
|
|
pr[x] = *(r++);
|
|
pg[x] = *(g++);
|
|
pb[x] = *(b++);
|
|
}
|
|
|
|
w = image->width;
|
|
|
|
for (y=1; y<image->height-1; y++) {
|
|
pr[w-1] = r[w-1];
|
|
pg[w-1] = g[w-1];
|
|
pb[w-1] = b[w-1];
|
|
|
|
pr[0] = *(r++);
|
|
pg[0] = *(g++);
|
|
pb[0] = *(b++);
|
|
|
|
for (x=1; x<image->width-1; x++) {
|
|
tmp = *r;
|
|
*(r++) = MASK(r,pr,x);
|
|
pr[x] = tmp;
|
|
|
|
tmp = *g;
|
|
*(g++) = MASK(g,pg,x);
|
|
pg[x] = tmp;
|
|
|
|
tmp = *b;
|
|
*(b++) = MASK(b,pb,x);
|
|
pb[x] = tmp;
|
|
}
|
|
r++;
|
|
g++;
|
|
b++;
|
|
}
|
|
|
|
#undef MASK
|
|
|
|
#ifdef C_ALLOCA
|
|
alloca(0);
|
|
#endif
|
|
return True;
|
|
|
|
outofmem:
|
|
RErrorCode = RERR_NOMEMORY;
|
|
#ifdef C_ALLOCA
|
|
alloca(0);
|
|
#endif
|
|
return False;
|
|
}
|
|
|
|
|
|
#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;
|
|
RDestroyImage(image2);
|
|
}
|
|
|
|
#undef MASK
|
|
|
|
return True;
|
|
}
|
|
|
|
|
|
int
|
|
RSmoothImage(RImage *image)
|
|
{
|
|
register int x, y;
|
|
register int v, w;
|
|
unsigned char *r, *g, *b, *a;
|
|
|
|
r = image->data[0];
|
|
g = image->data[1];
|
|
b = image->data[2];
|
|
a = image->data[3];
|
|
|
|
w = image->width;
|
|
for (y=0; y<image->height - 1; y++) {
|
|
for (x=0; x<image->width - 1; x++) {
|
|
v = *r + 2 * *(r + 1) + 2 * *(r + w) + *(r + w + 1);
|
|
*(r++) = v/6;
|
|
|
|
v = *g + 2 * *(g + 1) + 2 * *(g + w) + *(g + w + 1);
|
|
*(g++) = v/6;
|
|
|
|
v = *b + 2 * *(b + 1) + 2 * *(b + w) + *(b + w + 1);
|
|
*(b++) = v/6;
|
|
}
|
|
|
|
/* last column */
|
|
v = 3 * *r + 3 * *(r + w);
|
|
*(r++) = v/6;
|
|
|
|
v = 3 * *g + 3 * *(g + w);
|
|
*(g++) = v/6;
|
|
|
|
v = 3 * *b + 3 * *(b + w);
|
|
*(b++) = v/6;
|
|
}
|
|
|
|
/* last line */
|
|
for (x=0; x<image->width - 1; x++) {
|
|
v = 3 * *r + 3 * *(r + 1);
|
|
*(r++) = v/6;
|
|
|
|
v = 3 * *g + 3 * *(g + 1);
|
|
*(g++) = v/6;
|
|
|
|
v = 3 * *b + 3 * *(b + 1);
|
|
*(b++) = v/6;
|
|
}
|
|
|
|
return True;
|
|
}
|
|
#endif
|