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 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 /* (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;
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 /* (median img1 grid scale imgr) */
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 { /* find (p-cindex)th in up */
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 /*  printf("convolve is being initialized. mod=%x\n",mod); */
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 


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Jun 6 2019 18:05:53