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
/
wriffout.c
< prev
Wrap
C/C++ Source or Header
|
1991-10-19
|
8KB
|
430 lines
/* wasp - copyright Steven Reiz 1990, 1991
* see 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
*/
#include "wasp.h"
#include "wriff.h"
#ifndef NOSH
#include "wriffout.sh"
#endif
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
};
#ifdef __STDC__
row_out(int row)
#else
row_out(row)
int row;
#endif
{
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;
}
}
}
#ifdef __STDC__
rgb_row_out(int row)
#else
rgb_row_out(row)
int row;
#endif
{
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;
}
}
}
#ifdef __STDC__
PRIVATE rgb_line(int y, u_char *inq, int bitnum)
#else
PRIVATE rgb_line(y, inq, bitnum)
int y;
u_char *inq;
int bitnum;
#endif
{
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);
}
#ifdef __STDC__
ham_row_out(int row)
#else
ham_row_out(row)
int row;
#endif
{
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;
}
}
#ifdef __STDC__
fill_prgbtab(void)
#else
fill_prgbtab()
#endif
{
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));
}
}
#ifdef __STDC__
u_char *next_row(int flush)
#else
u_char *next_row(flush)
int flush;
#endif
{
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;
}
#ifdef __STDC__
PRIVATE cwritec(int inlen)
#else
PRIVATE cwritec(inlen)
int inlen;
#endif
{
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-outcrows));
body_size+=r-outcrows;
}