home *** CD-ROM | disk | FTP | other *** search
- /* 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;
- }
-