home *** CD-ROM | disk | FTP | other *** search
- /* wasp - Copyright 1991 by Steven Reiz
- * see COPYING and wasp.c for further info
- * wriffout.c, 4/12/90 - 29/12/90,
- * 4/5/91 - 2/6/91, 23/6/91 - 30/6/91, 3/7/91 - 8/7/91,
- * 15/11/91, 8/12/91
- */
-
- static char *sourcefile=__FILE__;
-
- #include "wasp.h"
- #include "wriff.h"
-
- static u_char *prtab[16], *pgtab[16], *pbtab[16], *pxtab[16];
- static long squares[]={
- 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225
- };
-
-
- void
- row_out(int row)
- {
- long currow; /* u_char *currow; */
- short *ps, i, x, bperrow;
- char regind;
- u_char *p, *q;
-
- counter();
- currow=(long)next_row(0);
- bperrow=bytesperrow;
- ps=(short *)currow;
- i=bperrow*nplanes/2-1;
- do {
- *ps++ =0;
- } while (--i>=0);
- ps=(short *)rgb[row];
- for (x=0; x<xsz; ++x) {
- i= *ps++;
- regind=newcol[i];
- err+=error[i];
- err2+=error2[i];
- p=conv+((regind<<3)|(x&7))*MAXNPLANES;
- q=(u_char *)currow+(x>>3);
- switch (nplanes) {
- case 8: *q|= *p++; q+=bperrow;
- case 7: *q|= *p++; q+=bperrow;
- case 6: *q|= *p++; q+=bperrow;
- case 5: *q|= *p++; q+=bperrow;
- case 4: *q|= *p++; q+=bperrow;
- case 3: *q|= *p++; q+=bperrow;
- case 2: *q|= *p++; q+=bperrow;
- case 1: *q|= *p;
- }
- }
- }
-
-
- void
- rgb_row_out(int row)
- {
- u_char *currow;
- short *ps, i, bitlast;
-
- counter();
- currow=next_row(0);
- ps=(short *)currow;
- i=bytesperrow*nplanes/2-1;
- do {
- *ps++ =0;
- } while (--i>=0);
- for (bitlast=12; bitlast>0; bitlast-=4) { /* walk over r, g, and b */
- for (i=0; i<nzero; ++i)
- currow+=bytesperrow;
- for (i=bitlast-ncolor; i<bitlast; ++i) {
- rgb_line(row, currow, (int)i);
- currow+=bytesperrow;
- }
- }
- }
-
-
- void
- rgb_line(int y, unsigned char *inq, int bitnum)
- {
- u_short *p, mask;
- u_char *q, byte;
- short i;
-
- i=bytesperrow-1;
- p=rgb[y];
- mask=1<<bitnum;
- q=inq;
- do {
- byte=0;
- if (*p++ & mask) byte|=0x80;
- if (*p++ & mask) byte|=0x40;
- if (*p++ & mask) byte|=0x20;
- if (*p++ & mask) byte|=0x10;
- if (*p++ & mask) byte|=0x08;
- if (*p++ & mask) byte|=0x04;
- if (*p++ & mask) byte|=0x02;
- if (*p++ & mask) byte|=0x01;
- *q++ =byte;
- } while (--i>=0);
- }
-
-
- void
- ham_row_out(int row)
- {
- NON_REG int alternate_rgb;
- long currow; /* actually u_char *currow; */
- short *ps;
- long x, curcolor; /* curcolor doubles as bperrow */
- long r, g, b, pr, pg, pb, d1, d2, d3;
- u_char *p, *q;
-
- counter();
- currow=(long)next_row(0);
- p=(u_char *)currow;
- r=bytesperrow*3-1;
- #ifdef LATTICE
- do {
- *(short *)p=0;
- p+=2;
- } while (--r>=0);
- #else
- do {
- *((short *)p)++ =0;
- } while (--r>=0);
- #endif
- ps=(short *)rgb[row];
- pb=curcm[0];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- alternate_rgb=0;
- for (x=0; x<xsz; ++x) {
- curcolor= *ps++;
- b=curcolor;
- r=b>>8;
- g=(b>>4)&0xf;
- b&=0xf;
- if (r==pr) {
- if (g==pg) {
- if (b==pb) { /* r ok, g ok, b ok */
- if (++alternate_rgb==1) {
- p=pgtab[g];
- } else if (alternate_rgb==2) {
- p=prtab[r];
- } else {
- p=pbtab[b];
- alternate_rgb=0;
- }
- } else { /* r ok, g ok, b wrong */
- p=pbtab[b];
- pb=b;
- }
- } else {
- if (b==pb) { /* r ok, g wrong, b ok */
- p=pgtab[g];
- 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)) {
- err+=error[curcolor];
- err2+=error2[curcolor];
- curcolor=newcol[curcolor];
- p=pxtab[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>=d2) {
- err+=d2;
- err2+=squares[d2];
- p=pgtab[g];
- pg=g;
- } else {
- err+=d1;
- err2+=squares[d1];
- p=pbtab[b];
- pb=b;
- }
- }
- }
- } else {
- if (g==pg) {
- if (b==pb) { /* r wrong, g ok, b ok */
- p=prtab[r];
- 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)) {
- err+=error[curcolor];
- err2+=error2[curcolor];
- curcolor=newcol[curcolor];
- p=pxtab[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>=d2) {
- err+=d2;
- err2+=squares[d2];
- p=prtab[r];
- pr=r;
- } else {
- err+=d1;
- err2+=squares[d1];
- p=pbtab[b];
- 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)) {
- err+=error[curcolor];
- err2+=error2[curcolor];
- curcolor=newcol[curcolor];
- p=pxtab[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>d2) {
- err+=d2;
- err2+=squares[d2];
- p=prtab[r];
- pr=r;
- } else {
- err+=d1;
- err2+=squares[d1];
- p=pgtab[g];
- 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))) {
- err+=error[curcolor];
- err2+=error2[curcolor];
- curcolor=newcol[curcolor];
- p=pxtab[curcolor];
- pb=curcm[curcolor];
- pr=pb>>8;
- pg=(pb>>4)&0xf;
- pb&=0xf;
- } else if (d1>d2 && d1>=d3) {
- err+=d2+d3;
- err2+=squares[d2]+squares[d3];
- p=prtab[r];
- pr=r;
- } else if (d2>=d3) {
- err+=d1+d3;
- err2+=squares[d1]+squares[d3];
- p=pgtab[g];
- pg=g;
- } else {
- err+=d1+d2;
- err2+=squares[d1]+squares[d2];
- p=pbtab[b];
- pb=b;
- }
- }
- }
- }
- p+=(x&7)<<MAXPLANESHIFT;
- q=(u_char *)currow+(x>>3);
- curcolor=bytesperrow;
- *q|= *p++; q+=curcolor;
- *q|= *p++; q+=curcolor;
- *q|= *p++; q+=curcolor;
- *q|= *p++; q+=curcolor;
- *q|= *p++; q+=curcolor;
- *q|= *p;
- }
- }
-
-
- void
- fill_prgbtab(void)
- {
- int i;
-
- for (i=0; i<16; ++i) {
- prtab[i]=conv+((0x20+i)<<(3+MAXPLANESHIFT));
- pgtab[i]=conv+((0x30+i)<<(3+MAXPLANESHIFT));
- pbtab[i]=conv+((0x10+i)<<(3+MAXPLANESHIFT));
- pxtab[i]=conv+(i<<(3+MAXPLANESHIFT));
- }
- }
-
-
- unsigned char *
- next_row(int flush)
- {
- static int freerows= -1;
- static u_char *currow;
-
- if (flush) {
- char c;
-
- cwritec((int)((noutrows-freerows)*bytesperrow*nplanes));
- if (body_size&1) {
- c=0;
- cwrite(&c, 1);
- ++body_size;
- }
- if (compression)
- erase_counter("IFF output; body compression: %ld%%",
- body_size*100L/(xsz*ysz*(long)nplanes/8L));
- return NULL; /* return value not used */
- }
- if (--freerows<0) {
- if (freerows== -1)
- cwritec(outbufsz);
- freerows=noutrows-1;
- currow=outrows;
- } else
- currow+=bytesperrow*nplanes;
- return currow;
- }
-
-
- void
- cwritec(int inlen)
- {
- REG char *p, *r;
- char *q, *countp, *curoutrows;
- short n, todo;
- char c;
-
- if (!compression) {
- cwrite(outrows, inlen);
- body_size+=inlen;
- return;
- }
- assert(!(inlen%bytesperrow));
- inlen/=bytesperrow;
- curoutrows=(char *)outrows;
- r=(char *)outcrows;
- while (--inlen>=0) {
- todo=bytesperrow;
- p=(char *)curoutrows;
- q=p+todo-2;
- while (p<q) {
- c= *p;
- if (*(p+1)==c) {
- countp=p;
- p+=2;
- n=todo-(p-curoutrows);
- if (n>126)
- n=126;
- while (*p==c && --n>=0)
- ++p;
- *r++ =countp-p+1;
- *r++ =c;
- } else {
- countp=r++;
- n=todo-(p-curoutrows);
- if (n>128)
- n=128;
- do {
- ++p;
- if (*p==c && *(p+1)==c) {
- --p;
- break;
- }
- *r++ =c;
- c= *p;
- } while (--n>0);
- *countp=r-countp-2;
- }
- }
- todo=curoutrows+todo-p;
- assert(todo<=2);
- if (todo==1) {
- *r++ =0;
- *r++ = *p;
- } else if (todo==2) {
- c= *p++;
- if (c== *p) {
- *r++ = -1;
- *r++=c;
- } else {
- *r++ =1;
- *r++ =c;
- *r++ = *p;
- }
- }
- curoutrows+=bytesperrow;
- }
- cwrite(outcrows, (int)(r-(char *)outcrows));
- body_size+=r-(char *)outcrows;
- }
-