home *** CD-ROM | disk | FTP | other *** search
- /* wasp - Copyright 1991 by Steven Reiz
- * see COPYING and wasp.c for further info
- * wriffcount.c, 4/12/90 - 29/12/90,
- * 2/6/91, 23/6/91, 1/7/91 - 10/7/91, 8/12/91
- */
-
- static char *sourcefile=__FILE__;
-
- #include "wasp.h"
- #include "wriff.h"
-
- static u_char *xor_tab=NULL;
-
-
- #ifndef AZTEC_C
- /* this function has been rewritten in assembler for the Aztec C
- * assembler, see wriffasm.c
- */
-
- void
- clear_counts(void)
- {
- short i;
- u_long *p;
- long r0, r1, r2, r3, r4, r5, r6, r7;
-
- p=counts; i=NRGB/16-1;
- r0=0; r1=r0; r2=r0; r3=r0;
- r4=r0; r5=r0; r6=r0; r7=r0;
- do {
- *p++ =r0; *p++ =r1; *p++ =r2; *p++ =r3;
- *p++ =r4; *p++ =r5; *p++ =r6; *p++ =r7;
- *p++ =r0; *p++ =r1; *p++ =r2; *p++ =r3;
- *p++ =r4; *p++ =r5; *p++ =r6; *p++ =r7;
- } while (--i>=0);
- }
- #endif /* AZTEC_C */
-
-
- void
- fill_xor_tab(void)
- {
- short i;
- u_char *tab;
-
- xor_tab=Malloc(NRGB);
- tab=xor_tab+NRGB;
- i=NRGB-1;
- do {
- if ((i&0xf0f)==0 || (i&0xff0)==0 || (i&0x0ff)==0)
- *--tab=0;
- else
- *--tab=1;
- } while (--i>=0);
- }
-
-
- void
- call1(int row)
- {
- u_short *pp;
- u_long *cp;
- short x;
-
- pp=rgb[row];
- cp=counts;
- x=xsz-1;
- do {
- ++cp[*pp++];
- } while (--x>=0);
- }
-
-
- void
- calldif(int row)
- {
- u_short *pp;
- u_long *cp;
- short x;
- short prevcolor, color;
- short d, t;
-
- pp=rgb[row];
- cp=counts;
- x=xsz-1;
- prevcolor=0;
- do {
- color= *pp++;
- t=(color-prevcolor)>>8;
- if (t<0) d= -t; else d=t;
- t=((color&0x00f0)-(prevcolor&0x00f0))>>4;
- if (t<0) d-=t; else d+=t;
- t=(color&0x000f)-(prevcolor&0x000f);
- if (t<0) d-=t; else d+=t;
- cp[color]+=d;
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- callfixdif(int row)
- {
- u_short *pp;
- u_long *cp;
- short x;
- short prevcolor, color;
- short r, g, b;
-
- pp=rgb[row];
- cp=counts;
- x=xsz-1;
- prevcolor=0;
- do {
- color= *pp++;
- r=(color-prevcolor)>>8;
- if (r<0) r= -r;
- g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
- if (g<0) g= -g;
- b=(color&0x000f)-(prevcolor&0x000f);
- if (b<0) b= -b;
- if (r>g) {
- if (b>r)
- cp[color]+=r+g;
- else
- cp[color]+=b+g;
- } else {
- if (b>g)
- cp[color]+=r+g;
- else
- cp[color]+=r+b;
- }
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- cjump1(int row)
- {
- u_short *pp;
- u_long *cp;
- u_char *tab;
- short x;
- long prevcolor, color;
-
- if (!xor_tab)
- fill_xor_tab();
- tab=xor_tab;
- pp=rgb[row];
- cp=counts;
- prevcolor= *pp++;
- ++cp[prevcolor];
- x=xsz-2;
- do {
- color= *pp++;
- if (tab[color^prevcolor])
- ++cp[color];
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- cjump21(int row)
- {
- u_short *pp;
- u_long *cp;
- u_char *tab;
- short x;
- long prevcolor, color, add;
-
- if (!xor_tab)
- fill_xor_tab();
- tab=xor_tab;
- pp=rgb[row];
- cp=counts;
- add=1;
- prevcolor= *pp++;
- cp[prevcolor]+=2;
- x=xsz-2;
- do {
- color= *pp++;
- if (tab[color^prevcolor])
- add=2;
- cp[color]+=add;
- add>>=1;
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- cjumpdif(int row)
- {
- u_short *pp;
- u_long *cp;
- u_char *tab;
- short x;
- long prevcolor, color, d, t;
-
- if (!xor_tab)
- fill_xor_tab();
- tab=xor_tab;
- pp=rgb[row];
- cp=counts;
- prevcolor= *pp++;
- cp[prevcolor]+=12;
- x=xsz-2;
- do {
- color= *pp++;
- if (tab[color^prevcolor]) {
- if ((d=(color-prevcolor)>>8)<0)
- d= -d;
- if ((t=((color&0x00f0)-(prevcolor&0x00f0))>>4)<0)
- d-=t;
- else
- d+=t;
- if ((t=(color&0x000f)-(prevcolor&0x000f))<0)
- d-=t;
- else
- d+=t;
- cp[color]+=d;
- }
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- cjumpdifsh(int row)
- {
- u_short *pp;
- u_long *cp;
- short x;
- short prevcolor, color;
- short d, t;
- long add;
-
- pp=rgb[row];
- cp=counts;
- color= *pp;
- add=(color>>8)+((color>>4)&0x0f)+(color&0x0f);
- prevcolor=0;
- x=xsz-1;
- do {
- color= *pp++;
- t=color^prevcolor;
- if (!( (t&0xf0f)==0 || (t&0xff0)==0 || (t&0x0ff)==0 )) {
- t=(color-prevcolor)>>8;
- if (t<0) d= -t; else d=t;
- t=((color&0x00f0)-(prevcolor&0x00f0))>>4;
- if (t<0) d-=t; else d+=t;
- t=(color&0x000f)-(prevcolor&0x000f);
- if (t<0) d-=t; else d+=t;
- if (add<d)
- add=d;
- }
- cp[color]+=add;
- add>>=1;
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- cjumpfixdif(int row)
- {
- u_short *pp;
- u_long *cp;
- short x;
- short prevcolor, color;
- short r, g, b;
-
- pp=rgb[row];
- cp=counts;
- prevcolor= *pp++;
- r=prevcolor>>8;
- g=(prevcolor>>4)&0x0f;
- b=prevcolor&0x0f;
- if (r>g) {
- if (b>r)
- cp[prevcolor]+=r+g;
- else
- cp[prevcolor]+=b+g;
- } else {
- if (b>g)
- cp[prevcolor]+=r+g;
- else
- cp[prevcolor]+=r+b;
- }
- x=xsz-2;
- do {
- color= *pp++;
- r=color^prevcolor;
- if (!( (r&0xf0f)==0 || (r&0xff0)==0 || (r&0x0ff)==0 )) {
- r=(color-prevcolor)>>8;
- if (r<0) r= -r;
- g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
- if (g<0) g= -g;
- b=(color&0x000f)-(prevcolor&0x000f);
- if (b<0) b= -b;
- if (r>g) {
- if (b>r)
- cp[color]+=r+g;
- else
- cp[color]+=b+g;
- } else {
- if (b>g)
- cp[color]+=r+g;
- else
- cp[color]+=r+b;
- }
- }
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- cjumpfixdifsh(int row)
- {
- u_short *pp;
- u_long *cp;
- short x;
- short prevcolor, color;
- short r, g, b;
- long add;
-
- pp=rgb[row];
- cp=counts;
- prevcolor=0;
- color= *pp;
- r=color>>8;
- g=(color>>4)&0x0f;
- b=color&0x0f;
- if (r>g) {
- if (b>r)
- add=r+g;
- else
- add=b+g;
- } else {
- if (b>g)
- add=r+g;
- else
- add=r+b;
- }
- x=xsz-1;
- do {
- color= *pp++;
- r=color^prevcolor;
- if (!( (r&0xf0f)==0 || (r&0xff0)==0 || (r&0x0ff)==0 )) {
- r=(color-prevcolor)>>8;
- if (r<0) r= -r;
- g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
- if (g<0) g= -g;
- b=(color&0x000f)-(prevcolor&0x000f);
- if (b<0) b= -b;
- if (r>g) {
- if (b>r)
- add=r+g;
- else
- add=b+g;
- } else {
- if (b>g)
- add=r+g;
- else
- add=r+b;
- }
- }
- cp[color]+=add;
- add>>=1;
- prevcolor=color;
- } while (--x>=0);
- }
-
-
- void
- chammap(int row)
- {
- u_short *pp;
- u_long *cp;
- short x;
- long curcolor;
- long r, g, b, pr, pg, pb, d1, d2, d3;
-
- pp=rgb[row];
- cp=counts;
- x=xsz-1;
- pb=curcm[0];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- do {
- curcolor= *pp++;
- b=curcolor;
- r=b>>8;
- g=(b>>4)&0xf;
- b&=0xf;
- if (r==pr) {
- if (g==pg) { /* r ok, g ok */
- pb=b;
- } else {
- if (b==pb) { /* r ok, g wrong, b ok */
- pg=g;
- } else { /* r ok, g wrong, b wrong */
- if ((d1=g-pg)<0) d1= -d1;
- if ((d2=b-pb)<0) d2= -d2;
- if (error[curcolor]<(d1<d2 ? d1 : d2)) {
- cp[curcolor]+=error[curcolor];
- curcolor=newcol[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>=d2) {
- cp[curcolor]+=d2;
- pg=g;
- } else {
- cp[curcolor]+=d1;
- pb=b;
- }
- }
- }
- } else {
- if (g==pg) {
- if (b==pb) { /* r wrong, g ok, b ok */
- pr=r;
- } else { /* r wrong, g ok, b wrong */
- if ((d1=r-pr)<0) d1= -d1;
- if ((d2=b-pb)<0) d2= -d2;
- if (error[curcolor]<(d1<d2 ? d1 : d2)) {
- cp[curcolor]+=error[curcolor];
- curcolor=newcol[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>=d2) {
- cp[curcolor]+=d2;
- pr=r;
- } else {
- cp[curcolor]+=d1;
- pb=b;
- }
- }
- } else {
- if (b==pb) { /* r wrong, g wrong, b ok */
- if ((d1=r-pr)<0) d1= -d1;
- if ((d2=g-pg)<0) d2= -d2;
- if (error[curcolor]<(d1<d2 ? d1 : d2)) {
- cp[curcolor]+=error[curcolor];
- curcolor=newcol[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>d2) {
- cp[curcolor]+=d2;
- pr=r;
- } else {
- cp[curcolor]+=d1;
- pg=g;
- }
- } else { /* r wrong, g wrong, b wrong */
- if ((d1=r-pr)<0) d1= -d1;
- if ((d2=g-pg)<0) d2= -d2;
- if ((d3=b-pb)<0) d3= -d3;
- if (error[curcolor]<(d1>d2 ? (d1>d3 ? d2+d3 : d1+d2) : (d2>d3 ? d1+d3 : d1+d2))) {
- cp[curcolor]+=error[curcolor];
- curcolor=newcol[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>d2 && d1>=d3) {
- cp[curcolor]+=d2+d3;
- pr=r;
- } else if (d2>=d3) {
- cp[curcolor]+=d1+d3;
- pg=g;
- } else {
- cp[curcolor]+=d1+d2;
- pb=b;
- }
- }
- }
- }
- } while (--x>=0);
- }
-
-
- void
- fill_curcm(short meth)
- {
- int i;
- short c=0;
- static short cubic[]={
- 0x222, 0xe22, 0x2e2, 0x22e,
- 0x666, 0xa66, 0x6a6, 0x66a,
- 0x6aa, 0xa6a, 0xaa6, 0xaaa,
- 0x2ee, 0xe2e, 0xee2, 0xeee
- };
-
- for (i=0; i<16; ++i) {
- switch (meth) {
- case COUNTMETH_HAMMAP_GS:
- curcm[i]=c;
- c+=0x111;
- break;
- case COUNTMETH_HAMMAP_CUBIC:
- curcm[i]=cubic[i];
- break;
- }
- }
- }
-
-
- int
- count_colors(unsigned long thr)
- {
- short i;
- long n;
- u_long *p, th;
-
- assert((p=counts)!=NULL1);
- i=NRGB/8-1; th=thr;
- if (th==0)
- n=NRGB;
- else if (th==1) {
- n=0;
- do {
- if (*p++) ++n; if (*p++) ++n; if (*p++) ++n; if (*p++) ++n;
- if (*p++) ++n; if (*p++) ++n; if (*p++) ++n; if (*p++) ++n;
- } while (--i>=0);
- } else {
- n=0;
- do {
- if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n;
- if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n;
- } while (--i>=0);
- }
- return (int)n;
- }
-
-
- void
- count_pixels(int firstrow, int lastrow, int moverride)
- {
- static int sfirstrow= -1, slastrow= -1;
- short meth; static short smeth= -1;
- int row;
- void (*countfunc)(int);
-
- if (counts==NULL1)
- counts=Malloc(NRGB*sizeof(u_long));
- meth=countmeth;
- if (moverride)
- meth=COUNTMETH_ALL_1;
- if (!inoperation && firstrow==sfirstrow && lastrow==slastrow && meth==smeth)
- return;
- sfirstrow=firstrow; slastrow=lastrow; smeth=meth;
- switch (meth) {
- case COUNTMETH_ALL_1 : countfunc=call1; break;
- case COUNTMETH_ALL_DIF : countfunc=calldif; break;
- case COUNTMETH_ALL_FIXDIF : countfunc=callfixdif; break;
- case COUNTMETH_JUMP_1 : countfunc=cjump1; break;
- case COUNTMETH_JUMP_21 : countfunc=cjump21; break;
- case COUNTMETH_JUMP_DIF : countfunc=cjumpdif; break;
- case COUNTMETH_JUMP_DIFSH : countfunc=cjumpdifsh; break;
- case COUNTMETH_JUMP_FIXDIF : countfunc=cjumpfixdif; break;
- case COUNTMETH_JUMP_FIXDIFSH: countfunc=cjumpfixdifsh; break;
- case COUNTMETH_HAMMAP_GS:
- case COUNTMETH_HAMMAP_CUBIC:
- if (xmode!=HAM)
- error0(E0_FATAL, E1_IFF, E2_OPTION, E3_ITMETH);
- count_pixels(firstrow, lastrow, 1);
- fill_curcm(meth);
- fill_newcol_count();
- countfunc=chammap;
- break;
- default:
- error0(E0_FATAL, E1_IFF, E2_OPTION, E3_COUNTMETH);
- break;
- }
- clear_counts();
- for (row=firstrow; row<=lastrow; ++row) {
- countfunc(row);
- }
- }
-