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
/
wriff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-19
|
13KB
|
628 lines
/* wasp - copyright Steven Reiz 1990, 1991
* see wasp.c for further info
* wriff.c, 4/12/90 - 30/1/91,
* 5/5/91 - 2/6/91, 23/6/91, 30/6/91 - 8/7/91
*/
#include "wasp.h"
#define WRIFFMAIN
#include "wriff.h"
#ifndef NOSH
#include "wriff.sh"
#endif
static int ticolors;
#ifdef __STDC__
write_iff(void)
#else
write_iff()
#endif
{
long patchadr1, patchadr2;
long t;
err=0; err2=0;
wriff_init();
decide_mode();
compute_nregs();
wrl(id('F', 'O', 'R', 'M'));
patchadr1=4;
wrl(0L); /* size of the form ilbm, will be patched later */
wrl(id('I', 'L', 'B', 'M'));
write_header();
write_cmap();
write_sham();
patchadr2=lseek(outfd, 0L, 1)+4; /* the size of the body chunk will be patched later */
write_body();
t=lseek(outfd, 0L, 1);
lseek(outfd, patchadr1, 0);
wrl(t-patchadr1-4);
lseek(outfd, patchadr2, 0);
wrl(t-patchadr2-4);
write_cmap();
write_sham();
printf("IFF file written; %ld bytes, error: %ld, error2: %ld\n", t, err, err2);
}
#ifdef __STDC__
wriff_init(void)
#else
wriff_init()
#endif
{
slicedo=0;
counts=NULL1;
cm=NULL1;
curcm=NULL1;
wf2rgbweight=NULL1;
cmrgb=NULL1;
newcol=NULL1;
error=NULL1;
error2=NULL1;
}
#ifdef __STDC__
decide_mode(void)
#else
decide_mode()
#endif
{
float sx, sy, st;
if (directrgb>=0) {
if (directrgb%3)
error1(E0_FATAL, E1_IFF_RGB, E2_OPTION, E3_WRONG_NR_PLANES, (int)directrgb);
nplanes=directrgb;
printf("IFF output; direct rgb, %d planes\n", nplanes);
return;
}
if ((xmode!=UNSET || ymode!=UNSET) && asc)
error0(E0_FATAL, E1_IFF, E2_OPTION, E3_ASC);
if (xmode!=UNSET && hires!=HIRES_OK)
error0(E0_FATAL, E1_IFF, E2_OPTION, E3_NOHIRES);
count_pixels(0, (int)ysz-1, 1);
ticolors=icolors=count_colors(1L);
if (hires==HIRES_MAYBE)
hires=(icolors<=16 ? HIRES_OK : HIRES_NOT);
if (asc && (xsz>scrw || ysz>scrh)) {
sx=(float)scrw/(float)xsz;
sy=(float)scrh/(float)ysz;
if (sy<sx)
st=sy;
else
st=sx;
ymode=LACE;
sy=st*2.0;
if (hires==HIRES_OK) {
xmode=HIRES;
sx=st*2.0;
} else {
sx=st;
if (sy>1.0) {
sx=sx/sy;
sy=1.0;
}
}
if (sx!=sy || sx<1.0) {
scalef(1, sy);
scalef(0, sx);
}
}
if (xmode==UNSET) {
if (icolors<=32)
xmode=LORES;
else
xmode=HAM;
}
slicedo=sliced;
if (ymode==UNSET)
ymode=NOLACE;
if (distrmeth2!=DISTRMETH_UNSET && xmode!=HAM)
error0(E0_FATAL, E1_IFF, E2_OPTION, E3_ITMETH);
if (!inoperation && distrmeth==DISTRMETH_UNSET) {
if (xmode==EHB)
distrmeth=DEF_EHB_DISTRMETH;
else
distrmeth=DEF_DISTRMETH;
}
if (countmeth==COUNTMETH_UNSET)
countmeth=(xmode==HAM ? DEF_HAM_COUNTMETH : DEF_COUNTMETH);
if (xmode==EHB && !is_ehb_distr())
error1(E0_FATAL, E1_IFF, E2_OPTION, E3_EHB_METH, dmethnam(distrmeth));
printf("IFF output; xmode: %s%s, ymode: %s, cmeth: %s, dmeth: %s",
(slicedo ? "sliced " : ""), xmodenam(xmode), ymodenam(ymode),
cmethnam(countmeth), dmethnam(distrmeth));
if (distrmeth2!=DISTRMETH_UNSET)
printf(", dmeth2: %s", dmethnam(distrmeth2));
putchar('\n');
}
#ifdef __STDC__
int is_ehb_distr(void)
#else
int is_ehb_distr()
#endif
{
return (distrmeth==DISTRMETH_EHB || distrmeth==DISTRMETH_MUE ? 1 : 0);
}
#ifdef __STDC__
compute_nregs(void)
#else
compute_nregs()
#endif
{
if (directrgb>=0)
return;
switch (xmode) {
case HAM: nregs=16; nplanes=6; break;
case EHB: nregs=64; nplanes=6; break;
case LORES: nregs=32; nplanes=5; break;
case HIRES: nregs=16; nplanes=4; break;
}
if (slicedo) {
cm=Malloc((ymode==LACE && sliced==SLICED_SHAM ? (ysz+1)/2 : ysz)*nregs*sizeof(u_short));
curcm=cm;
goto compute_npixvals;
}
count_pixels(0, (int)ysz-1, 0);
icolors=count_colors(1L);
if (icolors>nregs && threshold>1) {
icolors=count_colors(threshold);
if (icolors<nregs) {
u_long mint, curt, maxt;
printf("%d colors occur at least %ld times, trying to complete to %d\n",
icolors, threshold, nregs);
mint=1;
maxt=threshold;
while (maxt>mint+1) {
curt=(mint+maxt)/2;
icolors=count_colors(curt);
if (icolors<nregs)
maxt=curt-1;
else
mint=curt;
}
threshold=(mint+maxt)/2;
icolors=count_colors(threshold);
printf("%d colors occur at least %ld times\n", icolors, threshold);
}
}
if (xmode==LORES || xmode==HIRES) {
if (icolors<nregs)
nplanes=ceillog2((u_long)icolors);
else
nplanes=ceillog2((u_long)nregs);
nregs=1<<nplanes;
}
cm=Malloc(nregs*sizeof(u_short));
curcm=cm;
compute_npixvals:
if (distrmeth2!=DISTRMETH_UNSET) {
cm0=Malloc(nregs*sizeof(u_short));
cmprev=Malloc(nregs*sizeof(u_short));
}
npixvals=1<<nplanes;
printf("%d colors", ticolors);
if (icolors!=ticolors)
printf(", counting %d colors", icolors);
printf(", %d color registers, %d planes", nregs, nplanes);
if (nregs-icolors>0)
printf(", %d color registers will be wasted", nregs-icolors);
printf("\n");
if (nregs<2 || xsz<2 || ysz<2)
error0(E0_FATAL, E1_IFF, E2_FORMAT, E3_2SIMPLE);
assert(nplanes>0 && nplanes<=MAXNPLANES);
assert(nregs<=MAXNREGS);
}
#ifdef __STDC__
PRIVATE write_header(void)
#else
PRIVATE write_header()
#endif
{
struct bmhd_t {
u_short w, h;
short x, y;
u_char nplanes, masking, compression, pad;
u_short transpcol;
u_char xaspect, yaspect;
short pagew, pageh;
} bmhd;
u_long viewmodes;
wrl(id('B', 'M', 'H', 'D'));
wrl((long)sizeof(bmhd));
bmhd.w=xsz;
bmhd.h=ysz;
bmhd.x=bmhd.y=0;
bmhd.nplanes=nplanes;
bmhd.masking=0;
bmhd.compression=compression;
bmhd.pad=0;
bmhd.transpcol=0;
bmhd.yaspect=11;
if (xmode==HIRES && ymode==NOLACE)
bmhd.xaspect=5;
else if (xmode!=HIRES && ymode==LACE)
bmhd.xaspect=20;
else
bmhd.xaspect=10;
bmhd.pagew=bmhd.w;
bmhd.pageh=bmhd.h;
cwrite(&bmhd, sizeof(bmhd));
if (directrgb>=0)
return;
wrl(id('C', 'A', 'M', 'G'));
wrl(4L);
viewmodes=0;
if (xmode==HIRES)
viewmodes|=VM_HIRES;
else if (xmode==HAM)
viewmodes|=VM_HAM;
else if (xmode==EHB)
viewmodes|=VM_EHB;
if (ymode==LACE)
viewmodes|=VM_LACE;
wrl(viewmodes);
}
#ifdef __STDC__
PRIVATE write_cmap(void)
#else
PRIVATE write_cmap()
#endif
{
u_char *cmbuf;
long t;
short i, j, nr;
static long pos= -1;
if (directrgb>=0)
return;
if (xmode==EHB)
nr=nregs/2;
else
nr=nregs;
t=nr*3;
if (pos== -1) {
wrl(id('C', 'M', 'A', 'P'));
wrl(t);
pos=lseek(outfd, 0L, 1);
} else
lseek(outfd, pos, 0);
cmbuf=Malloc(t);
for (i=0, j=0; i<nr; ++i) {
cmbuf[j++]=(cm[i]&0x0f00)>>4;
cmbuf[j++]= cm[i]&0x00f0;
cmbuf[j++]=(cm[i]&0x000f)<<4;
}
cwrite(cmbuf, (int)t);
free(cmbuf);
}
#ifdef __STDC__
PRIVATE write_sham(void)
#else
PRIVATE write_sham()
#endif
{
long t;
static long pos= -1;
short version;
if (!slicedo)
return;
if (xmode==EHB)
error0(E0_FATAL, E1_IFF, E2_EHB, E3_SLICED_EHB);
t=(ymode==LACE && sliced==SLICED_SHAM ? (ysz+1)/2 : ysz)*nregs*sizeof(u_short);
if (pos== -1) {
if (sliced==SLICED_SHAM) {
wrl(id('S', 'H', 'A', 'M'));
wrl(t+2);
version=0;
cwrite(&version, 2);
} else {
wrl(id('C', 'T', 'B', 'L'));
wrl(t);
}
pos=lseek(outfd, 0L, 1);
} else
lseek(outfd, pos, 0);
cwrite(cm, (int)t);
}
#ifdef __STDC__
write_body(void)
#else
write_body()
#endif
{
int y, step;
#ifdef __STDC__
int (*outfunc)(int);
#else
int (*outfunc)();
#endif
if (directrgb<0)
fillconv();
if (xmode==HAM)
assert(nplanes==6);
if (!inoperation) {
wrl(id('B', 'O', 'D', 'Y'));
wrl(0L);
}
bytesperrow=(xsz+15)/16*2;
noutrows=MAXOUTBUFSZ/(bytesperrow*nplanes);
if (noutrows==0)
noutrows=1;
outbufsz=noutrows*bytesperrow*nplanes;
outrows=Malloc(outbufsz);
if (compression)
outcrows=Malloc(outbufsz*3/2);
body_size=0;
curcm=cm;
if (xmode==HAM) {
fill_prgbtab();
outfunc=ham_row_out;
} else
outfunc=row_out;
if (directrgb>=0) {
nzero=nplanes/3-4;
if (nzero<0)
nzero=0;
ncolor=nplanes/3;
if (ncolor>4)
ncolor=4;
init_counter(0, (int)ysz, 10, NULL);
for (y=0; y<ysz; ++y)
rgb_row_out(y);
} else if (slicedo) {
if (ymode==LACE && sliced==SLICED_SHAM)
step=2;
else
step=1;
init_counter(0, (int)ysz, 5, NULL);
for (y=0; y<ysz; y+=step) {
if (y==ysz-1)
step=1;
count_pixels(y, y+step-1, 0);
icolors=count_colors(threshold);
if (icolors<nregs && threshold>1)
printf("in row %d (and %d) only %d colors occur at least %ld times\n",
y, y+step-1, icolors, threshold);
compute_distr(y, y+step-1);
outfunc(y);
if (step==2)
outfunc(y+1);
curcm+=16;
}
} else {
compute_distr(0, (int)ysz-1);
init_counter(0, (int)ysz, 10, NULL);
for (y=0; y<ysz; ++y)
outfunc(y);
}
if (!inoperation)
(void)next_row(1); /* to flush the row buffer */
erase_counter(NULL);
}
#ifdef __STDC__
PRIVATE fillconv(void)
#else
PRIVATE fillconv()
#endif
{
short i, j, k;
u_char *p;
conv=Malloc(npixvals*8*MAXNPLANES);
p=conv;
for (i=0; i<npixvals; ++i) {
for (j=128; j; j>>=1) {
for (k=0; k<nplanes; ++k) {
if (i&(1<<k))
*p++ =j;
else
*p++ =0;
}
p+=MAXNPLANES-nplanes;
}
}
}
#ifdef __STDC__
PRIVATE int cmpcolregs(short *p1, short *p2)
#else
PRIVATE int cmpcolregs(p1, p2)
short *p1, *p2;
#endif
{
short c1, c2, i;
c1= *p1;
c2= *p2;
i=((c1>>8) + ((c1&0x00f0)>>4) + (c1&0x000f))
- ((c2>>8) + ((c2&0x00f0)>>4) + (c2&0x000f));
if (i)
return (int)i;
i=(c1>>8)-(c2>>8);
if (i)
return (int)i;
i=((c1&0x00f0)>>4)-((c2&0x00f0)>>4);
if (i)
return (int)i;
i=(c1&0x000f)-(c2&0x000f);
return (int)i;
}
#ifdef __STDC__
sort_cm(void)
#else
sort_cm()
#endif
{
qsort((char *)curcm, (int)nregs, sizeof(u_short), cmpcolregs);
}
static char *qm="?";
static char *sliceds[]={
"ok",
"not",
"maybe",
NULL
};
#ifdef __STDC__
char *slicednam(int i)
#else
char *slicednam(i)
int i;
#endif
{
if (i<0 || i>2)
return qm;
return sliceds[i];
}
static char *xmodes[]={
"unset",
"hires",
"lores",
"ehb",
"ham",
NULL
};
#ifdef __STDC__
char *xmodenam(int i)
#else
char *xmodenam(i)
int i;
#endif
{
if (i<0 || i>4)
return qm;
return xmodes[i];
}
static char *ymodes[]={
"unset",
"lace",
"nolace",
NULL
};
#ifdef __STDC__
char *ymodenam(int i)
#else
char *ymodenam(i)
int i;
#endif
{
if (i<0 || i>2)
return qm;
return ymodes[i];
}
/* should be in same order as DISTRMETH_ defines in wasp.h */
static char *dmeths[]={
"unset",
"mu",
"wf",
"ehb",
"mue",
"hs",
"con",
NULL
};
#ifdef __STDC__
char *dmethnam(int i)
#else
char *dmethnam(i)
int i;
#endif
{
if (i<0 || i>6)
return qm;
return dmeths[i];
}
#ifdef __STDC__
int dmethnum(char *s)
#else
int dmethnum(s)
char *s;
#endif
{
int i;
for (i=1; dmeths[i]; ++i)
if (!strcmp(s, dmeths[i]))
return i;
return -1;
}
/* should be in same order as COUNTMETH_ defines in wasp.h */
static char *cmeths[]={
"unset",
"all1",
"alldif",
"allfdif",
"j1",
"j21",
"jdif",
"jdifsh",
"jfdif",
"jfdifsh",
"hmgs",
"hmcubic",
"hm",
NULL
};
#ifdef __STDC__
char *cmethnam(int i)
#else
char *cmethnam(i)
int i;
#endif
{
if (i<0 || i>12)
return qm;
return cmeths[i];
}
#ifdef __STDC__
int cmethnum(char *s)
#else
int cmethnum(s)
char *s;
#endif
{
int i;
for (i=1; cmeths[i]; ++i)
if (!strcmp(s, cmeths[i]))
return i;
return -1;
}