[comp.sys.atari.st] filter: SCODE to Sun raster

braner@batcomputer.tn.cornell.edu (braner) (12/13/86)

[]

I'm just passing this on.   - Moshe Braner

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Date: Wed, 10 Dec 86
From: cornell!sun!leif@bullwinkle.UUCP (Leif Samuelsson)
Organization: Sun Microsystems, Mountain View
Message-Id: <8612101906.AA04934@viking.sun.com>
Subject: Re: cbw2ps.c - Compressed B&W screen to Postscript

I have made a version of cbw2ps which generates a standard Sun
rasterfile. I currently have no access to postnews, so feel free
to post it if you wish.
----------
/*
 * cbw2sun.c
 *
 * Compressed ST screen (monochrome) to Sun rasterfile filter.
 *
 * By Leif Samuelsson <leif@sun.com>, 861210
 *
 * Based on cbw2ps.c
 * By Moshe Braner, 861116.
 *
 * WARNING: assumes ASCII.
 *
 * Usage:
 *
 *  cbw2sun file
 *
 */

#include <stdio.h>
#include <rasterfile.h>

#define	OK	0
#define	ERROR	-1

FILE	*fp, *fopen();
char	scrn[32000];	/* virtual screen buffer		*/
char	*scrnptr;	/* target address for next decoded byte	*/
long	chksum;		/* chksum on input file			*/
int	rows;
int	cols;
int	row;
int	col;
int	bferr = 0;

main(argc,argv)
	int argc;
	char **argv;
{
	char *filename;
	extern double atof();
		
	fp = stdin;
	filename = "STDIN";
	while(--argc > 0) {
		++argv;
		if((*argv)[0] == '-') {
			switch((*argv)[1]) {
			    default:
				fprintf(stderr,
					"Illegal switch \'%c\' - ignored\n",
					(*argv)[1]);
			}
		} else {
			if((fp = fopen(*argv, "r")) == (FILE *)NULL) {
				fprintf(stderr,"Cannot open %s\n",*argv);
				exit(1);
			}
			filename = *argv;
		}
	}
	process(filename);
}

process(filename)
	char *filename;
{
	int inv = 1;
	int bpp, xmax, ymax, junk;
	register long  i;
	long bytes, origsum;
	register unsigned int c, s, out, mask;
	register int j, bpb, shift, k;
	extern unsigned int decode3();
	struct rasterfile rf;

	c = fgetb() - 0x10;
	chksum = ((long) c)&0x03;
	if (c != 2) {
		fprintf(stderr,
			"%s not a monochrome image!\n",filename);
		exit(1);
	}

	bpp = 1;
	ymax = 400;
	xmax = 640;

	/* Scan off color table */

	c = decode3();
	chksum += ((long) c)&0xFFFF;
	if ((c & 0x01) == 1)
		inv = (! inv);
	for(i = 0; i < 15; i++)
		chksum += ((long) decode3())&0xFFFF;

	/* decode the image itself */

	rows = 400;
	cols = 80;
	row = 0;
	col = 0;
	scrnptr = scrn;
	while ((c=fgetb()) != ERROR) {
		if (c > 0x0F)
			s = reps(c);
		else
			s = uniq(c);
		if (s != OK)
			break;
	}

	/* read original checksum */

	origsum = (((long) decode3())&0xFFFF) << 16;
	origsum += ((long) decode3())&0xFFFF;
	if (bferr) {
		fprintf(stderr,"Error while reading %s\n",
			filename);
		exit(3);
	} else if (chksum != origsum) {
		fprintf(stderr,"Checksum doesn't fit!\n");
		exit(3);
	}

	fclose(fp);

	/* Put out header */

	rf.ras_magic = RAS_MAGIC;		/* magic number */
	rf.ras_width = xmax;		/* width (pixels) of image */
	rf.ras_height = ymax;		/* height (pixels) of image */
	rf.ras_depth = bpp;		/* depth (1, 8, or 24 bits) of pixel */
	rf.ras_length = xmax*ymax/8;	/* length (bytes) of image */
	rf.ras_type = RT_STANDARD;	/* type of file; see RT_* below */
	rf.ras_maptype = RMT_EQUAL_RGB;	/* type of colormap; see RMT_* below */
	rf.ras_maplength = 0;		/* length (bytes) of following map */

	fwrite(&rf, sizeof(rf), 1, stdout);

	/* put out bit map data */

	scrnptr = scrn;
	for (i=0; i<rf.ras_length; i++) {
		out = *scrnptr++;
		putchar((unsigned int)(((inv == 1)? ~out : out)
			 & (unsigned int)0x00ff));
	}
}

/*
 * Read a byte from the input file, translate it.
 * Skip control chars and white space, etc.
 */
int
fgetb()
{
	register int    c;
again:
	if (bferr)
		return (ERROR);
	c = getc(fp);
	if (c == EOF)
		bferr = 1;
	if (c < ',' || c > 'z')
		goto again;
	if (c < 'a')
		return (c - ' ');
	if (c < 'm')
		return (c - 'a');
	if (c < 'v')
		return (c - 0x55);
	return (c - 0x3B);
}

/*
 * Decode one (16-bit) word out of 3 bytes of the input file.
 */
unsigned int
decode3()
{
	register unsigned int c;
	register unsigned int dummy;	/* avoid a Megamax bug */

	c = (fgetb() << 12);
	c |= (fgetb() << 6);
	c |= fgetb();
	return (c);
}

/*
 * Put a decoded byte into the screen buffer.
 */
int
putbyte(b)
	int	b;
{
	*scrnptr = (char) b;
	scrnptr += cols;
	if (++row >= rows) {
		if (++col >= cols) {
			return (ERROR);
		}
		scrnptr = scrn + col;
		row = 0;
	}
	return (OK);
}

/*
 * Handle a pair of decoded screen bytes.
 */
int
putword(w)
	register unsigned int w;
{
	register unsigned int dummy;	/* avoid a Megamax bug */

	chksum += ((long) w)&0xFFFF;
	if (putbyte((w>>8) & 0xFF) == ERROR)
		return (ERROR);
	return (putbyte(w & 0xFF));
}

/*
 * Decode 2 screen bytes.
 */
int
uniq(c)
	register unsigned int c;
{
	register unsigned int dummy;	/* avoid a Megamax bug */

	c <<= 12;
	c |= (fgetb() << 6);
	c |= fgetb();
	if (bferr)
		return (ERROR);
	return (putword(c));
}

/*
 * Decode a 4-byte repetition code.
 */
int
reps(b)
	register unsigned int b;
{
	register unsigned int c;

	b = ((b-0x10) << 2);
	c = fgetb();
	b |= (c >> 4);
	c <<= 12;
	c |= (fgetb() << 6);
	c |= fgetb();
	if (bferr)
		return (ERROR);
	while (b--) {
		if (putword(c) == ERROR)
			return (ERROR);
	}
	return (OK);
}	
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~