home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma01.dms / ma01.adf / wasp / src / operations.c < prev    next >
C/C++ Source or Header  |  1991-12-30  |  7KB  |  343 lines

  1. /* wasp - Copyright 1991 by Steven Reiz
  2.  * see COPYING and wasp.c for further info
  3.  * operations.c, 4/12/90 - 23/6/91, 16/11/91,
  4.  * 8/12/91, 27/12/91 - 31/12/91
  5.  */
  6.  
  7. static char *sourcefile=__FILE__;
  8.  
  9. #include "wasp.h"
  10.  
  11. void
  12. scalex(int t, int n)
  13. {
  14.     NON_REG u_long newxsz;
  15.     REG u_short **newrgb;
  16.     REG long x, y, xtot, newx;
  17.  
  18.     if (t==n || t<=0 || n<=0)
  19.         return;
  20.     init_counter(0, (int)xsz, 20, "x scaling %d/%d", t, n);
  21.     newxsz=xsz*t/n;
  22.     newrgb=Malloc(ysz*sizeof(u_short *));
  23.     for (y=0; y<ysz; ++y)
  24.         newrgb[y]=Calloc(newxsz*sizeof(u_short));
  25.     xtot=0; newx=0;
  26.     for (x=0; x<xsz; ++x) {
  27.         counter();
  28.         xtot+=t;
  29.         while (xtot>=n) {
  30.             xtot-=n;
  31.             y=ysz-1;
  32.             do {
  33.                 newrgb[y][newx]=rgb[y][x];
  34.             } while (--y>=0);
  35.             ++newx;
  36.         }
  37.     }
  38.     for (y=0; y<ysz; ++y)
  39.         free(rgb[y]);
  40.     free(rgb);
  41.     rgb=newrgb;
  42.     xsz=newxsz;
  43.     erase_counter("x scaling done; %ld x %ld", xsz, ysz);
  44. }
  45.  
  46.  
  47. void
  48. scaley(int t, int n)
  49. {
  50.     NON_REG u_long newysz;
  51.     NON_REG u_short **newrgb;
  52.     NON_REG short y, ytot, newy;
  53.     REG u_short *p, *q;
  54.     REG short i;
  55.     
  56.     if (t==n || t<=0 || n<=0)
  57.         return;
  58.     init_counter(0, (int)ysz, 20, "y scaling %d/%d", t, n);
  59.     newysz=ysz*t/n;
  60.     newrgb=Malloc(newysz*sizeof(u_short *));
  61.     ytot=0; newy=0;
  62.     for (y=0; y<ysz; ++y) {
  63.         counter();
  64.         ytot+=t;
  65.         while (ytot>=n) {
  66.             ytot-=n;
  67.             newrgb[newy]=Calloc(xsz*sizeof(u_short));
  68.             p=newrgb[newy];
  69.             q=rgb[y];
  70.             i=xsz-1;
  71.             do {
  72.                 *p++ = *q++;
  73.             } while (--i>=0);
  74.             ++newy;
  75.         }
  76.         free(rgb[y]);
  77.     }
  78.     free(rgb);
  79.     rgb=newrgb;
  80.     ysz=newysz;
  81.     erase_counter("y scaling done; %ld x %ld", xsz, ysz);
  82. }
  83.  
  84.  
  85. struct fac_t {
  86.     int t, n;
  87. } facs[]={
  88.     4, 1,
  89.     3, 1,
  90.     2, 1,
  91.     1, 1,
  92.     1, 2,
  93.     1, 3,
  94.     2, 3,
  95.     1, 4,
  96.     3, 4,
  97.     1, 5,
  98.     4, 5,
  99.     1, 6,
  100.     0, 0
  101. };
  102.  
  103.  
  104. void
  105. scalef(int yflag, float factor)
  106. {
  107.     int t, n;
  108.     int i, besti;
  109.     float error, besterror, tf;
  110.  
  111.     besterror=1000.0;
  112.     for (i=0; facs[i].n; ++i) {
  113.         tf=(float)facs[i].t/(float)facs[i].n;
  114.         if (tf<=factor) {
  115.             error=factor-tf;
  116.             if (error<besterror) {
  117.                 besti=i;
  118.                 besterror=error;
  119.             }
  120.         }
  121.     }
  122.     t=facs[besti].t;
  123.     n=facs[besti].n;
  124.     if (t==4 && n==1)
  125.         t=(int)(factor+0.5);
  126.     else if (t==1 && n==6)
  127.         n=(int)(1/factor+0.5);
  128.     if (yflag)
  129.         scaley(t, n);
  130.     else
  131.         scalex(t, n);
  132. }
  133.  
  134.  
  135. void
  136. do_clipping(int minx, int maxx, int miny, int maxy)
  137. {
  138.     int newxsz, newysz;
  139.     u_short **newrgb;
  140.     short x, y;
  141.     u_short *p, *q;
  142.  
  143.     printe("clipping; [0..%ld x 0..%ld] -> [%d..%d x %d..%d]\n",
  144.      xsz-1, ysz-1, minx, maxx, miny, maxy);
  145.     if (minx<0 || miny<0 || maxx>=xsz || maxy>=ysz || maxx<minx || maxy<miny)
  146.         error0(E0_FATAL, E1_OPERATION, E2_OPTION, E3_CLIP_REGION);
  147.     newxsz=maxx-minx+1;
  148.     newysz=maxy-miny+1;
  149.     for (y=0; y<miny; ++y)
  150.         free(rgb[y]);
  151.     for (y=maxy+1; y<ysz; ++y)
  152.         free(rgb[y]);
  153.     newrgb=Malloc(newysz*sizeof(u_short *));
  154.     init_counter(0, (int)newysz, 20, "clipping");
  155.     for (y=0; y<newysz; ++y) {
  156.         counter();
  157.         newrgb[y]=Calloc(newxsz*sizeof(u_short));
  158.         p=newrgb[y];
  159.         q=rgb[y+miny]+minx;
  160.         x=newxsz-1;
  161.         do {
  162.             *p++ = *q++;
  163.         } while (--x>=0);        
  164.         free(rgb[y+miny]);
  165.     }
  166.     free(rgb);
  167.     rgb=newrgb;
  168.     xsz=newxsz;
  169.     ysz=newysz;
  170.     erase_counter("clipping done; %ld x %ld", xsz, ysz);
  171. }
  172.  
  173.  
  174. void
  175. do_enlarge(int newxsz, int newysz)
  176. {
  177.     u_short **newrgb;
  178.     short x, y, x0, y0;
  179.     u_short *p, *q;
  180.  
  181.     printe("enlarging; [%ld x %ld] -> [%d x %d]\n", xsz, ysz, newxsz, newysz);
  182.     if (newxsz<xsz || newysz<ysz)
  183.     error0(E0_FATAL, E1_OPERATION, E2_OPTION, E3_ENLARGE_SIZE);
  184.     newrgb=Malloc(newysz*sizeof(u_short *));
  185.     x0=(newxsz-xsz)/2;
  186.     y0=(newysz-ysz)/2;
  187.     init_counter(0, (int)newysz, 20, "enlarging");
  188.     for (y=0; y<newysz; ++y) {
  189.         counter();
  190.     if (newxsz==xsz && y>=y0 && y<y0+ysz)
  191.         newrgb[y]=rgb[y-y0];
  192.     else
  193.             newrgb[y]=Calloc(newxsz*sizeof(u_short));
  194.     if (newxsz!=xsz && y>=y0 && y<y0+ysz) {
  195.         p=newrgb[y]+x0;
  196.         q=rgb[y-y0];
  197.             x=xsz-1;
  198.             do {
  199.             *p++ = *q++;
  200.             } while (--x>=0);        
  201.         free(rgb[y-y0]);
  202.     }
  203.     }
  204.     free(rgb);
  205.     rgb=newrgb;
  206.     xsz=newxsz;
  207.     ysz=newysz;
  208.     erase_counter("enlarging done; %ld x %ld", xsz, ysz);
  209. }
  210.  
  211.  
  212. void
  213. xaverage(void)
  214. {
  215.     NON_REG int y;
  216.     REG short x, *p, *q;
  217.     NON_REG u_short *oldrgby;
  218.     REG long c1, c2, mask1, mask2;
  219.     NON_REG long newxsz;
  220.  
  221.     init_counter(0, (int)ysz, 20, "xaveraging");
  222.     newxsz=xsz/2;
  223.     mask1=0xeef;
  224.     mask2=0x110;
  225.     for (y=0; y<ysz; ++y) {
  226.         counter();
  227.         oldrgby=rgb[y];
  228.         p=(short *)oldrgby;
  229.         rgb[y]=Calloc(newxsz*sizeof(u_short));
  230.         q=(short *)rgb[y];
  231.         x=newxsz-1;
  232.         do {
  233.             c1= *p++;
  234.             c2= *p++;
  235.             *q++ =(((c1&mask1)+(c2&mask1))>>1)+(c1&c2&mask2);
  236.         } while (--x>=0);
  237.         free(oldrgby);
  238.     }
  239.     xsz=newxsz;
  240.     erase_counter("xaverage done; %ld x %ld", xsz, ysz);
  241. }
  242.  
  243.  
  244. void
  245. xmirror(void)
  246. {
  247.     u_short *line;
  248.     short y, x;
  249.     u_short *p, *q;
  250.  
  251.     init_counter(0, (int)ysz, 20, "xmirroring");
  252.     line=Malloc(xsz*sizeof(u_short));
  253.     for (y=0; y<ysz; ++y) {
  254.         counter();
  255.         x=xsz-1;
  256.         p=line;
  257.         q=rgb[y]+xsz;
  258.         do {
  259.             *p++ = *--q;
  260.         } while (--x>=0);
  261.         p=rgb[y];
  262.         rgb[y]=line;
  263.         line=p;
  264.     }
  265.     erase_counter("xmirror done");
  266.     free(line);
  267. }
  268.  
  269.  
  270. void
  271. ymirror(void)
  272. {
  273.     short i, j;
  274.     u_short *p;
  275.  
  276.     i=0;
  277.     j=ysz-1;
  278.     while (i<j) {
  279.         p=rgb[i];
  280.         rgb[i]=rgb[j];
  281.         rgb[j]=p;
  282.         ++i;
  283.         --j;
  284.     }
  285.     printe("ymirror done\n");
  286. }
  287.  
  288.  
  289. void
  290. transpose(void)
  291. {
  292.     u_short **newrgb;
  293.     short x, y;
  294.     u_short *p;
  295.     long t;
  296.  
  297.     init_counter(0, (int)ysz, 10, "transposing");
  298.     newrgb=Malloc(xsz*sizeof(u_short *));
  299.     for (y=0; y<xsz; ++y)
  300.         newrgb[y]=Calloc(ysz*sizeof(u_short));
  301.     for (y=0; y<ysz; ++y) {
  302.         counter();
  303.         x=xsz-1;
  304.         p=rgb[y]+xsz;
  305.         do {
  306.             newrgb[x][y]= *--p;
  307.         } while (--x>=0);
  308.         free(rgb[y]);
  309.     }
  310.     free(rgb);
  311.     rgb=newrgb;
  312.     t=xsz;
  313.     xsz=ysz;
  314.     ysz=t;
  315.     erase_counter("transpose done; %ld x %ld", xsz, ysz);
  316. }
  317.  
  318.  
  319. void
  320. testpat(int testx, int testy)
  321. {
  322.     long x, y, cx, cy;
  323.     u_short clr;
  324.  
  325.     xsz=testx;
  326.     ysz=testy;
  327.     printe("TESTPAT input; %ld x %ld\n", xsz, ysz);
  328.     rgb=Malloc(ysz*sizeof(u_short *));
  329.     init_counter(0, (int)ysz, 20, "creating test pattern");
  330.     for (y=0; y<ysz; ++y)
  331.         rgb[y]=Calloc(xsz*sizeof(u_short));
  332.     for (y=0; y<ysz; ++y) {
  333.         counter();
  334.         cy=(64L*y)/ysz;
  335.         clr=((cy&3)<<6)|((cy&60)>>2);
  336.         for (x=0; x<xsz; ++x) {
  337.             cx=(64L*x)/xsz;
  338.             rgb[y][x]=clr|((cx&60)<<6)|((cx&3)<<4);
  339.         }
  340.     }
  341.     erase_counter(NULL);
  342. }
  343.