home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 564a.lha / wasp_v1.21 / Src.LZH / Src / wriffcount.c < prev    next >
C/C++ Source or Header  |  1991-10-19  |  14KB  |  682 lines

  1. /* wasp - copyright Steven Reiz 1990, 1991
  2.  * see wasp.c for further info
  3.  * wriffcount.c, 4/12/90 - 29/12/90,
  4.  * 2/6/91, 23/6/91, 1/7/91 - 10/7/91
  5.  */
  6.  
  7. #include "wasp.h"
  8. #include "wriff.h"
  9. #ifndef NOSH
  10. #include "wriffcount.sh"
  11. #endif
  12.  
  13. static u_char *xor_tab=NULL;
  14.  
  15.  
  16. #ifdef AZTEC_C
  17. extern clear_counts(void);
  18. #asm
  19.     xdef    _clear_counts
  20. _clear_counts:
  21.     movem.l    d2-d7/a2-a6,-(sp)
  22.     move.l    _counts,a6
  23.     add.l    #$4000,a6
  24.     move.w    #63,d7
  25.     move.l    #0,d0
  26.     move.l    d0,d1
  27.     move.l    d0,d2
  28.     move.l    d0,d3
  29.     move.l    d0,d4
  30.     move.l    d0,d5
  31.     move.l    d0,d6
  32.     move.l    d0,a0
  33.     move.l    d0,a1
  34.     move.l    d0,a2
  35.     move.l    d0,a3
  36.     move.l    d0,a4
  37.     move.l    d0,a5
  38. clear_counts_2:
  39.     movem.l    d0-d6/a0-a5,-(a6)
  40.     movem.l    d0-d6/a0-a5,-(a6)
  41.     movem.l    d0-d6/a0-a5,-(a6)
  42.     movem.l    d0-d6/a0-a5,-(a6)
  43.     movem.l    d0-d6/a0-a4,-(a6)
  44.     dbf.w    d7,clear_counts_2
  45.     movem.l    (sp)+,d2-d7/a2-a6
  46.     rts
  47. #endasm
  48. #else /* !AZTEC_C */
  49. #ifdef __STDC__
  50. PRIVATE clear_counts(void)
  51. #else
  52. PRIVATE clear_counts()
  53. #endif
  54. {
  55.     short i;
  56.     u_long *p;
  57.     long r0, r1, r2, r3, r4, r5, r6, r7;
  58.  
  59.     p=counts; i=NRGB/16-1;
  60.     r0=0;  r1=r0; r2=r0; r3=r0;
  61.     r4=r0; r5=r0; r6=r0; r7=r0;
  62.     do {
  63.         *p++ =r0; *p++ =r1; *p++ =r2; *p++ =r3;
  64.         *p++ =r4; *p++ =r5; *p++ =r6; *p++ =r7;
  65.         *p++ =r0; *p++ =r1; *p++ =r2; *p++ =r3;
  66.         *p++ =r4; *p++ =r5; *p++ =r6; *p++ =r7;
  67.     } while (--i>=0);
  68. }
  69. #endif /* AZTEC_C */
  70.  
  71.  
  72. #ifdef __STDC__
  73. PRIVATE fill_xor_tab(void)
  74. #else
  75. PRIVATE fill_xor_tab()
  76. #endif
  77. {
  78.     short i;
  79.     u_char *tab;
  80.  
  81.     xor_tab=Malloc(NRGB);
  82.     tab=xor_tab+NRGB;
  83.     i=NRGB-1;
  84.     do {
  85.         if ((i&0xf0f)==0 || (i&0xff0)==0 || (i&0x0ff)==0)
  86.             *--tab=0;
  87.         else
  88.             *--tab=1;
  89.     } while (--i>=0);
  90. }
  91.  
  92.  
  93. #ifdef __STDC__
  94. PRIVATE void call1(int row)
  95. #else
  96. PRIVATE void call1(row)
  97. int row;
  98. #endif
  99. {
  100.     u_short *pp;
  101.     u_long  *cp;
  102.     short x;
  103.  
  104.     pp=rgb[row];
  105.     cp=counts;
  106.     x=xsz-1;
  107.     do {
  108.         ++cp[*pp++];
  109.     } while (--x>=0);
  110. }
  111.  
  112.  
  113. #ifdef __STDC__
  114. PRIVATE void calldif(int row)
  115. #else
  116. PRIVATE void calldif(row)
  117. int row;
  118. #endif
  119. {
  120.     u_short *pp;
  121.     u_long  *cp;
  122.     short x;
  123.     short prevcolor, color;
  124.     short d, t;
  125.  
  126.     pp=rgb[row];
  127.     cp=counts;
  128.     x=xsz-1;
  129.     prevcolor=0;
  130.     do {
  131.         color= *pp++;
  132.         t=(color-prevcolor)>>8;
  133.         if (t<0) d= -t; else d=t;
  134.         t=((color&0x00f0)-(prevcolor&0x00f0))>>4;
  135.         if (t<0) d-=t;  else d+=t;
  136.         t=(color&0x000f)-(prevcolor&0x000f);
  137.         if (t<0) d-=t;  else d+=t;
  138.         cp[color]+=d;
  139.         prevcolor=color;
  140.     } while (--x>=0);
  141. }
  142.  
  143.  
  144. #ifdef __STDC__
  145. PRIVATE void callfixdif(int row)
  146. #else
  147. PRIVATE void callfixdif(row)
  148. int row;
  149. #endif
  150. {
  151.     u_short *pp;
  152.     u_long  *cp;
  153.     short x;
  154.     short prevcolor, color;
  155.     short r, g, b;
  156.  
  157.     pp=rgb[row];
  158.     cp=counts;
  159.     x=xsz-1;
  160.     prevcolor=0;
  161.     do {
  162.         color= *pp++;
  163.         r=(color-prevcolor)>>8;
  164.         if (r<0) r= -r;
  165.         g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
  166.         if (g<0) g= -g;
  167.         b=(color&0x000f)-(prevcolor&0x000f);
  168.         if (b<0) b= -b;
  169.         if (r>g) {
  170.             if (b>r)
  171.                 cp[color]+=r+g;
  172.             else
  173.                 cp[color]+=b+g;
  174.         } else {
  175.             if (b>g)
  176.                 cp[color]+=r+g;
  177.             else
  178.                 cp[color]+=r+b;
  179.         }
  180.         prevcolor=color;
  181.     } while (--x>=0);
  182. }
  183.  
  184.  
  185. #ifdef __STDC__
  186. PRIVATE void cjump1(int row)
  187. #else
  188. PRIVATE void cjump1(row)
  189. int row;
  190. #endif
  191. {
  192.     u_short *pp;
  193.     u_long  *cp;
  194.     u_char *tab;
  195.     short x;
  196.     long prevcolor, color;
  197.  
  198.     if (!xor_tab)
  199.     fill_xor_tab();
  200.     tab=xor_tab;
  201.     pp=rgb[row];
  202.     cp=counts;
  203.     prevcolor= *pp++;
  204.     ++cp[prevcolor];
  205.     x=xsz-2;
  206.     do {
  207.         color= *pp++;
  208.     if (tab[color^prevcolor])
  209.         ++cp[color];
  210.         prevcolor=color;
  211.     } while (--x>=0);
  212. }
  213.  
  214.  
  215. #ifdef __STDC__
  216. PRIVATE void cjump21(int row)
  217. #else
  218. PRIVATE void cjump21(row)
  219. int row;
  220. #endif
  221. {
  222.     u_short *pp;
  223.     u_long  *cp;
  224.     u_char *tab;
  225.     short x;
  226.     long prevcolor, color, add;
  227.  
  228.     if (!xor_tab)
  229.     fill_xor_tab();
  230.     tab=xor_tab;
  231.     pp=rgb[row];
  232.     cp=counts;
  233.     add=1;
  234.     prevcolor= *pp++;
  235.     cp[prevcolor]+=2;
  236.     x=xsz-2;
  237.     do {
  238.         color= *pp++;
  239.         if (tab[color^prevcolor])
  240.         add=2;
  241.         cp[color]+=add;
  242.         add>>=1;
  243.         prevcolor=color;
  244.     } while (--x>=0);
  245. }
  246.  
  247.  
  248. #ifdef __STDC__
  249. PRIVATE void cjumpdif(int row)
  250. #else
  251. PRIVATE void cjumpdif(row)
  252. int row;
  253. #endif
  254. {
  255.     u_short *pp;
  256.     u_long  *cp;
  257.     u_char *tab;
  258.     short x;
  259.     long prevcolor, color, d, t;
  260.  
  261.     if (!xor_tab)
  262.     fill_xor_tab();
  263.     tab=xor_tab;
  264.     pp=rgb[row];
  265.     cp=counts;
  266.     prevcolor= *pp++;
  267.     cp[prevcolor]+=12;
  268.     x=xsz-2;
  269.     do {
  270.         color= *pp++;
  271.         if (tab[color^prevcolor]) {
  272.             if ((d=(color-prevcolor)>>8)<0)
  273.         d= -d;
  274.             if ((t=((color&0x00f0)-(prevcolor&0x00f0))>>4)<0)
  275.         d-=t;
  276.         else
  277.         d+=t;
  278.             if ((t=(color&0x000f)-(prevcolor&0x000f))<0)
  279.         d-=t;
  280.         else
  281.         d+=t;
  282.             cp[color]+=d;
  283.         }
  284.         prevcolor=color;
  285.     } while (--x>=0);
  286. }
  287.  
  288.  
  289. #ifdef __STDC__
  290. PRIVATE void cjumpdifsh(int row)
  291. #else
  292. PRIVATE void cjumpdifsh(row)
  293. int row;
  294. #endif
  295. {
  296.     u_short *pp;
  297.     u_long  *cp;
  298.     short x;
  299.     short prevcolor, color;
  300.     short d, t;
  301.     long add;
  302.  
  303.     pp=rgb[row];
  304.     cp=counts;
  305.     color= *pp;
  306.     add=(color>>8)+((color>>4)&0x0f)+(color&0x0f);
  307.     prevcolor=0;
  308.     x=xsz-1;
  309.     do {
  310.         color= *pp++;
  311.         t=color^prevcolor;
  312.         if (!( (t&0xf0f)==0 || (t&0xff0)==0 || (t&0x0ff)==0 )) {
  313.             t=(color-prevcolor)>>8;
  314.             if (t<0) d= -t; else d=t;
  315.             t=((color&0x00f0)-(prevcolor&0x00f0))>>4;
  316.             if (t<0) d-=t;  else d+=t;
  317.             t=(color&0x000f)-(prevcolor&0x000f);
  318.             if (t<0) d-=t;  else d+=t;
  319.             if (add<d)
  320.                 add=d;
  321.         }
  322.         cp[color]+=add;
  323.         add>>=1;
  324.         prevcolor=color;
  325.     } while (--x>=0);
  326. }
  327.  
  328.  
  329. #ifdef __STDC__
  330. PRIVATE void cjumpfixdif(int row)
  331. #else
  332. PRIVATE void cjumpfixdif(row)
  333. int row;
  334. #endif
  335. {
  336.     u_short *pp;
  337.     u_long  *cp;
  338.     short x;
  339.     short prevcolor, color;
  340.     short r, g, b;
  341.  
  342.     pp=rgb[row];
  343.     cp=counts;
  344.     prevcolor= *pp++;
  345.     r=prevcolor>>8;
  346.     g=(prevcolor>>4)&0x0f;
  347.     b=prevcolor&0x0f;
  348.     if (r>g) {
  349.         if (b>r)
  350.             cp[prevcolor]+=r+g;
  351.         else
  352.             cp[prevcolor]+=b+g;
  353.     } else {
  354.         if (b>g)
  355.             cp[prevcolor]+=r+g;
  356.         else
  357.             cp[prevcolor]+=r+b;
  358.     }
  359.     x=xsz-2;
  360.     do {
  361.         color= *pp++;
  362.         r=color^prevcolor;
  363.         if (!( (r&0xf0f)==0 || (r&0xff0)==0 || (r&0x0ff)==0 )) {
  364.             r=(color-prevcolor)>>8;
  365.             if (r<0) r= -r;
  366.             g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
  367.             if (g<0) g= -g;
  368.             b=(color&0x000f)-(prevcolor&0x000f);
  369.             if (b<0) b= -b;
  370.             if (r>g) {
  371.                 if (b>r)
  372.                     cp[color]+=r+g;
  373.                 else
  374.                     cp[color]+=b+g;
  375.             } else {
  376.                 if (b>g)
  377.                     cp[color]+=r+g;
  378.                 else
  379.                     cp[color]+=r+b;
  380.             }
  381.         }
  382.         prevcolor=color;
  383.     } while (--x>=0);
  384. }
  385.  
  386.  
  387. #ifdef __STDC__
  388. PRIVATE void cjumpfixdifsh(int row)
  389. #else
  390. PRIVATE void cjumpfixdifsh(row)
  391. int row;
  392. #endif
  393. {
  394.     u_short *pp;
  395.     u_long  *cp;
  396.     short x;
  397.     short prevcolor, color;
  398.     short r, g, b;
  399.     long add;
  400.  
  401.     pp=rgb[row];
  402.     cp=counts;
  403.     prevcolor=0;
  404.     color= *pp;
  405.     r=color>>8;
  406.     g=(color>>4)&0x0f;
  407.     b=color&0x0f;
  408.     if (r>g) {
  409.         if (b>r)
  410.             add=r+g;
  411.         else
  412.             add=b+g;
  413.     } else {
  414.         if (b>g)
  415.             add=r+g;
  416.         else
  417.             add=r+b;
  418.     }
  419.     x=xsz-1;
  420.     do {
  421.         color= *pp++;
  422.         r=color^prevcolor;
  423.         if (!( (r&0xf0f)==0 || (r&0xff0)==0 || (r&0x0ff)==0 )) {
  424.             r=(color-prevcolor)>>8;
  425.             if (r<0) r= -r;
  426.             g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
  427.             if (g<0) g= -g;
  428.             b=(color&0x000f)-(prevcolor&0x000f);
  429.             if (b<0) b= -b;
  430.             if (r>g) {
  431.                 if (b>r)
  432.                     add=r+g;
  433.                 else
  434.                     add=b+g;
  435.             } else {
  436.                 if (b>g)
  437.                     add=r+g;
  438.                 else
  439.                     add=r+b;
  440.             }
  441.         }
  442.         cp[color]+=add;
  443.         add>>=1;
  444.         prevcolor=color;
  445.     } while (--x>=0);
  446. }
  447.  
  448.  
  449. #ifdef __STDC__
  450. PRIVATE void chammap(int row)
  451. #else
  452. PRIVATE void chammap(row)
  453. int row;
  454. #endif
  455. {
  456.     u_short *pp;
  457.     u_long *cp;
  458.     short x;
  459.     long curcolor;
  460.     long r, g, b, pr, pg, pb, d1, d2, d3;
  461.  
  462.     pp=rgb[row];
  463.     cp=counts;
  464.     x=xsz-1;
  465.     pb=curcm[0];
  466.     pr=pb>>8;
  467.     pg=(pb>>4)&0xf;
  468.     pb&=0xf;
  469.     do {
  470.         curcolor= *pp++;
  471.         b=curcolor;
  472.         r=b>>8;
  473.         g=(b>>4)&0xf;
  474.         b&=0xf;
  475.         if (r==pr) {
  476.             if (g==pg) {        /* r ok, g ok */
  477.                 pb=b;
  478.             } else {
  479.                 if (b==pb) {    /* r ok, g wrong, b ok */
  480.                     pg=g;
  481.                 } else {    /* r ok, g wrong, b wrong */
  482.                     if ((d1=g-pg)<0) d1= -d1;
  483.                     if ((d2=b-pb)<0) d2= -d2;
  484.                     if (error[curcolor]<(d1<d2 ? d1 : d2)) {
  485.                         cp[curcolor]+=error[curcolor];
  486.                         curcolor=newcol[curcolor];
  487.                         pb=curcm[curcolor];
  488.                         pr=pb>>8;
  489.                         pg=(pb>>4)&0xf;
  490.                         pb&=0xf;
  491.                     } else if (d1>=d2) {
  492.                         cp[curcolor]+=d2;
  493.                         pg=g;
  494.                     } else {
  495.                         cp[curcolor]+=d1;
  496.                         pb=b;
  497.                     }
  498.                 }
  499.             }
  500.         } else {
  501.             if (g==pg) {
  502.                 if (b==pb) {    /* r wrong, g ok, b ok */
  503.                     pr=r;
  504.                 } else {    /* r wrong, g ok, b wrong */
  505.                     if ((d1=r-pr)<0) d1= -d1;
  506.                     if ((d2=b-pb)<0) d2= -d2;
  507.                     if (error[curcolor]<(d1<d2 ? d1 : d2)) {
  508.                         cp[curcolor]+=error[curcolor];
  509.                         curcolor=newcol[curcolor];
  510.                         pb=curcm[curcolor];
  511.                         pr=pb>>8;
  512.                         pg=(pb>>4)&0xf;
  513.                         pb&=0xf;
  514.                     } else if (d1>=d2) {
  515.                         cp[curcolor]+=d2;
  516.                         pr=r;
  517.                     } else {
  518.                         cp[curcolor]+=d1;
  519.                         pb=b;
  520.                     }
  521.                 }
  522.             } else {
  523.                 if (b==pb) {    /* r wrong, g wrong, b ok */
  524.                     if ((d1=r-pr)<0) d1= -d1;
  525.                     if ((d2=g-pg)<0) d2= -d2;
  526.                     if (error[curcolor]<(d1<d2 ? d1 : d2)) {
  527.                         cp[curcolor]+=error[curcolor];
  528.                         curcolor=newcol[curcolor];
  529.                         pb=curcm[curcolor];
  530.                         pr=pb>>8;
  531.                         pg=(pb>>4)&0xf;
  532.                         pb&=0xf;
  533.                     } else if (d1>d2) {
  534.                         cp[curcolor]+=d2;
  535.                         pr=r;
  536.                     } else {
  537.                         cp[curcolor]+=d1;
  538.                         pg=g;
  539.                     }
  540.                 } else {    /* r wrong, g wrong, b wrong */
  541.                     if ((d1=r-pr)<0) d1= -d1;
  542.                     if ((d2=g-pg)<0) d2= -d2;
  543.                     if ((d3=b-pb)<0) d3= -d3;
  544.                     if (error[curcolor]<(d1>d2 ? (d1>d3 ? d2+d3 : d1+d2) : (d2>d3 ? d1+d3 : d1+d2))) {
  545.                         cp[curcolor]+=error[curcolor];
  546.                         curcolor=newcol[curcolor];
  547.                         pb=curcm[curcolor];
  548.                         pr=pb>>8;
  549.                         pg=(pb>>4)&0xf;
  550.                         pb&=0xf;
  551.                     } else if (d1>d2 && d1>=d3) {
  552.                         cp[curcolor]+=d2+d3;
  553.                         pr=r;
  554.                     } else if (d2>=d3) {
  555.                         cp[curcolor]+=d1+d3;
  556.                         pg=g;
  557.                     } else {
  558.                         cp[curcolor]+=d1+d2;
  559.                         pb=b;
  560.                     }
  561.                 }
  562.             }
  563.         }
  564.     } while (--x>=0);
  565. }
  566.  
  567.  
  568. #ifdef __STDC__
  569. PRIVATE void fill_curcm(short meth)
  570. #else
  571. PRIVATE void fill_curcm(meth)
  572. short meth;
  573. #endif
  574. {
  575.     int i;
  576.     short c=0;
  577.     static short cubic[]={
  578.         0x222, 0xe22, 0x2e2, 0x22e,
  579.         0x666, 0xa66, 0x6a6, 0x66a,
  580.         0x6aa, 0xa6a, 0xaa6, 0xaaa,
  581.         0x2ee, 0xe2e, 0xee2, 0xeee
  582.     };
  583.  
  584.     for (i=0; i<16; ++i) {
  585.         switch (meth) {
  586.         case COUNTMETH_HAMMAP_GS:
  587.             curcm[i]=c;
  588.             c+=0x111;
  589.         break;
  590.         case COUNTMETH_HAMMAP_CUBIC:
  591.             curcm[i]=cubic[i];
  592.         break;
  593.         }
  594.     }
  595. }
  596.  
  597.  
  598. #ifdef __STDC__
  599. int count_colors(u_long thr)
  600. #else
  601. int count_colors(thr)
  602. u_long thr;
  603. #endif
  604. {
  605.     short i;
  606.     long n;
  607.     u_long *p, th;
  608.  
  609.     assert((p=counts)!=NULL1);
  610.     i=NRGB/8-1; th=thr;
  611.     if (th==0)
  612.         n=NRGB;
  613.     else if (th==1) {
  614.     n=0;
  615.         do {
  616.             if (*p++) ++n; if (*p++) ++n; if (*p++) ++n; if (*p++) ++n;
  617.             if (*p++) ++n; if (*p++) ++n; if (*p++) ++n; if (*p++) ++n;
  618.         } while (--i>=0);
  619.     } else {
  620.     n=0;
  621.         do {
  622.             if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n;
  623.             if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n;
  624.         } while (--i>=0);
  625.     }
  626.     return (int)n;
  627. }
  628.  
  629.  
  630. #ifdef __STDC__
  631. count_pixels(int firstrow, int lastrow, int moverride)
  632. #else
  633. count_pixels(firstrow, lastrow, moverride)
  634. int firstrow, lastrow, moverride;
  635. #endif
  636. {
  637.     static int sfirstrow= -1, slastrow= -1;
  638.     short meth; static short smeth= -1;
  639.     int row;
  640. #ifdef __STDC__
  641.     void (*countfunc)(int);
  642. #else
  643.     void (*countfunc)();
  644. #endif
  645.  
  646.     if (counts==NULL1)
  647.         counts=Malloc(NRGB*sizeof(u_long));
  648.     meth=countmeth;
  649.     if (moverride)
  650.         meth=COUNTMETH_ALL_1;
  651.     if (!inoperation && firstrow==sfirstrow && lastrow==slastrow && meth==smeth)
  652.         return;
  653.     sfirstrow=firstrow; slastrow=lastrow; smeth=meth;
  654.     switch (meth) {
  655.     case COUNTMETH_ALL_1        : countfunc=call1;         break;
  656.     case COUNTMETH_ALL_DIF      : countfunc=calldif;       break;
  657.     case COUNTMETH_ALL_FIXDIF   : countfunc=callfixdif;    break;
  658.     case COUNTMETH_JUMP_1       : countfunc=cjump1;        break;
  659.     case COUNTMETH_JUMP_21      : countfunc=cjump21;       break;
  660.     case COUNTMETH_JUMP_DIF     : countfunc=cjumpdif;      break;
  661.     case COUNTMETH_JUMP_DIFSH   : countfunc=cjumpdifsh;    break;
  662.     case COUNTMETH_JUMP_FIXDIF  : countfunc=cjumpfixdif;   break;
  663.     case COUNTMETH_JUMP_FIXDIFSH: countfunc=cjumpfixdifsh; break;
  664.     case COUNTMETH_HAMMAP_GS:
  665.     case COUNTMETH_HAMMAP_CUBIC:
  666.     if (xmode!=HAM)
  667.         error0(E0_FATAL, E1_IFF, E2_OPTION, E3_ITMETH);
  668.     count_pixels(firstrow, lastrow, 1);
  669.     fill_curcm(meth);
  670.     fill_newcol_count();
  671.     countfunc=chammap;
  672.     break;
  673.     default:
  674.     error0(E0_FATAL, E1_IFF, E2_OPTION, E3_COUNTMETH);
  675.     break;
  676.     }
  677.     clear_counts();
  678.     for (row=firstrow; row<=lastrow; ++row) {
  679.         countfunc(row);
  680.     }
  681. }
  682.