00001
00002
00003 #include "../c/eus.h"
00004
00005 #pragma init (init_object_module)
00006 extern void convolve(context *, int, pointer *);
00007 static init_object_module()
00008 { add_module_initializer("convolve", convolve);}
00009
00010 #define is2Dstring(a) (isarray(a) && \
00011 ((a)->c.ary.rank==makeint(2)) && \
00012 isstring((a)->c.ary.entity))
00013 pointer CONVOLVE3(ctx,n,argv)
00014
00015 context *ctx;
00016 int n;
00017 pointer argv[];
00018 {
00019 pointer convp, imgp, resultp;
00020 char *conv;
00021 unsigned char *img, *result, *g;
00022 register int x,y,width,height, v, diviser;
00023
00024 ckarg(4);
00025 convp= argv[0]; imgp=argv[2]; resultp= argv[3];
00026 diviser=ckintval(argv[1]);
00027 if (!is2Dstring(convp) || !is2Dstring(imgp) || !is2Dstring(resultp))
00028 error(E_NOARRAY);
00029 conv=(char *)(convp->c.ary.entity->c.str.chars);
00030 img=imgp->c.ary.entity->c.str.chars;
00031 result=resultp->c.ary.entity->c.str.chars;
00032 width=intval(imgp->c.ary.dim[1]); height=intval(imgp->c.ary.dim[0]);
00033
00034 for (y=1; y<=height-1; y++) {
00035 for (x=1; x<=width-1; x++) {
00036 g= &img[width*y+x];
00037 v= g[-width-1]*conv[0] + g[-width]* conv[1] + g[-width+1]*conv[2] +
00038 g[-1]*conv[3] + g[0]* conv[4] + g[1]*conv[5] +
00039 g[width-1]*conv[6] + g[width]* conv[7] + g[width+1]*conv[8];
00040 result[width*y+x]=v/diviser;}
00041 }
00042 return(resultp);}
00043
00044 pointer LOOK_UP(ctx,n,argv)
00045
00046 context *ctx;
00047 int n;
00048 pointer argv[];
00049 { pointer imgp, tablep, resultp;
00050 register unsigned char *img, *ctable, *result;
00051 register long size, i, *itable;
00052
00053 ckarg(3);
00054 imgp=argv[0]; resultp= argv[1]; tablep=argv[2];
00055 if (!isstring(imgp) || !isvector(tablep) || !isstring(resultp))
00056 error(E_NOSTRING);
00057 if (elmtypeof(imgp)==ELM_FOREIGN)
00058 img=(unsigned char *)imgp->c.ivec.iv[0];
00059 else img=imgp->c.str.chars;
00060 if (elmtypeof(resultp)==ELM_FOREIGN)
00061 result=(unsigned char *)resultp->c.ivec.iv[0];
00062 else result=resultp->c.str.chars;
00063 size=vecsize(imgp);
00064 if (elmtypeof(tablep)==ELM_INT) {
00065 itable=tablep->c.ivec.iv;
00066 for (i=0; i<size; i++) result[i]=itable[img[i]];}
00067 else if (elmtypeof(tablep)==ELM_CHAR || elmtypeof(tablep)==ELM_BYTE) {
00068 ctable=tablep->c.str.chars;
00069 for (i=0; i<size; i++) result[i]=ctable[img[i]];}
00070 return(resultp);}
00071
00072 pointer HALVE_IMAGE(ctx,n,argv)
00073 context *ctx;
00074 int n;
00075 pointer argv[];
00076 { pointer imgp, half_imgp;
00077 register unsigned char *img, *half_img;
00078 register int i, j, base, half_base;
00079 int width, height;
00080 register int half_width, half_height;
00081
00082 ckarg(2);
00083 imgp=argv[0]; half_imgp=argv[1];
00084 if (!is2Dstring(imgp) || !is2Dstring(half_imgp)) error(E_NOARRAY);
00085 width=intval(imgp->c.ary.dim[1]);
00086 height=intval(imgp->c.ary.dim[0]);
00087 half_width=width/2; half_height=height/2;
00088
00089 img= imgp->c.ary.entity->c.str.chars;
00090 half_img= half_imgp->c.ary.entity->c.str.chars;
00091
00092 for (j=0; j<half_height; j++) {
00093 base= width*j*2; half_base=half_width*j;
00094 for (i=0; i<half_width; i++)
00095 half_img[half_base+i]=
00096 (unsigned long)(img[base+i*2]+img[base+i*2+1]+
00097 img[base+width+i*2]+img[base+i*2+width+1])/4; }
00098 return(half_imgp);}
00099
00100 pointer DOUBLE_IMAGE(ctx,n,argv)
00101 context *ctx;
00102 int n;
00103 pointer argv[];
00104 { pointer imgp, double_imgp;
00105 register unsigned char *img, *double_img;
00106 register int i, j, base, double_base;
00107 int width, height;
00108 register int double_width, double_height;
00109
00110 ckarg(2);
00111 imgp=argv[0]; double_imgp=argv[1];
00112 if (!is2Dstring(imgp) || !is2Dstring(double_imgp)) error(E_NOARRAY);
00113 width=intval(imgp->c.ary.dim[1]);
00114 height=intval(imgp->c.ary.dim[0]);
00115 double_width=width*2; double_height=height*2;
00116
00117 img= imgp->c.ary.entity->c.str.chars;
00118 double_img= double_imgp->c.ary.entity->c.str.chars;
00119
00120 for (j=0; j<height; j++) {
00121 base= width*j; double_base=double_width*j*2;
00122 for (i=0; i<width; i++)
00123 double_img[double_base+i*2]=
00124 double_img[double_base+i*2+1]=
00125 double_img[double_base+double_width+i*2]=
00126 double_img[double_base+double_width+i*2+1]=
00127 (unsigned long)(img[base+i]);
00128 }
00129 return(double_imgp);}
00130
00131
00132 static median_img(img, width, height, x, y, size)
00133 unsigned char *img;
00134 register int width, height, x, y, size;
00135 { register int med, p, q, r;
00136 register int i, j, k, v, cindex;
00137 unsigned char seq[100], up[100], down[100];
00138
00139 cindex=size*size/2;
00140 k=0;
00141 for (j=0; j<size; j++)
00142 for (i=0; i<size; i++)
00143 seq[k++]= img[(j+y)*width+(x+i)];
00144
00145 find_med:
00146
00147 med=seq[0];
00148 p=q=r=0;
00149
00150 for (i=0; i<k; i++)
00151 v=seq[i];
00152 if (v==med) r++;
00153 else if (v>med) up[p++]=v;
00154 else down[q++]=v;
00155
00156 if (q<=cindex)
00157 if (q+r>=cindex) return(med);
00158 else {
00159 for (i=0; i<p; i++) seq[i]=up[i];
00160 cindex=cindex-(q+r); k=p;
00161 goto find_med; }
00162 else {
00163 for (i=0; i<q; i++) seq[i]=down[i];
00164 k=q;
00165 goto find_med; }
00166 }
00167
00168 pointer MEDIAN_IMAGE(ctx,n,argv)
00169 context *ctx;
00170 int n;
00171 pointer argv[];
00172 { pointer img1, img2;
00173 register unsigned char *img1p, *img2p;
00174 register int i,j;
00175 int width, height, swidth, sheight;
00176 int hgrid, grid_size, hscale, scale;
00177
00178 ckarg2(2,4);
00179 img1=argv[0];
00180 width=intval(img1->c.ary.dim[1]);
00181 height=intval(img1->c.ary.dim[0]);
00182 grid_size=ckintval(argv[1]);
00183 scale = ckintval(argv[2]);
00184 hgrid=grid_size/2;
00185 hscale=scale/2;
00186 img2=argv[3];
00187 if (!is2Dstring(img1) || !is2Dstring(img2)) error(E_NOARRAY);
00188 img1p=img1->c.ary.entity->c.str.chars;
00189 img2p=img2->c.ary.entity->c.str.chars;
00190 swidth=width/scale;
00191 sheight=height/scale;
00192 for (j=0; j<sheight-1; j++) {
00193 for (i=0; i<swidth-1; i++) {
00194 img2p[j*swidth+i]=
00195 median_img(img1p, width, height, scale*i, scale*j, grid_size);
00196 }}
00197 return(img2);}
00198
00199 void convolve(ctx,n,argv)
00200 context *ctx;
00201 int n;
00202 pointer argv[];
00203 { pointer mod=argv[0];
00204
00205
00206 defun(ctx,"CONVOLVE3",mod,CONVOLVE3);
00207 defun(ctx,"LOOK-UP",mod,LOOK_UP);
00208 defun(ctx,"HALVE-IMAGE",mod,HALVE_IMAGE);
00209 defun(ctx,"DOUBLE-IMAGE",mod,DOUBLE_IMAGE);
00210 defun(ctx,"MEDIAN-IMAGE",mod,MEDIAN_IMAGE);
00211 }
00212