convolve.c
Go to the documentation of this file.
00001 /* cc -c -Bstatic -Dsun4 -I../c convolve.c */
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 /* (convolve3 convolution_mask divisor image result) */
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 /* foreach element indexed i, result[i]=table[src[i]] */
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 /* (median img1 grid scale imgr) */
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 { /* find (p-cindex)th in up */
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 /*  printf("convolve is being initialized. mod=%x\n",mod); */
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 


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Sep 3 2015 10:36:19