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

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