home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
580b.lha
/
Wasp_v1.23
/
src.LZH
/
src
/
wriffcount.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-15
|
14KB
|
682 lines
/* wasp - copyright Steven Reiz 1990, 1991
* see 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
*/
#include "wasp.h"
#include "wriff.h"
#ifndef NOSH
#include "wriffcount.sh"
#endif
static u_char *xor_tab=NULL;
#ifdef AZTEC_C
extern clear_counts(void);
#asm
xdef _clear_counts
_clear_counts:
movem.l d2-d7/a2-a6,-(sp)
move.l _counts,a6
add.l #$4000,a6
move.w #63,d7
move.l #0,d0
move.l d0,d1
move.l d0,d2
move.l d0,d3
move.l d0,d4
move.l d0,d5
move.l d0,d6
move.l d0,a0
move.l d0,a1
move.l d0,a2
move.l d0,a3
move.l d0,a4
move.l d0,a5
clear_counts_2:
movem.l d0-d6/a0-a5,-(a6)
movem.l d0-d6/a0-a5,-(a6)
movem.l d0-d6/a0-a5,-(a6)
movem.l d0-d6/a0-a5,-(a6)
movem.l d0-d6/a0-a4,-(a6)
dbf.w d7,clear_counts_2
movem.l (sp)+,d2-d7/a2-a6
rts
#endasm
#else /* !AZTEC_C */
#ifdef __STDC__
PRIVATE clear_counts(void)
#else
PRIVATE clear_counts()
#endif
{
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 */
#ifdef __STDC__
PRIVATE fill_xor_tab(void)
#else
PRIVATE fill_xor_tab()
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void call1(int row)
#else
PRIVATE void call1(row)
int row;
#endif
{
u_short *pp;
u_long *cp;
short x;
pp=rgb[row];
cp=counts;
x=xsz-1;
do {
++cp[*pp++];
} while (--x>=0);
}
#ifdef __STDC__
PRIVATE void calldif(int row)
#else
PRIVATE void calldif(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void callfixdif(int row)
#else
PRIVATE void callfixdif(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void cjump1(int row)
#else
PRIVATE void cjump1(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void cjump21(int row)
#else
PRIVATE void cjump21(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void cjumpdif(int row)
#else
PRIVATE void cjumpdif(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void cjumpdifsh(int row)
#else
PRIVATE void cjumpdifsh(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void cjumpfixdif(int row)
#else
PRIVATE void cjumpfixdif(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void cjumpfixdifsh(int row)
#else
PRIVATE void cjumpfixdifsh(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void chammap(int row)
#else
PRIVATE void chammap(row)
int row;
#endif
{
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);
}
#ifdef __STDC__
PRIVATE void fill_curcm(short meth)
#else
PRIVATE void fill_curcm(meth)
short meth;
#endif
{
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;
}
}
}
#ifdef __STDC__
int count_colors(u_long thr)
#else
int count_colors(thr)
u_long thr;
#endif
{
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;
}
#ifdef __STDC__
count_pixels(int firstrow, int lastrow, int moverride)
#else
count_pixels(firstrow, lastrow, moverride)
int firstrow, lastrow, moverride;
#endif
{
static int sfirstrow= -1, slastrow= -1;
short meth; static short smeth= -1;
int row;
#ifdef __STDC__
void (*countfunc)(int);
#else
void (*countfunc)();
#endif
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);
}
}