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