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
/
wriffdistr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-19
|
25KB
|
1,226 lines
/* wasp - copyright Steven Reiz 1990, 1991
* see wasp.c for further info
* wriffdistr.c, 4/12/90 - 30/1/91, 2/6/91, 23/6/91,
* 3/7/91 - 10/7/91
* symbols: SORT_SLICED, SHAM_BLACK
*/
struct hs_t {
char dist;
char pad;
short color;
};
#include "wasp.h"
#include "wriff.h"
#ifndef NOSH
#include "wriffdistr.sh"
#endif
#define SORT_SLICED
/* #define SHAM_BLACK */
static char regind;
static long squares[]={
0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225
};
#ifdef __STDC__
compute_distr(int firstrow, int lastrow)
#else
compute_distr(firstrow, lastrow)
int firstrow, lastrow;
#endif
{
assert(counts!=NULL1);
if (icolors<=nregs)
no_distr();
else {
switch (distrmeth) {
case DISTRMETH_MOSTUSED:
mostused_distr();
break;
case DISTRMETH_WORSTFIRST:
worstfirst_distr();
break;
case DISTRMETH_EHB:
ehb_distr();
break;
case DISTRMETH_MUE:
mue_distr();
break;
case DISTRMETH_HAMSHARP:
hamsharp_distr();
break;
case DISTRMETH_CONTRACTION:
contraction_distr();
break;
default:
error0(E0_FATAL, E1_IFF, E2_OPTION, E3_DISTRMETH);
break;
}
}
if (xmode!=EHB) {
#ifdef SORT_SLICED
sort_cm();
#else
if (!slicedo)
sort_cm();
#endif
}
count_pixels(firstrow, lastrow, 1);
fill_newcol();
}
#ifdef __STDC__
PRIVATE no_distr(void)
#else
PRIVATE no_distr()
#endif
{
short i;
u_long th, *p;
u_short *q;
p=counts+NRGB;
th=threshold;
q=curcm;
i=NRGB-1;
if (th<=1) {
do {
if (*--p)
*q++ =i;
} while (--i>=0);
} else {
do {
if (*--p >=th)
*q++ =i;
} while (--i>=0);
}
assert(q==curcm+icolors);
while (q<curcm+nregs)
*q++ =0;
}
#ifdef __STDC__
PRIVATE mostused_distr(void)
#else
PRIVATE mostused_distr()
#endif
{
static u_long regcounts[MAXNREGS];
u_long *countp, *countp2, th;
static u_long *savecountp;
u_short *cmp;
short i;
countp=regcounts;
i=nregs-1;
do {
*countp++ =0;
} while (--i>=0);
th=0;
countp=counts+NRGB;
i=NRGB-1;
do {
if (*--countp>th) {
th= *countp;
savecountp=countp;
countp=regcounts;
do {
/* tight loop! */
} while (*countp++ >=th);
countp2=regcounts+nregs;
cmp=curcm+nregs;
if (countp2>countp) {
do {
*--countp2= *(countp2-2);
*--cmp = *(cmp-2);
} while (countp2>countp);
}
*--countp2=th;
*--cmp=i;
th=regcounts[nregs-1];
countp=savecountp;
}
} while (--i>=0);
#ifdef SHAM_BLACK
if (slicedo) {
for (i=0; i<nregs; ++i)
if (curcm[i]==0x000)
break;
if (i>=nregs) { /* black isn't amongst the colors, add it */
curcm[nregs-1]=0x000;
}
}
#endif
}
#ifdef __STDC__
PRIVATE worstfirst_distr(void)
#else
PRIVATE worstfirst_distr()
#endif
{
static int sicolors= -1;
static int startreg;
int i;
short rgb1, rgb2;
if (sicolors<icolors) {
if (sicolors== -1) {
if (icolors<128)
sicolors=128;
else
sicolors=icolors;
} else {
free(wfmindist);
free(wfminind);
free(wfrgb);
if (icolors<256)
sicolors=256;
else
sicolors=icolors;
}
wfmindist=Malloc(sicolors);
wfminind=Malloc(sicolors);
wfrgb=Malloc(sicolors*3);
}
fill_wf_rgb();
startreg=2;
#ifdef SHAM_BLACK
if (slicedo) {
startreg=1;
rgb1=0x000; regind=0;
fill_wf_dist_1(rgb1);
} else {
#endif
find_2_furthest(&rgb1, &rgb2);
curcm[0]=rgb1; regind=0;
fill_wf_dist_1(rgb1);
curcm[1]=rgb2; regind=1;
fill_wf_dist_2(rgb2);
#ifdef SHAM_BLACK
}
#endif
for (i=startreg; i<nregs; ++i) {
find_1_furthest(&rgb1);
curcm[i]=rgb1; regind=i;
fill_wf_dist_2(rgb1);
}
fill_wf2rgbweight();
wf2_redo_curcm();
}
#ifdef __STDC__
PRIVATE fill_wf_rgb(void)
#else
PRIVATE fill_wf_rgb()
#endif
{
long i;
u_long th, *p;
char *q;
p=counts+NRGB;
th=threshold;
q=wfrgb;
i=NRGB-1;
if (th<=1) {
do {
if (*--p) {
*q++ =i>>8;
*q++ =(i>>4)&0x0f;
*q++ =i&0x0f;
}
} while (--i>=0);
} else {
do {
if (*--p >=th) {
*q++ =i>>8;
*q++ =(i>>4)&0x0f;
*q++ =i&0x0f;
}
} while (--i>=0);
}
assert(q==wfrgb+3*icolors);
}
#ifdef __STDC__
PRIVATE find_2_furthest(short *rgb1p, short *rgb2p)
#else
PRIVATE find_2_furthest(rgb1p, rgb2p)
short *rgb1p, *rgb2p;
#endif
{
REG char *p, *q;
REG char r, g, b, t, dist, bigdist;
NON_REG char *bigp, *bigq;
bigdist=0;
p=wfrgb+3*icolors;
while (p>wfrgb) {
b= *--p;
g= *--p;
r= *--p;
q=wfrgb;
do {
if ((dist=r- *q++)<0) dist= -dist;
if ((t=g- *q++)<0) dist-=t; else dist+=t;
if ((t=b- *q++)<0) dist-=t; else dist+=t;
if (dist>bigdist) {
bigdist=dist;
bigp=p;
bigq=q;
}
} while (q<p);
}
*rgb1p=(*bigp<<8) |(*(bigp+1)<<4)|(*(bigp+2));
*rgb2p=(*(bigq-3)<<8)|(*(bigq-2)<<4)|(*(bigq-1));
}
#ifdef __STDC__
PRIVATE fill_wf_dist_1(short color)
#else
PRIVATE fill_wf_dist_1(color)
short color;
#endif
{
short i;
char r, g, b, t, dist;
char *mdp, *mip, *rgbp;
r=color>>8;
g=(color>>4)&0x0f;
b=color&0x0f;
mdp=wfmindist+icolors;
mip=wfminind+icolors;
rgbp=wfrgb+3*icolors;
i=icolors-1;
do {
if ((dist=b- *--rgbp)<0) dist= -dist;
if ((t=g- *--rgbp)<0) dist-=t; else dist+=t;
if ((t=r- *--rgbp)<0) dist-=t; else dist+=t;
*--mdp=dist;
*--mip=regind;
} while (--i>=0);
}
#ifdef __STDC__
PRIVATE fill_wf_dist_2(short color)
#else
PRIVATE fill_wf_dist_2(color)
short color;
#endif
{
short i;
char r, g, b, t, dist;
char *mdp, *mip, *rgbp;
r=color>>8;
g=(color>>4)&0x0f;
b=color&0x0f;
mdp=wfmindist+icolors;
mip=wfminind+icolors;
rgbp=wfrgb+3*icolors;
i=icolors-1;
do {
if ((dist=b- *--rgbp)<0) dist= -dist;
if ((t=g- *--rgbp)<0) dist-=t; else dist+=t;
if ((t=r- *--rgbp)<0) dist-=t; else dist+=t;
if (dist< *--mdp) {
*mdp=dist;
*--mip=regind;
} else
--mip;
} while (--i>=0);
}
#ifdef __STDC__
PRIVATE find_1_furthest(short *rgbp)
#else
PRIVATE find_1_furthest(rgbp)
short *rgbp;
#endif
{
char *p, max;
short i, maxi;
p=wfmindist+icolors;
max=0;
i=icolors-1;
do {
if (*--p>max) {
max= *p;
maxi=i;
}
} while (--i>=0);
p=wfrgb+3*maxi;
*rgbp=(*p<<8)|(*(p+1)<<4)|(*(p+2));
}
#ifdef __STDC__
PRIVATE fill_wf2rgbweight(void)
#else
PRIVATE fill_wf2rgbweight()
#endif
{
char *rgbp, *mip;
u_long *weightp, weight;
short i;
char r, g, b;
if (wf2rgbweight==NULL1)
wf2rgbweight=Malloc(nregs*4*sizeof(u_long));
weightp=wf2rgbweight;
i=nregs-1;
do {
*weightp++ =0;
*weightp++ =0;
*weightp++ =0;
*weightp++ =0;
} while (--i>=0);
rgbp=wfrgb;
mip=wfminind;
i=icolors-1;
do {
r= *rgbp++;
g= *rgbp++;
b= *rgbp++;
weight=counts[(r<<8)|(g<<4)|b];
weightp=wf2rgbweight+4* (*mip++);
*weightp++ += r*weight;
*weightp++ += g*weight;
*weightp++ += b*weight;
*weightp += weight;
} while (--i>=0);
}
#ifdef __STDC__
PRIVATE wf2_redo_curcm(void)
#else
PRIVATE wf2_redo_curcm()
#endif
{
u_long *weightp, weight, r, g, b;
short i;
u_short *cmp;
weightp=wf2rgbweight;
cmp=curcm;
i=nregs-1;
do {
r= *weightp++;
g= *weightp++;
b= *weightp++;
weight= *weightp++;
if (!weight)
weight=1;
r=(r+weight/2)/weight;
if (r>15) r=15;
g=(g+weight/2)/weight;
if (g>15) g=15;
b=(b+weight/2)/weight;
if (b>15) b=15;
*cmp++ =(r<<8)|(g<<4)|b;
} while (--i>=0);
#ifdef SHAM_BLACK
if (slicedo)
black_darkest();
#endif
}
#ifdef __STDC__
PRIVATE black_darkest(void)
#else
PRIVATE black_darkest()
#endif
{
short i, besti, val, bestval;
bestval=100;
for (i=0; i<nregs; ++i) {
val=(curcm[i]&0xf)+((curcm[i]>>4)&0xf)+(curcm[i]>>8);
if (val<bestval) {
bestval=val;
besti=i;
}
}
curcm[besti]=0x000;
}
#ifdef __STDC__
PRIVATE ehb_distr(void)
#else
PRIVATE ehb_distr()
#endif
{
static int sicolors= -1;
int i, nr;
short rgb1, rgb2;
nr=nregs/2;
if (sicolors<icolors) {
if (sicolors== -1) {
if (icolors<128)
sicolors=128;
else
sicolors=icolors;
} else {
free(wfmindist);
free(wfminind);
free(wfrgb);
if (icolors<256)
sicolors=256;
else
sicolors=icolors;
}
wfmindist=Malloc(sicolors);
wfminind=Malloc(sicolors);
wfrgb=Malloc(sicolors*3);
}
fill_wf_rgb();
find_2_furthest(&rgb1, &rgb2);
regind=0;
fill_wf_dist_1(rgb1);
ehb_pair(rgb1, 0);
for (i=1; i<nr; ++i) {
find_1_furthest(&rgb1);
regind=i;
fill_wf_dist_2(rgb1);
ehb_pair(rgb1, i);
}
fill_wf2rgbweight();
ehb_redo_curcm();
}
#ifdef __STDC__
PRIVATE ehb_pair(short c1, int i)
#else
PRIVATE ehb_pair(c1, i)
short c1;
int i;
#endif
{
short c2, c3, c4;
short r, g, b;
int nr;
nr=nregs/2;
r=c1>>8;
g=(c1>>4)&0x0f;
b=c1&0x0f;
c2=((r>>1)<<8)|((g>>1)<<4)|(b>>1);
if (r<8 && g<8 && b<8) {
c3=(r<<9)|(g<<5)|(b<<1);
ehb_worst(c2, c3, &c4);
if (c4==c2) {
curcm[i]=c1;
curcm[nr+i]=c2;
regind=nr+i;
} else {
curcm[i]=c4;
curcm[nr+i]=c1;
c2=c4;
ehb_minind_adjust((int)i, (int)(nr+i));
regind=i;
}
} else {
curcm[i]=c1;
curcm[nr+i]=c2;
regind=nr+i;
}
fill_wf_dist_2(c2);
}
#ifdef __STDC__
PRIVATE ehb_worst(short col1, short col8, short *worstp)
#else
PRIVATE ehb_worst(col1, col8, worstp)
short col1, col8;
short *worstp;
#endif
{
short curcol;
int curdist, bestdist;
short i;
bestdist=ehb_farcol(col1);
*worstp=col1;
i=7;
do {
curcol=col8;
if (i&1)
curcol|=0x001;
if (i&2)
curcol|=0x010;
if (i&4)
curcol|=0x100;
curdist=ehb_farcol(curcol);
if (curdist>bestdist) {
bestdist=curdist;
*worstp=curcol;
}
} while (--i>=0);
}
#ifdef __STDC__
PRIVATE int ehb_farcol(short color)
#else
PRIVATE int ehb_farcol(color)
short color;
#endif
{
char r, g, b;
char *p, *q;
char t, dist, bigdist;
short i;
r=color>>8;
g=(color>>4)&0x0f;
b=color&0x0f;
bigdist=0;
i=icolors-1;
p=wfmindist;
q=wfrgb;
do {
if ((dist=r- *q++)>0) dist= -dist;
if ((t=g- *q++)>0) dist-=t; else dist+=t;
if ((t=b- *q++)>0) dist-=t; else dist+=t;
dist+= *p++;
if (dist>bigdist)
bigdist=dist;
} while (--i>=0);
return (int)bigdist;
}
#ifdef __STDC__
PRIVATE ehb_minind_adjust(int from, int to)
#else
PRIVATE ehb_minind_adjust(from, to)
int from, to;
#endif
{
char *p;
char fromc, toc;
short i;
p=wfminind+icolors;
i=icolors-1;
fromc=from;
toc=to;
do {
if (*--p ==fromc)
*p=toc;
} while (--i>=0);
}
#ifdef __STDC__
PRIVATE ehb_redo_curcm(void)
#else
PRIVATE ehb_redo_curcm()
#endif
{
short nr, i;
long r1, g1, b1, w1, r2, g2, b2, w2;
u_long *p1, *p2;
nr=nregs/2;
p1=wf2rgbweight;
p2=wf2rgbweight+4*nr;
for (i=0; i<nr; ++i) {
r1= *p1++; g1= *p1++; b1= *p1++; w1= *p1++;
r2=(*p2++)<<1; g2=(*p2++)<<1; b2=(*p2++)<<1; w2= *p2++;
w1=w1+w2;
assert(w1);
w2=w1/2;
r1=(r1+r2+w2)/w1;
if (r1>15) r1=15;
g1=(g1+g2+w2)/w1;
if (g1>15) g1=15;
b1=(b1+b2+w2)/w1;
if (b1>15) b1=15;
curcm[i]=(r1<<8)|(g1<<4)|b1;
r1>>=1; g1>>=1; b1>>=1;
curcm[nr+i]=(r1<<8)|(g1<<4)|b1;
}
}
#ifdef __STDC__
PRIVATE mue_distr(void)
#else
PRIVATE mue_distr()
#endif
{
static u_long regcounts[MAXNREGS];
u_long *countp, *countp2, th;
static u_long *savecountp;
u_short *cmp;
short i, nr;
nr=nregs/2;
countp=regcounts;
i=nr-1;
do {
*countp++ =0;
} while (--i>=0);
th=0;
countp=counts+NRGB;
i=NRGB-1;
do {
if (*--countp>th) {
th= *countp;
savecountp=countp;
countp=regcounts;
do {
/* tight loop! */
} while (*countp++ >=th);
countp2=regcounts+nr;
cmp=curcm+nr;
if (countp2>countp) {
do {
*--countp2= *(countp2-2);
*--cmp = *(cmp-2);
} while (countp2>countp);
}
*--countp2=th;
*--cmp=i;
th=regcounts[nr-1];
countp=savecountp;
}
} while (--i>=0);
mue_extend();
}
#ifdef __STDC__
PRIVATE mue_extend(void)
#else
PRIVATE mue_extend()
#endif
{
short i;
short r, g, b, color;
u_short *p, *q;
i=nregs/2;
p=curcm;
q=p+i;
--i;
do {
color= *p++;
r=color>>9;
g=(color>>5)&0x07;
b=(color>>1)&0x07;
*q++ = (r<<8)|(g<<4)|b;
} while (--i>=0);
}
#ifdef __STDC__
PRIVATE hamsharp_distr(void)
#else
PRIVATE hamsharp_distr()
#endif
{
static int sicolors= -1;
int i;
if (sicolors<icolors) {
if (sicolors!= -1) {
for (i=0; i<sicolors; ++i)
free(hshead[i]);
free(hshead);
free(hsmark);
free(wfminind);
free(wfrgb);
}
sicolors=icolors;
wfrgb=Malloc(sicolors*3);
wfminind=Malloc(sicolors);
hsmark=Malloc(sicolors);
hshead=Malloc(sicolors*sizeof(void *));
for (i=0; i<sicolors; ++i)
hshead[i]=Malloc(sicolors*sizeof(struct hs_t));
}
fill_wf_rgb();
fill_hsmark();
fill_hshead();
fill_hs_cm();
fill_wf2rgbweight();
wf2_redo_curcm();
}
#ifdef __STDC__
PRIVATE fill_hsmark(void)
#else
PRIVATE fill_hsmark()
#endif
{
short i;
char *q;
q=hsmark;
i=icolors-1;
do {
*q++ =1;
} while (--i>=0);
}
#ifdef __STDC__
PRIVATE int cmphs(struct hs_t *p1, struct hs_t *p2)
#else
PRIVATE int cmphs(p1, p2)
struct hs_t *p1, *p2;
#endif
{
return p1->dist - p2->dist;
}
#ifdef __STDC__
PRIVATE fill_hshead(void)
#else
PRIVATE fill_hshead()
#endif
{
REG char *p, *q;
REG struct hs_t *hp;
NON_REG int ic;
REG short i;
REG char r, g, b, t, dist;
p=wfrgb+3*icolors;
ic=icolors;
while (p>wfrgb) {
b= *--p;
g= *--p;
r= *--p;
q=wfrgb+3*icolors;
hp=hshead[--ic];
i=icolors-1;
do {
if ((dist=b- *--q)<0) dist= -dist;
if ((t=g- *--q)<0) dist-=t; else dist+=t;
if ((t=r- *--q)<0) dist-=t; else dist+=t;
hp->dist=dist;
hp->color=i;
++hp;
} while (--i>=0);
qsort((char *)hshead[ic], (int)icolors, sizeof(struct hs_t), cmphs);
}
}
#ifdef __STDC__
PRIVATE fill_hs_cm(void)
#else
PRIVATE fill_hs_cm()
#endif
{
NON_REG short j;
REG short i, k, bestk, colperreg;
REG long dist, bestdist;
REG struct hs_t *p;
REG char *q, *r;
colperreg=icolors/nregs;
q=hsmark;
for (j=0; j<nregs; ++j) {
if (j==nregs-1)
colperreg+=icolors-nregs*colperreg;
bestdist=1000000000L;
for (k=0; k<icolors; ++k) {
dist=0;
p=hshead[k];
i=colperreg-1;
do {
while (!q[p->color])
++p;
dist+=p->dist;
++p;
} while (--i>=0);
if (dist<bestdist) {
bestdist=dist;
bestk=k;
}
}
p=hshead[bestk];
i=colperreg-1;
do {
while (!q[p->color])
++p;
q[p->color]=0;
wfminind[p->color]=j;
++p;
} while (--i>=0);
r=wfrgb+3*bestk;
curcm[j]=(*r<<8)|(*(r+1)<<4)|*(r+2);
}
}
#define CONTRACT2
#ifdef __STDC__
PRIVATE contraction_distr(void)
#else
PRIVATE contraction_distr()
#endif
{
static int sicolors= -1;
int i;
if (sicolors!= -1) {
for (i=0; i<sicolors; ++i)
if (cthead[i])
free(cthead[i]);
free(cthead);
free(ctrgbw);
}
sicolors=icolors;
ctrgbw=Malloc(sicolors*4*sizeof(float));
cthead=Malloc(sicolors*sizeof(void *));
cthead[0]=NULL;
for (i=1; i<sicolors; ++i)
cthead[i]=Malloc(i*sizeof(float));
fill_ctrgbw();
fill_cthead();
do_contraction();
fill_ct_cm();
}
#ifdef __STDC__
PRIVATE fill_ctrgbw(void)
#else
PRIVATE fill_ctrgbw()
#endif
{
short i;
u_long th, *p;
float *q;
p=counts+NRGB;
th=threshold;
q=ctrgbw;
i=NRGB-1;
do {
if (*--p >=th) {
*q++ =(float)(i>>8);
*q++ =(float)((i>>4)&0x0f);
*q++ =(float)(i&0x0f);
*q++ =(float)*p;
}
} while (--i>=0);
assert(q==ctrgbw+4*icolors);
}
#ifdef __STDC__
PRIVATE fill_cthead(void)
#else
PRIVATE fill_cthead()
#endif
{
short i, j;
float *p, *q;
float r, g, b, dist, t;
for (i=1; i<icolors; ++i) {
p=cthead[i];
q=ctrgbw+4*i;
r= *q++;
g= *q++;
b= *q;
q=ctrgbw;
#ifdef CONTRACT2
for (j=0; j<i; ++j) {
t=r- *q++; dist=t*t;
t=g- *q++; dist+=t*t;
t=b- *q++; dist+=t*t;
++q;
*p++ =dist;
}
#else
for (j=0; j<i; ++j) {
if ((dist=r- *q++)<0) dist= -dist;
if ((t=g- *q++)<0) dist-=t; else dist+=t;
if ((t=b- *q++)<0) dist-=t; else dist+=t;
++q;
*p++ =dist;
}
#endif
}
}
#ifdef __STDC__
PRIVATE do_contraction(void)
#else
PRIVATE do_contraction()
#endif
{
short ncolors, i, j, besti, bestj;
float *p, *q, bestdist;
float newr, newg, newb, neww, wi, wj;
float t, dist;
ncolors=icolors;
while (ncolors>nregs) {
/* find minimum pair */
bestdist=2000.0;
for (i=0; i<icolors; ++i) {
p=cthead[i];
if (!p)
continue;
j=0;
do {
if (*p++ <bestdist) {
besti=i;
bestj=j;
bestdist= *(p-1);
}
} while (++j<i);
}
/* contract pair to new pair */
p=ctrgbw+4*besti;
q=ctrgbw+4*bestj;
wi=p[3];
wj=q[3];
neww=wi+wj;
newr=(wi*p[0]+wj*q[0])/neww;
newg=(wi*p[1]+wj*q[1])/neww;
newb=(wi*p[2]+wj*q[2])/neww;
/* delete 1 of pair */
if (bestj>besti) {
i=besti;
besti=bestj;
bestj=i;
}
free(cthead[besti]);
cthead[besti]=NULL;
ctrgbw[4*besti+3]= -1.0;
for (i=besti+1; i<icolors; ++i) {
p=cthead[i];
if (p)
p[besti]=1000.0;
}
/* replace other of pair by new contracted color */
p=ctrgbw+4*bestj;
*p++ =newr;
*p++ =newg;
*p++ =newb;
*p =neww;
for (i=bestj+1, q=ctrgbw+4*i; i<icolors; ++i) {
p=cthead[i];
if (p) {
#ifdef CONTRACT2
t=newr- *q++; dist=t*t;
t=newg- *q++; dist+=t*t;
t=newb- *q++; dist+=t*t;
#else
if ((dist=newr- *q++)<0) dist= -dist;
if ((t=newg- *q++)<0) dist-=t; else dist+=t;
if ((t=newb- *q++)<0) dist-=t; else dist+=t;
#endif
++q;
p[bestj]=dist;
} else {
q+=4;
}
}
for (i=0, p=cthead[bestj]; i<bestj; ++i) {
q=ctrgbw+4*i;
if (q[3]< -0.5) {
*p++ =1000.0;
} else {
#ifdef CONTRACT2
t=newr- *q++; dist=t*t;
t=newg- *q++; dist+=t*t;
t=newb- *q; dist+=t*t;
#else
if ((dist=newr- *q++)<0) dist= -dist;
if ((t=newg- *q++)<0) dist-=t; else dist+=t;
if ((t=newb- *q)<0) dist-=t; else dist+=t;
#endif
*p++ =dist;
}
}
/* decrease number of colors */
--ncolors;
}
}
#ifdef __STDC__
PRIVATE fill_ct_cm(void)
#else
PRIVATE fill_ct_cm()
#endif
{
float *p;
u_short *q, color;
short i;
p=ctrgbw;
q=curcm;
i=icolors-1;
do {
if (p[3]< -0.5) {
p+=4;
} else {
color =((int)(*p++ + 0.5)<<8)&0xf00;
color|=((int)(*p++ + 0.5)<<4)&0x0f0;
color|=((int)(*p++ + 0.5)) &0x00f;
++p;
*q++ =color;
}
} while (--i>=0);
assert(q==curcm+nregs);
#ifdef SHAM_BLACK
if (slicedo)
black_darkest();
#endif
}
#ifdef __STDC__
PRIVATE fill_cmrgb(void)
#else
PRIVATE fill_cmrgb()
#endif
{
short i, color;
u_short *p;
char *q;
if (cmrgb==NULL1)
cmrgb=Malloc(3*nregs);
p=curcm;
q=cmrgb;
i=nregs-1;
do {
color= *p++;
*q++ = color>>8;
*q++ = (color>>4)&0x0f;
*q++ = color&0x0f;
} while (--i>=0);
}
#ifdef __STDC__
fill_newcol(void)
#else
fill_newcol()
#endif
{
short i, mini;
char r, g, b, min, dist, t;
NON_REG short savei;
u_long *countp;
char *rgbp;
fill_cmrgb();
if (newcol==NULL1) {
newcol=Malloc(NRGB);
error=Malloc(NRGB);
error2=Malloc(NRGB*sizeof(u_long));
}
i=NRGB-1;
countp=counts+NRGB;
do {
if (*--countp) {
savei=i;
r=i>>8;
g=(i>>4)&0x0f;
b=i&0x0f;
min=100;
rgbp=cmrgb+3*nregs;
i=nregs-1;
do {
if ((dist=b- *--rgbp)<0) dist= -dist;
if ((t=g- *--rgbp)<0) dist-=t; else dist+=t;
if ((t=r- *--rgbp)<0) dist-=t; else dist+=t;
if (dist<min) {
min=dist;
mini=i;
}
} while (--i>=0);
i=savei;
newcol[i]=mini;
error[i]=min;
rgbp=cmrgb+3*mini;
if ((t=r- *rgbp++)<0) t= -t; error2[i]=squares[t];
if ((t=g- *rgbp++)<0) t= -t; error2[i]+=squares[t];
if ((t=b- *rgbp )<0) t= -t; error2[i]+=squares[t];
}
} while (--i>=0);
}
#ifdef __STDC__
fill_newcol_count(void)
#else
fill_newcol_count()
#endif
{
short i, mini;
char r, g, b, min, dist, t;
NON_REG short savei;
u_long *countp;
char *rgbp;
fill_cmrgb();
if (newcol==NULL1) {
newcol=Malloc(NRGB);
error=Malloc(NRGB);
error2=Malloc(NRGB*sizeof(u_long));
}
i=NRGB-1;
countp=counts+NRGB;
do {
if (*--countp) {
savei=i;
r=i>>8;
g=(i>>4)&0x0f;
b=i&0x0f;
min=100;
rgbp=cmrgb+3*nregs;
i=nregs-1;
do {
if ((dist=b- *--rgbp)<0) dist= -dist;
if ((t=g- *--rgbp)<0) dist-=t; else dist+=t;
if ((t=r- *--rgbp)<0) dist-=t; else dist+=t;
if (dist<min) {
min=dist;
mini=i;
}
} while (--i>=0);
i=savei;
newcol[i]=mini;
error[i]=min;
}
} while (--i>=0);
}