[comp.graphics] Targa to TIFF source

schear@ttidca.TTI.COM (Steve Schear) (04/15/89)

My group has developed a Targa/Vista to TIFF conversion program to convert
24-bit/pixel images for use on the Mac II.  The program is coded for MS-DOS
operation, but should't be too difficult to port (e.g., to the Mac).

We discovered that the Mac program we use, LaserPaint Color II, diverges
slightly from the TIFF standard, and we accomodated that change (documented
in the source).

Good luck.

# ---------------
# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# GFC.C GFC.H GFCGLOB.C GFCGLOB.H MGDOBUF.C MSR.C MUBUF.C MUERROR.C MUGETLIN.C MULEX.C MUSWAP.C MUTIL.H SRCFMT.C TARGA.C TGAGEN.C TGA_PARS.C TIFF.C TIFFGEN.C TIFFGEN.H TT.C TTCNV.H arch.shar

echo x - GFC.C
cat > "GFC.C" << '//E*O*F GFC.C//'
/*
	gfc.c
		
	Graphics file format converter. Only does TARGA24(aka VISTA) and
	TIFF24 formats.


	89/ 3/20 : M.Guzman created

*/
static char *id = "$header : gfc v1.0, graphics file converter\n";

#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <string.h>
#include "gfcglob.h"
#include "gfc.h"

main ( argc, argv )
int argc;
char *argv[];
{
	char ofn[15], *pptr;
	int fret, ofdi, ifdi, i, sfmt;
	
/* init error reporting mechanism */
	
	mu_error_init("err.cfg");

/* global init */

	Ifd = Ofd = -1;
	Dump = Bpp = Dfmt = Dbo = 0;
	
/* check for help */
	
	if ( argc < 2 )
		usage();

/* process switches and find file names */

	ifdi = ofdi = 0;
	for ( i=1; i<argc; i++ ) {
		if ( argv[i][0] == '-' ) {
			switch( (int)argv[i][1] ) {

/* dump header switch */
				
			case 'h' :
				Dump = 1;
				break;
							
			default :
				printf("Illegal switch : -%c\n",argv[i][1]);
				break;
			}
		}
		else {
			if ( !ifdi )
				ifdi = i;
			else {
				if ( !ofdi )
					ofdi = i;
			}
		}
	}

/* open input file */
	
	if ( ifdi ) {
		if ( (Ifd = open(argv[ifdi], O_BINARY | O_RDONLY)) < 0 ) {
			printf("Cannot open input file : %s\n",argv[ifdi]);
			exit(0);
		}
	}
	else {
		printf("Missing input file name.\n");
		exit(0);
	}

/* identify source format */
	
	sfmt = source_format();

/* since we only do TARGA24(aka VISTA) & TIFF24, Dfmt must be other */

	if ( sfmt == VISTA)
		Dfmt = TIFF;
	else {
		Dfmt = VISTA;
		Dbo = LSF;
	}
	
/* build output file name */

	if ( ofdi )
		strcpy(ofn,argv[ofdi]);
	else {
		strcpy(ofn,argv[ifdi]);
		if ( (pptr = strchr(ofn,'.')) != NULL )
			strcpy(pptr,Fnames[Dfmt]);
		else
			strcat(ofn,Fnames[Dfmt]);
	}

	if ( !((int)strcmp(ofn,argv[ifdi])) ) {
		printf("Input and output filenames match!\n");
		exit(0);
	}
		

/* parse infile */

	switch ( sfmt ) {
		
		case VISTA:
			targa(ofn);
			break;
			
		case TIFF:
			tiff(ofn);
			break;
			
		default:
			printf("Unknown file type.\n");
			exit();
	}
	

/* Clean up and exit from gfc */

	close(Ifd);
	close(Ofd);
	
	exit(0);
}

/*--------------------------------------------------------------*/
/*	usage : print gfc usage					*/
/*--------------------------------------------------------------*/

usage()
{
printf("\nusage : gfc infile [outfile] [-h{8,12,16,24,32}bcfrv]\n\n");
printf("Graphics file converter, vers 1.O. Only VISTA(TARGA24) and TIFF24\n");
printf("formats, default conversion is always to other format. Switches\n");
printf("may appear anywhere in command line.\n\n");
printf("outfile : default is derived from infile, extensions(.vst,.tif)\n");
printf("-h : interpret header to stdout\n");
printf("-{8,12,16,24,32}bcfrv : future enhancement\n\n");
exit(0);
}
//E*O*F GFC.C//

echo x - GFC.H
cat > "GFC.H" << '//E*O*F GFC.H//'
/*
	gfc.h

	Main header file for gfc.
		
*/

/* format types */

#define	UNK	0
#define TARGA	1
#define VISTA	2
#define TIFF	3
#define	CGM	4
#define NAPLP	5
#define	TTIDO	10

/* format extensions */

static char *Fnames[] = { 0, ".tga", ".vst", ".tif", ".cgm", ".plp" };

/* byte order: least sig first, most sig first */

#define	LSF	1
#define MSF	2


//E*O*F GFC.H//

echo x - GFCGLOB.C
cat > "GFCGLOB.C" << '//E*O*F GFCGLOB.C//'

/*
	gfcglob.c
		
	Global variable allocation. Header file "gfcglob.h" has external
	definitions.
		
*/


#include	<gfcglob.h>
/* dump header, bits per pixel, destination format, destination byte order */
int Dump, Bpp, Dfmt, Dbo;

/* input file descriptor, output file descriptor */
int Ifd, Ofd;

/* working buffer */
char Bb[1024];

char Wbuf[WBUFSIZ];
char *tag_txt[] = {

			"NewSubfileType",
			"SubfileType",
			"ImageWidth",
			"ImageLength",
			"BitsPerSample",
			"Compression",
			"","",
			"PhotometricInterpretation",
			"Threshholding",
			"CellWidth",
			"CellLength",
			"FillOrder",
			"","",
			"DocumentName",
			"ImageDescription",
			"Make",
			"Model",
			"StripOffsets",
			"Orientation",
			"","",
			"SamplesPerPixel",
			"RowsPerStrip",
			"StripByteCounts",
			"MinSampleValue",
			"MaxSampleValue",
			"XResolution",
			"YResolution",
			"PlanarConfiguration",
			"PageName",
			"XPosition",
			"YPosition",
			"FreeOffsets",
			"FreeByteCounts",
			"GrayResponseUnit",
			"GrayResponseCurve",
			"Group3Options",
			"Group4Options",
			"","",
			"ResolutionUnit",
			"PageNumber",
			"","","",
			"ColorResponseCurves",
			"","","",
			"Software",
			"DateTime",
			"","","","","","","","",
			"Artist",
			"HostComputer",
			"Predictor",
			"WhitePoint",
			"PrimaryChromaticities",
			"ColorMap"
			};

//E*O*F GFCGLOB.C//

echo x - GFCGLOB.H
cat > "GFCGLOB.H" << '//E*O*F GFCGLOB.H//'
/*
	gfcglob.h
		
	Global variable definitions.
		
*/

/* dump header, bits per pixel, destination format, destination byte order */
extern int Dump, Bpp, Dfmt, Dbo;

/* input file descriptor, output file descriptor */
extern int Ifd, Ofd;

/* working buffer *//* working buffer */
extern char Bb[1024];

#define	CI_NUM		0
#define	COLOR_MAP	1
#define	IMAGE_CODE	2
#define	CL_MAP_SPEC	3
#define	IMAGE_SPEC	4
#define	XORIGIN		5
#define	YORIGIN		6
#define	IMAGE_WIDTH	7
#define	IMAGE_LENGTH	8
#define	IM_PIX_SIZE	9
#define	IM_DES		10
#define	IMAGE_ID	11
#define	CL_MAP_DATA	12
#define	IM_DATA_FLD	13


#define INTEL		0

#define OPEN_MODE	O_CREAT|O_RDWR|O_BINARY|O_TRUNC
#define OPEN_ACCESS	S_IREAD|S_IWRITE
#define WBUFSIZ		10240
//E*O*F GFCGLOB.H//

echo x - MGDOBUF.C
cat > "MGDOBUF.C" << '//E*O*F MGDOBUF.C//'
/*	mgdobuf.c : Output data buffer manager routines.
 
	ROUTINES : mgd_obuf_init : initialize output buffers and control
		   mgd_obuf_fill : write queue data to output buffers
		   mgd_obuf_len : get length of output buffer
		   mgd_obuf_output : write out output buffers
			   
	88/08/29 : MAG created
*/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "sc.h"
#include "scerr.h"
#include "acrtc.h"
#include "mutil.h"

#define OBUFSIZE	512

static struct {
	int	status;
	char	*data;
	long	loc;
	int	len;
} Oq[4] = { -1, 0, 0, NULL,
	    -1, 0, 0, NULL,
	    -1, 0, 0, NULL,
	    -1, 0, 0, NULL };

/*--------------------------------------------------------------*/
/*	mgd_obuf_init : initialize output buffers and control	*/
/*--------------------------------------------------------------*/

mgd_obuf_init ()
{
	int i;

/* set the status to NORM, create list buffer, write dummy first size */
	
	for ( i=0; i<4; i++ ) {
		Oq[i].status = NORM;
		Oq[i].len = 0;
		Oq[i].loc = 0L;
		if ( (Oq[i].data = mu_alloc_buf(OBUFSIZE)) == NULL ) {
			mu_error( NULL, MALLOCFAIL,
				"Q(%d) data buffer malloc failure\n",i);
			return( - 1 );
		}
		mu_buf_fill(Oq[i].data,&Oq[i].len,2);
	}
}
		

/*--------------------------------------------------------------*/
/*	mgd_obuf_fill : write queue data to output buffers	*/
/*--------------------------------------------------------------*/

mgd_obuf_fill ( q, buf, len, flag )
int q, len, flag;
char *buf;
{
	int ret;

/* check */
	
	if ( Oq[q].status != NORM && Oq[q].status != EXCEPT ) {
		printf("Output buffers not initialized : Q(%d)  status(%d)\n",
			q,Oq[q].status);
		exit(0);
	}

	if ( len != (len & 0xfffe )) {
		printf("Odd length data buffer : Q(%d)  len(%d)\n",q,len);
		ret = -1;
		goto exit;
	}
	
/* compare flag to last flag. process if different */

	if ( flag != Oq[q].status ) {
		
/* rewrite the size of the block of ACRTC data */

		mu_buf_refill( Oq[q].data, Oq[q].loc, &Oq[q].len, 2 );

/* update */

		Oq[q].status = flag;
		Oq[q].loc = mu_buf_len( Oq[q].data );
		Oq[q].len = 0;

/* write a place holder for a future size value */

		mu_buf_fill( Oq[q].data, &Oq[q].len, 2 );
	}
		
/* write the data to the buffer */

	Oq[q].len += len;
	mu_buf_fill( Oq[q].data, buf, len );
	ret = len;
exit:
	return(ret);
}


/*--------------------------------------------------------------*/
/*	mgd_obuf_len : get length of output buffer		*/
/*--------------------------------------------------------------*/

long mgd_obuf_len ( q )
int q;
{
	return( mu_buf_len(Oq[q].data) + 2l);
}


/*--------------------------------------------------------------*/
/*	mgd_obuf_output : write out output buffers		*/
/*--------------------------------------------------------------*/

mgd_obuf_output ( fd, q )
int fd,q;
{
	int len, ecnt, i, wamt;
	long lret;
	
/* rewrite the size of the last block of ACRTC data */

	mu_buf_refill( Oq[q].data, Oq[q].loc, &Oq[q].len, 2 );

/* add a terminating size of zero, swap bytes for motorola format write */
	
	len = 0;
	mu_buf_fill(Oq[q].data,&len,2);
	
	mu_buf_swab( Oq[q].data );
	if ((lret = mu_buf_write( fd, Oq[q].data )) < 0L )
		mu_error(sc_longjmp,WRITEFAIL,
			"obuf output - data write fail : fd(%d)\n",fd);

	printf("   %5ld bytes, ACRTC(%d) data\n",lret,q);

}
//E*O*F MGDOBUF.C//

echo x - MSR.C
cat > "MSR.C" << '//E*O*F MSR.C//'
static char *id = "$header : Motorola S record converter : 10/17/88\n";

#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "string.h"

#define SRSIZE	32
#define IBSIZE	10240
#define S9	"S9030000FC\n"

char Ibuf[IBSIZE], aa[200], bb[200];
char *ih(), nta(), *cta();
unsigned char cs();

main ( argc, argv )
int argc;
char *argv[];
{
	char ifn[20], ofn[20], *pptr, *bptr;
	int fret, ofd, ifd, i, ramt, wamt, red, wrot, ifi, ofi, pos, cnt;
	int srsize, ibsize;
	long loadr;
	
/* check for help */
	
	if ( argc < 2 )
		usage();

/* process switches and find file names */

	ifi = ofi = 0;
	loadr = 0L;
	srsize = SRSIZE;
	
	for ( i=1; i<argc; i++ ) {
		if ( argv[i][0] == '-' ) {
			switch( (int)argv[i][1] ) {

			case 'a' :
				i++;
				sscanf(argv[i],"%lx",&loadr);
				break;
				
			case 's' :
				i++;
				sscanf(argv[i],"%d",&srsize);
				break;
							
			default :
				printf("Illegal switch : -%c\n",argv[i][1]);
				break;
			}
		}
		else {
			if ( !ifi )
				ifi = i;
			else {
				if ( !ofi )
					ofi = i;
			}
		}
	}

/* create file names */

	if ( !ifi ) {
		printf(" Missing input file name.\n");
		exit(0);
	}
	
	strncpy(ifn,argv[ifi],13);
	if ( (pptr = strchr(ifn,'.')) == NULL )
		strcat(ifn,".m");
	
	if ( ofi ) {
		strncpy(ofn,argv[ofi],13);
		if ( (pptr = strchr(ofn,'.')) == NULL )
			strcat(ofn,".ms");
	}
	else {
		strcpy(ofn,ifn);
		pptr = strchr(ofn,'.');
		*pptr = 0;
		strcat(ofn,".ms");
	}
	
	if ( !(int)strcmp(ifn,ofn) ) {
		printf("Input and output filenames match! : %s, %s\n",
			ifn,ofn);
		exit(0);
	}
	
/* open files */
	
	if ( (ifd = open(ifn, O_BINARY | O_RDONLY)) < 0 ) {
		printf("Cannot open input file : %s\n",argv[ifi]);
		exit(0);
	}

	if (( ofd = open(ofn,O_CREAT|O_RDWR|O_BINARY|O_TRUNC,
		S_IREAD|S_IWRITE))<0) {
		printf("Cannot create output file : %s\n",argv[ofi]);
		exit(0);
	}

/* loop reading input file */

	ibsize = (IBSIZE / srsize) * srsize;
	while ( (red = read(ifd,Ibuf,ibsize)) > 0 ) {
		bptr = Ibuf;

		while ( red ) {
			cnt = ( srsize < red ? srsize : red );
		
/* build binary form of record, without header. length, address, data */

			pptr = ih(aa,(long)(cnt+4),1);
			pptr = ih(pptr,loadr,3);
			memmove(pptr,bptr,cnt); pptr+=cnt;
			*pptr = cs(aa,cnt+4);

/* build ascii version */
		
			strcpy(bb,"S2");
			pptr = cta(&bb[2],aa,cnt+5);
			sprintf(pptr,"\n\r");
			
/* write */
			
			write(ofd,bb,strlen(bb));
			
/* update */
			
			red -= cnt;
			bptr += cnt;
			loadr += (long)cnt;
		}
	}
	write(ofd,S9,strlen(S9));
}
				
				
char *ih( dptr, val, len )
char *dptr;
long val;
int len;
{
	char *tptr;
	int ofs;
	
/* work backwards from end to start */

	dptr += len;
	tptr = dptr;

	while ( len-- ) {
		tptr--;
		*tptr = (char)(val & 0xff);
		val >>= 8;
	}
	return( dptr );
}


unsigned char cs( sptr, len )
unsigned char *sptr;
int len;
{
	unsigned long sum;
	
	sum = 0L;
	while( len-- )
		sum += *sptr++;

	sum &= 0xff;
	sum ^= 0xff;
	
	return ( (unsigned char)sum);
}


char *cta ( dptr, sptr, len )
char *dptr, *sptr;
int len;
{
	while ( len-- ) {
		*dptr++ = nta( *sptr >> 4 );
		*dptr++ = nta( *sptr++ & 0xf );
	}
	return( dptr );
}


char nta( val )
char val;
{
	val &= 0xf;
	
	if ( val < 10 )
		return( val+'0' );
	else
		return( val+'A' - 0xA );
}


usage()
{
printf("usage : sr infile [outfile] [-a hexadr][-s srecsize]\n\n");
printf("   Assumes .m on input file if extension is missing. Default\n");
printf("   output file is input filename with .ms extension.\n\n");
exit(0);
}

//E*O*F MSR.C//

echo x - MUBUF.C
cat > "MUBUF.C" << '//E*O*F MUBUF.C//'
/*	mubuf.c : Generic buffer manager routines.

	ROUTINES : ptr = mu_alloc_buf( size ) : allocate buffer
			 mu_buf_len( ptr ) : get length of buffer
			 mu_buf_fill( ptr, buf, len ) : add data to buffer
			 mu_buf_refill( ptr, adr, buf, len ) : rewrite at adr
			 mu_buf_read( b, adr, buf, len ) : read buffer
			 mu_buf_write( fd, ptr ) : output buffer
			 mu_free_buf( ptr ) : free buffer
			 mu_buf_swap( ptr ) : swap bytes

	88/08/29 : MAG created
		
*/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define IDCODE	0xa5425546

/* buffer control structures */

typedef struct LInk {
	struct LInk	*prev;
	struct LInk	*next;
	int	size;
	int	used;
	char	data[1];
} LINK;

typedef struct {
	long	id;
	LINK	*head;
	LINK	*tail;
	long	size;
	int	grow;
} Bctl;

/*--------------------------------------------------------------*/
/*	ptr = mu_alloc_buf( size ) : allocate buffer		*/
/*--------------------------------------------------------------*/

char *mu_alloc_buf( size )
int size;
{
	Bctl *ret;
	LINK *link;
	
/* check for valid size. should be even */
	
	if ( size < 0 || size > 32500 ) {
		ret = NULL;
		goto exit;
	}
	
	size++;
	size &= 0xfffe;

/* malloc buffer */	

	if ( (ret=(Bctl *)malloc(size+sizeof(Bctl)+sizeof(LINK))) == NULL ) {
		mu_error( NULL, -1,
			"mu buffer alloc - malloc fail\n");
		goto exit;
	}
	link = (LINK *)(ret+1);
	
/*printf("Bctl(%ld)  Link(%ld)  sizeof(Bctl)(%d)\n",ret,link,sizeof(Bctl));*/

/* setup control structures */

	ret->id   = IDCODE;
	ret->head = link;
	ret->tail = link;
	ret->size = 0;
	ret->grow = size;

	link->prev = NULL;
	link->next = NULL;
	link->size = size;
	link->used = 0;

exit:
	return( (char *)ret );
}
		
/*--------------------------------------------------------------*/
/*	 mu_buf_len( ptr ) : get length of buffer		*/
/*--------------------------------------------------------------*/
long mu_buf_len( b )
Bctl *b;
{
	long lret;
	
	if ( b->id != IDCODE ) {
		mu_error(NULL,-1,"mu_buf_len : Bad buf pointer(%lx)\n",
			b);
		lret = -1L;
	}
	else
		lret = b->size;
	
	return( lret );
}

/*--------------------------------------------------------------*/
/*	growbuf( link, size ) : add another block to buffer	*/
/*--------------------------------------------------------------*/

static LINK *(growbuf)( l, size )
LINK *l;
int size;
{
	LINK *t;
	
/* allocate buffer */

	if ( (t = (LINK *)malloc(size+sizeof(LINK))) == NULL ) {
		mu_error( NULL, -1,"mu grow buf - malloc fail\n");
		goto exit;
	}
	
/* update */
	
	l->next = t;
	t->prev = l;
	t->next = NULL;
	t->size = size;
	t->used = 0;

exit :
	return( t );
}

/*--------------------------------------------------------------*/
/*	 mu_buf_fill( ptr, buf, len ) : add data to buffer	*/
/*--------------------------------------------------------------*/
mu_buf_fill( b, buf, len )
Bctl *b;
char *buf;
int len;
{
	LINK *link;
	int avl, cnt, ret;

/*printf("		Buf(%lx), amount(%d)\n",b,len);*/

	if ( b->id != IDCODE ) {
		mu_error(NULL,-1,"mu_buf_len : Bad buf pointer(%lx)\n",
			b);
		ret = -1;
		goto exit;
	}
			
/* point to tail */
	
	link = b->tail;

/* fill buffer */
	
	while ( len ) {
		
/* calc avail space, link to another buffer if needed */
		
		avl = link->size - link->used;
		if ( !(avl) ) {
			avl = ( b->grow > len ? b->grow : len );
			if ( (link = growbuf( link, avl )) == NULL ) {
				ret = -1;
				goto exit;
			}
			else
				b->tail = link;
		}
		
/* fill in current buffer */
		
		cnt = ( len < avl ? len : avl );
		memcpy( &link->data[link->used], buf, cnt );
		
/* update */		
		
		len -= cnt;
		buf += cnt;
		link->used += cnt;
		b->size += cnt;
	}
	ret = len;
	
exit:
	return(ret);
}


/*--------------------------------------------------------------*/
/*	 mu_buf_refill() : rewrite at addr			*/
/*--------------------------------------------------------------*/
mu_buf_refill( b, adr, buf, len )
Bctl *b;
long adr;
char *buf;
int len;
{
	LINK *link;
	int avl, cnt, ret, fill, refill, used, sref;
	long tadr;

	if ( b->id != IDCODE ) {
		mu_error(NULL,-1,"mu_buf_len : Bad buf pointer(%lx)\n",
			b);
		ret = -1;
		goto exit;
	}
			
	ret = 0;
	

/* check for end of buf. if past, error. overlap ok */
	
	if ( adr > b->size ) {
		ret = -1;
		goto exit;
	}
	
	if ( len < 1 )
		goto exit;

/* do refill part first. goto adr */
	
	sref = refill = ( b->size < adr+(long)len ? (int)b->size-adr : len);
	
	if ( refill ) {
		tadr = adr;
		link = b->head;
	
		while ( tadr >= link->used ) {
			tadr -= link->used;
			link = link->next;
		}
		
/* fill buffer */
	
		used = tadr;
		while ( refill ) {
		
/* calc avail space, link to another buffer if needed */
		
			avl = link->used - used;
			if ( !(avl) ) {
				link = link->next;
				used = 0;
				avl = link->used;
			}
		
/* fill in current buffer */
		
			cnt = ( refill < avl ? refill : avl );
			memcpy( &link->data[used], buf, cnt );
		
			refill -= cnt;
			buf += cnt;
			used += cnt;
		}
	}
	
/* do the fill part */	
	
	if ( (fill = len - sref) ) {
		if ( (ret = mu_buf_fill( b, buf, fill )) == fill )
			ret = len;
		else
			ret = -1;
	}
	else
		ret = len;
		
exit:
	return( ret );
}


/*--------------------------------------------------------------*/
/*	 mu_buf_read() : read buffer				*/
/*--------------------------------------------------------------*/
mu_buf_read( b, adr, buf, len )
Bctl *b;
long adr;
char *buf;
int len;
{
	LINK *link;
	int avl, cnt, ret, redto;
	long tadr;

	if ( b->id != IDCODE ) {
		mu_error(NULL,-1,"mu_buf_len : Bad buf pointer(%lx)\n",
			b);
		ret = -1;
		goto exit;
	}
			
	ret = 0;
	
/* check for read past end of buf */
	
	if ( (adr+(long)len) > b->size ) {
		ret = -1;
		goto exit;
	}
	
	if ( len < 1 )
		goto exit;

/* goto adr */
	
	tadr = adr;
	link = b->head;
	
	while ( tadr >= link->used ) {
		tadr -= link->used;
		link = link->next;
	}
		
/* read buffer */
	
	redto = tadr;
	while ( len ) {
		
/* calc avail data to read, link to another buffer if needed */
		
		avl = link->used - redto;
		if ( !(avl) ) {
			link = link->next;
			redto = 0;
			avl = link->used;
		}
		
/* fill in current buffer */
		
		cnt = ( len < avl ? len : avl );
		memcpy( buf, &link->data[redto], cnt );
		
		len -= cnt;
		buf += cnt;
		redto += cnt;
	}
	
exit:
	return( len );
}


/*--------------------------------------------------------------*/
/*	 mu_buf_write( fd, ptr ) : output buffer		*/
/*--------------------------------------------------------------*/
long mu_buf_write( fd, b )
int fd;
Bctl *b;
{
	LINK *l;
	long total;
	int fret, wamt;

	if ( b->id != IDCODE ) {
		mu_error(NULL,-1,"mu_buf_len : Bad buf pointer(%lx)\n",
			b);
		total = -1L;
		goto exit;
	}
			
/* point to first buffer */
	
	total = 0;
	l = b->head;
	
/* loop writing out buffers */	

	while ( l != NULL ) {
printf("		Buf(%lx), link block(%lx)  size(%d)\n",b,l,l->used);
		wamt = l->used;
		if ((fret = write(fd,l->data,wamt)) != wamt ) {
			mu_error(NULL,-1,
				"mu buf write - write fail : fd(%d)\n",fd);
			total = -1;
			goto exit;
		}
		total += wamt;

/* point to the next buffer */
		
		l = l->next;
	}

exit:
	return(total);
}

/*--------------------------------------------------------------*/
/*	 mu_free_buf( ptr ) : free buffer			*/
/*--------------------------------------------------------------*/
mu_free_buf( b )
Bctl *b;
{
}


/*--------------------------------------------------------------*/
/*	 mu_buf_swab( ptr ) : swap bytes			*/
/*--------------------------------------------------------------*/
long mu_buf_swab( b )
Bctl *b;
{
	LINK *l;
	long total;
	int fret, wamt;

	if ( b->id != IDCODE ) {
		mu_error(NULL,-1,"mu_buf_len : Bad buf pointer(%lx)\n",
			b);
		total = -1L;
		goto exit;
	}
			
/* point to first buffer */
	
	total = 0;
	l = b->head;
	
/* loop swapping buffers */	

	while ( l != NULL ) {
		total += mu_swab_ip(l->data,l->used);
		l = l->next;
	}

exit:
	return(total);
}
//E*O*F MUBUF.C//

echo x - MUERROR.C
cat > "MUERROR.C" << '//E*O*F MUERROR.C//'
/*
	muerror.c
		
	Utility error reporting.

	merr ( error val, printf string, ARGS )
	mu_error ( &error handler, error val, printf string, ARGS )
	mu_error_init ( &error control file name )
		
	88/09/02 : M.Guzman created
	89/03/20 : added merr()
		
*/

#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>

#include <mutil.h>

#define	MODE	100
#define SCREEN	101
#define ONCEF	102
#define ALWAYSF	103
#define LEXSIZE	5

extern int errno;
static char Ebuf[512], Fname[30];
static FILE *Fp;
static int Mode = SCREEN, Ecnt = 1;
static LEX Tok[] =
	{	"alwaysf",	ALWAYSF,
		"mode",		MODE,
		"oncef",	ONCEF,
		"screen",	SCREEN,
		NULL,		0 };
static char Delim[] = "	 ()=,";
static LEX Lex[LEXSIZE];
			

/*----------------------------------------------------------------------*/
/*	print error message, then return. 				*/
/*----------------------------------------------------------------------*/

muerr ( eval, fmt )
int eval;
char *fmt;
{
	int elen, wamt;
	va_list argptr;
			
/* point to the stacked variables */
	
	va_start(argptr, fmt);
	
/* build output message and write to screen */
	
	sprintf( Ebuf,"%4d. E(%4d) > ",Ecnt++,eval);
	vsprintf( &Ebuf[strlen(Ebuf)],fmt, argptr );
	elen = strlen(Ebuf);
	printf(Ebuf);
	
/* process depending on mode */
	
	switch ( Mode ) {

	case SCREEN :
		break;
		
	case ONCEF :
		if ( (wamt = fprintf(Fp,Ebuf)) != elen)
			printf("MU_ERROR : file write fail(%d)\n",
				errno);
		break;
			
	case ALWAYSF :
		if ( (Fp = fopen(Fname,"a")) == NULL ) {
			printf("MU_ERROR_INIT : ""%s"" open fail\n",
				Lex[2].str);
			break;
		}
		if ( (wamt = fprintf(Fp,Ebuf)) != elen)
			printf("MU_ERROR : file write fail(%d)\n",
				errno);
		fclose(Fp);
		break;
	}
}

/*----------------------------------------------------------------------*/
/*	print error message, then pass control to handler		*/
/*----------------------------------------------------------------------*/

mu_error ( ehand, eval, fmt )
int (*ehand)(), eval;
char *fmt;
{
	int elen, wamt;
	va_list argptr;
			
/* point to the stacked variables */
	
	va_start(argptr, fmt);
	
/* build output message and write to screen */
	
	sprintf( Ebuf,"%4d. E(%4d) > ",Ecnt++,eval);
	vsprintf( &Ebuf[strlen(Ebuf)],fmt, argptr );
	elen = strlen(Ebuf);
	printf(Ebuf);
	
/* process depending on mode */
	
	switch ( Mode ) {

	case SCREEN :
		break;
		
	case ONCEF :
		if ( (wamt = fprintf(Fp,Ebuf)) != elen)
			printf("MU_ERROR : file write fail(%d)\n",
				errno);
		break;
			
	case ALWAYSF :
		if ( (Fp = fopen(Fname,"a")) == NULL ) {
			printf("MU_ERROR_INIT : ""%s"" open fail\n",
				Lex[2].str);
			break;
		}
		if ( (wamt = fprintf(Fp,Ebuf)) != elen)
			printf("MU_ERROR : file write fail(%d)\n",
				errno);
		fclose(Fp);
		break;
	}
	
/* call the error service routine */

	if ( ehand != NULL )
		(*ehand)(eval);
}

/*----------------------------------------------------------------------*/
/*	initialize debugging.						*/
/*----------------------------------------------------------------------*/

mu_error_init( cfile )
char *cfile;
{
	int llen, tcnt;
	FILE *fp;
	
/* passed or default file name */
	
	if ( cfile == NULL )
		cfile = "muerror.cfg";
	
/* check for debug config file. if not there, mode is "write to screen" */

	if ( (fp = fopen(cfile,"r")) == NULL ) {
		Mode = 0;
		goto exit;
	}
	
/* process config file. get a line, lex it, process it */
	
	while ( (llen = mu_get_line(fp,Ebuf,sizeof(Ebuf),'!')) > 0 ) {

		if ( (tcnt = mu_lex(Tok,Delim,Lex,LEXSIZE,Ebuf)) < 1 )
			continue;
		
		if ( Lex[0].val != MODE ) {
			Mode = -1;
			printf("MU_ERROR_INIT : bad cmd(%s)\n",
				Lex[0].str);
			goto exit;
		}
		
/* process based on debug write mode. default mode is SCREEN */
		
		switch ( Lex[1].val ) {
			
		case ONCEF :
			Mode = ONCEF;
			if ( (Fp = fopen(Lex[2].str,"w")) == NULL )
				printf("MU_ERROR_INIT : ""%s"" create fail\n",
					Lex[2].str);
			break;
					
		case ALWAYSF :
			Mode = ALWAYSF;
			if ( (Fp = fopen(Lex[2].str,"w")) == NULL )
				printf("MU_ERROR_INIT : ""%s"" create fail\n",
					Lex[2].str);
			fclose(Fp);
			strcpy(Fname,Lex[2].str);
			break;
		}
	}
exit :
	return;
}
//E*O*F MUERROR.C//

echo x - MUGETLIN.C
cat > "MUGETLIN.C" << '//E*O*F MUGETLIN.C//'
#include <stdio.h>
#include <string.h>

/* get a line from a file. filter out comments and blank lines. */

mu_get_line ( fp, buf, len, comchar )
FILE *fp;
char *buf, comchar;
int len;

{
	int ret;
	char *str, *tstr;

/* loop getting lines */

	while ( 1 ) {

/* get a line and transform \r and \n into zeros */

		if ( (str = fgets(buf,len,fp)) == NULL ) {
			ret = 0;
			goto exit;
		}
		
		if ( tstr = strchr(buf,'\r') )
			*tstr = 0;
		if ( tstr = strchr(buf,'\n') )
			*tstr = 0;

/* find the first non-white character */
		
		while ( (strchr(" 	",*str)) != NULL )
			str++;

		if ( *str != 0 && *str != comchar )
			break;
		
/* keep at it until a non-zero length line is found */
		
	}

exit:
	return( ret );
}
//E*O*F MUGETLIN.C//

echo x - MULEX.C
cat > "MULEX.C" << '//E*O*F MULEX.C//'
/*	
	mulex : lex routines.
	ROUTINES :
	cnt =	mu_lex( token list, delimiter list, lex list, lex size, buf )
			Token list is alphabetized. Delimiter list
			is a string of single characters. if string
			in buf causes non unique match then string is
			considered unmatched.
	token =	mu_astrs( string, token list )
			Returns token value from token list or -1/-2 if
			not found/ambigous (DO NOT USE A -1 or -2 TOKEN
			VALUE ).
				
	88/09/06 : MAG created
		
*/

#include <stdio.h>
#include <string.h>
#include "mutil.h"

/*--------------------------------------------------------------*/
/*	mu_lex( tokstrc, delimlist, buf, lex )			*/
/*--------------------------------------------------------------*/

mu_lex ( tok, delim, lex, lsize, buf )
LEX tok[], lex[];
char *delim, *buf;
int lsize;
{
	char *tptr, *eptr;
	int blen,tkn,lidx,tlen;

	tptr = buf;
	eptr = tptr+strlen(buf);
	lidx = 0;

	while ( tptr < eptr ) {
		
/* skip any leading delimiters, save the pointer in the lex structure */
		
		while ( (strchr(delim,*tptr)) != NULL )
			tptr++;
		lex[lidx].str = tptr;
		
/* find the length of the tokenizable string */
		
		tlen = (int)strcspn(tptr,delim);
		tptr[tlen] = 0;

/* find the string in the token list */

		lex[lidx++].val = mu_astrs(tok,tptr);
		if ( lidx >= lsize )
			break;
		
/* next string */
		
		tptr += (tlen+1);
	}

	return( lidx );
}


/*--------------------------------------------------------------*/
/*	token =	mu_astrs( string, token list )			*/
/*--------------------------------------------------------------*/

mu_astrs ( tok, str )
char *str;
LEX tok[];
{
	int i,c1,c2,ret;

	i = 0;
	while ( tok[i].str != NULL ) {
	
		c1 = strnicmp(tok[i].str,str,strlen(str));
		
/* switch on compare results */
		
		switch ( c1 ) {
			case -1 :
				i++;
				break;
			
			case 0 :
				c2 = strnicmp(str,tok[i+1].str,strlen(str));
				if ( c2 )
					ret = tok[i].val;
				else
					ret = -2;
				
				goto exit;
				break;
				
			case 1 :
				ret = -1;
				goto exit;
				break;
		}
	}
	ret = -1;
	
exit :
	return( ret );
}
//E*O*F MULEX.C//

echo x - MUSWAP.C
cat > "MUSWAP.C" << '//E*O*F MUSWAP.C//'
mu_swab_ip ( ptr, cnt )
char *ptr;
int cnt;
{
	char *a,*b,*e, c;
	int ret;
	
/* gots to be even */
	
	cnt &= 0xfffe;
	
/* swap in place */
	
	a = ptr;
	b = a+1;
	e = ptr+cnt;
	
	while ( a < e ) {
		c = *a;
		*a++ = *b;
		*b++ = c;
		a++;
		b++;
	}
	
exit:
	return( cnt );
}


mu_swaw_ip ( ptr, cnt )
short *ptr;
int cnt;
{
	short *a,*b,*e, c;
	int ret;
	
/* gots to be even */
	
	cnt &= 0xfffe;
	
/* swap in place */
	
	a = b = ptr;
	b++;
	e = ptr+cnt;
/*printf("ptr-%8lx  cnt-%d a-%8lx  b-%8lx  e-%8lx\n",ptr,cnt,a,b,e);	*/
	while ( a < e ) {
		c = *a;
		*a++ = *b;
		*b++ = c;
		a++;
		b++;
	}
	
exit:
	return( cnt );
}
//E*O*F MUSWAP.C//

echo x - MUTIL.H
cat > "MUTIL.H" << '//E*O*F MUTIL.H//'
/*--------------------------------------------------------------*/
/*								*/
/*    MUTIL.H : Utility include file.				*/
/*								*/
/*--------------------------------------------------------------*/

typedef struct {
	char *str;
	int val;
} LEX;

/* procedure defs */

char *mu_alloc_buf();
long mu_buf_len();

//E*O*F MUTIL.H//

echo x - SRCFMT.C
cat > "SRCFMT.C" << '//E*O*F SRCFMT.C//'
/*
	srcfmt.c
		
	Determine the input file format type. Return the file pointer to
	the beginning of the file.
		
*/
#include <io.h>
#include <stdio.h>
#include <string.h>
#include "gfc.h"
#include "gfcglob.h"

extern errno;

source_format()
{
	int ramt;
	
/* read first 100 bytes, rewind */
	
	if ( (ramt = read(Ifd,Bb,100)) < 0 ) {
		muerr(errno,"Error during source_format read.\n");
		exit();
	}
	lseek(Ifd,0L,SEEK_SET);

/* look for TIFF */
	
	if ( strncmp("II",Bb,2) == 0 || strncmp("MM",Bb,2) == 0 )
		return(TIFF);
	
/* look for TARGA and VISTA(TARGA24) */
	
	if ( Bb[1] == 0 && Bb[2] == 2) {
		if ( Bb[16] == 24 )
			return(VISTA);
		else
			return(TARGA);
	}
	
/* don't know it */
	
	return(-1);
}
//E*O*F SRCFMT.C//

echo x - TARGA.C
cat > "TARGA.C" << '//E*O*F TARGA.C//'
/*
	targa.c
		
	Parser for TARGA format files.
		
*/
#include <stdio.h>
#include <gfc.h>
#include <gfcglob.h>


static struct {
	char	idsiz;
	char	clrmaptype;
	char	imagetypecode;
	char	clrmapspec[5];
	int	llx;
	int	lly;
	int	xdim;
	int	ydim;
	char	pixsiz;
	char	imagedesc;
	char	imageid[1];
} T;


targa(ofn)
char *ofn;
{



	if ( Dump )  tga_dmp();
	else tga_parse(Ifd,ofn);
}

tga_dmp()
{
		read(Ifd,&T,sizeof(T));
		strncpy(Bb,T.imageid,T.idsiz);
		Bb[T.idsiz] = 0;
		printf("TARGA file type 2 dump.\n\n");
		printf("File id : %s\n",Bb);
		printf("Image type code : %d\n",T.imagetypecode);
		printf("X origin : %d\n",T.llx);
		printf("Y origin : %d\n",T.lly);
		printf("X dim : %d\n",T.xdim);
		printf("Y dim : %d\n",T.ydim);
		printf("Bits per pixel : %d\n",T.pixsiz);
		printf("Image descriptor : 0x%x\n",T.imagedesc);
}//E*O*F TARGA.C//

echo x - TGAGEN.C
cat > "TGAGEN.C" << '//E*O*F TGAGEN.C//'
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <string.h>
#include <gfc.h>
#include <tiffgen.h>
#include <ttcnv.h>
#include <gfcglob.h>


extern errno;
extern char Wbuf[];
static	TGA tif_tga;
static int Motor;

tga_open(ofn, bord)
char *ofn;
int bord;
{
		
	if (( Ofd = open( ofn, OPEN_MODE, OPEN_ACCESS )) < 0 ) {
		printf("Cannot create output file : %s\n",ofn);
		exit(0);
	}
	
/* check byte order */
	
	if  ( bord == INTEL )
		Motor = 0;
	else if ( bord == MOTOROLA )
		Motor = 1;
	else {
		printf("Illegal byte order specifier : %d\n",bord);
		exit(0);
	}	
}

tga_entry(data_type,field,value)
unsigned char data_type;
int field;
unsigned short value;
{
	
	
	switch (data_type) {
		case 1:
		case 10:
		case 11:			
			printf(" Targa data type is not supported\n");
		
			exit(0);
		case 2:
/* Set the default fields of the Targa file data type 2 */
			set_t2_def();   
			if (field == IMAGE_WIDTH) tif_tga.wi = value;
			else if (field == IMAGE_LENGTH) tif_tga.hi = value;
			else if (field == IM_PIX_SIZE) tif_tga.ips = (unsigned char)value;
			else {
				printf("tga_entry....incorrect parameter\n");
				exit(0);
			}
			break;
		}

}

set_t2_def()
{
	tif_tga.ncif = 0;
	tif_tga.cmt  = 0;
	tif_tga.itc =  2;
	tif_tga.cms[0] = tif_tga.cms[1] = tif_tga.cms[2] = tif_tga.cms[3]= tif_tga.cms[4] = 0;
	tif_tga.x_org = 0;
	tif_tga.y_org = 0;
	tif_tga.idb =   0;
}
tga_close(offset,fsize)
long offset;
long fsize;
{
	int wamt, avl, ramt;
	long position;
	printf("size of TGA = %d\n",sizeof(TGA));
	
	if (wamt = write(Ofd,&tif_tga,sizeof(TGA) - 6) != (sizeof(TGA) - 6 )) {
		printf("TARGA header write error : %d\n",errno);
		exit(0);
	}
	position = lseek(Ifd,offset,SEEK_SET);
	while (fsize){
		avl = ( fsize < WBUFSIZ ? (int)fsize : WBUFSIZ);
		
		if ((ramt=read(Ifd,Wbuf,avl)) != avl) {
			printf("TIFF File data read error : %d\n",errno);
			exit(0);
		}
/*		mu_swab_ip(Wbuf,avl);*/
		
		if ((wamt = write(Ofd,Wbuf,avl)) != avl) {
			printf("TARGA Image data write error : %d\n",errno);
			exit(0);
		}
		fsize -= (long)avl;
	}
}
//E*O*F TGAGEN.C//

echo x - TGA_PARS.C
cat > "TGA_PARS.C" << '//E*O*F TGA_PARS.C//'
#include <stdio.h>
#include "\dcf\dev\include\gfc.h"
#include "\dcf\dev\include\tiffgen.h"
#include "\dcf\dev\include\gfcglob.h"
#include "\dcf\dev\include\ttcnv.h"

tga_parse(ifd,ofn)
int ifd;
char *ofn;
{

	int i1, i, i2, i3, dir;
	long image_size, l, x_res[2], y_res[2];
	TGA	tga;
/*Field Bit Length */
	unsigned short fbl[3];	
	
	read(Ifd,&tga,sizeof(tga));
/* Image Identification field is normally empty */
	strncpy(Bb,tga.iidf,tga.ncif);
	Bb[tga.ncif] = 0;
		
/* this is equivalent to bits per sample in tiff format */
/* For RGB files we have 3 samples (R,G,B) per pixel; if tgs.idb is greater than zero, we have essentially 4 samples per pixel */	
/* For targa 24 the fbl should equal 8, as in 8 bits per sample */
	fbl[0] = fbl[1] = fbl[2] = (tga.ips - (tga.idb & 0xF)) / 3; 	
	
/* Now, create a tiff file */
	
	tiff_open(ofn,MOTOROLA);
	i = 1;
	tiff_entry(dir, SubfileType, TIF_SHORT, &i, 1L, -1);

	tiff_entry(dir, ImageWidth, TIF_SHORT, &tga.wi, 1L, -1);
	tiff_entry(dir, ImageLength, TIF_SHORT, &tga.hi, 1L, -1);
	tiff_entry(dir, BitsPerSample, TIF_SHORT, fbl, 3L, -1);
	tiff_entry(dir, Compression, TIF_SHORT, &i, 1L, -1);
	i2 = 2;
	tiff_entry(dir, PhotometricInterpretation, TIF_SHORT, &i2, 1L, -1);
/* for 3 samples per pixel */
	i1 = 3;	
	tiff_entry(dir, SamplesPerPixel, TIF_SHORT, &i1, 1L, -1);
	i3 = 4;
	tiff_entry(dir, Orientation, TIF_SHORT, &i3, 1L, -1);
	/* Default x resolution for LaserPaint is found by multiplying 72 (pixels per inch) by image width */
	x_res[0] = 72 * tga.wi;
	x_res[1] = tga.wi;
	tiff_entry(dir, XResolution, TIF_RATIONAL, x_res, 1L, -1);
/* Default y resolution for LaserPaint is found by multiplying 72 (pixels per inch) by image heigth */
	y_res[0] = 72 * tga.hi;
	y_res[1] = tga.hi;
	tiff_entry(dir, YResolution, TIF_RATIONAL, y_res, 1L, -1);

	tiff_entry(dir, PlanarConfiguration, TIF_SHORT, &i, 1L, -1);
	image_size = (long)tga.wi * (long)tga.hi; 
/*image size in bits */
	image_size *= (long)tga.ips;
/* Divide by 8 to get image size in bytes */
	image_size = image_size >> 3;
	tiff_strip(dir, TIF_BYTE, 18L, image_size, ifd);
	tiff_close();
}//E*O*F TGA_PARS.C//

echo x - TIFF.C
cat > "TIFF.C" << '//E*O*F TIFF.C//'
/*
	tiff.c
		
	Parser for TIFF format files.
		
*/
#include <stdio.h>
#include <malloc.h>
#include <gfc.h>
#include <gfcglob.h>
#include <ttcnv.h>

IFD 	ifd;
unsigned char type_size[5];
unsigned char	*val_buf;
extern	char *tag_txt[];
tiff(ofn)
char *ofn;
{
	TFHDR	tfhdr;
	DIR_ptr	dir;

	int i,j, value;
	long position, len, cnt;
	unsigned short *sbuf;
	long *lbuf,offset;
	char	*buf, data_type = 2;
	read(Ifd,&tfhdr,sizeof(tfhdr));

	type_size[0] = type_size[1] = 1;
/* Two byte for short */
	type_size[2] = 2;	
/* Four bytes for long */
	type_size[3] = 4;
/* 8 bytes for double */
	type_size[4] = 8; 
	
	if ( Dump ) printf("TIFF file dump.\n\n");
	else tga_open(ofn,INTEL); /* targa file on PCs only */
	buf = (char *)(&(tfhdr));

	if(tfhdr.byor == 0x4D4D){	/* Motorolla */
		/* Order of bytes must be reversed per word */
		mu_swab_ip(&(tfhdr.byor),8);
		swap_w(&(tfhdr.ifd));
	}
	if (Dump) {
		printf("Byte order = %c\n",tfhdr.byor);
		printf("Version = %d\n",tfhdr.version);
	}
		/* got to the beginning of the IFD */

	/*printf("tfhdr.ifd = %lx\n",tfhdr.ifd);*/
	
	position = lseek(Ifd,tfhdr.ifd,SEEK_SET);
	read(Ifd,&ifd, 2);
	if (tfhdr.byor == 0x4D4D)
	mu_swab_ip(&(ifd.ent_cnt),2);

/*multiply by sixteen by shifting the entry count 4 times */
	if (Dump) printf("ifd.ent_cnt = %d\n",ifd.ent_cnt);

	len = ifd.ent_cnt << 4;
/* Then subtract it from the entry count shifted twice, i.e. entry count is multiplied by 4 */
/* this is effectively multiplying the entry count by 12 */
	len -= ifd.ent_cnt << 2;	
/*printf("len = %d\n",len);*/
	read(Ifd,&(ifd.dir[0]),len);
	if (tfhdr.byor ==0x4D4D)
		prep_ifd(&ifd,len);
		
	dir = (DIR_ptr)(&(ifd.dir[0]));

	for(i=0;i<ifd.ent_cnt;i++){

		j = i * 12;
		dir = (DIR_ptr)(&(ifd.dir[j]));
		if (Dump) {	
			printf("\n\nContents of Directory entry %d are:\n",i+1);
			printf("%s:   ",tag_txt[dir->tag - 254]);
			printf("Tag = %d\n",dir->tag);

			printf("Type = %d\n",dir->type);

			printf("Length = %lx\n",dir->len);
			printf("Value Offset = %lx\n",dir->value);
		}
		else {
			switch (dir -> tag) {
				case 256 :	 /* Image Width */
					tga_entry ( data_type, IMAGE_WIDTH, dir->value);
					break;
				case 257 : 	/*Image Length */
					tga_entry (data_type, IMAGE_LENGTH, dir->value);
					break;
				case 273:
					offset = (long)(dir -> value);
					break;
				case 279:
					tga_close(offset,dir->value);
					break;
			}
		}
				
				
				
				
		cnt = dir->len * type_size[dir->type - 1];
		if(cnt > 4 ){
		   if(tfhdr.byor == 0x4D4D)
			   prep_val(dir);
		if (Dump) {
		   switch(dir->type){
			   case 1:
			   case 2:	   
				   for(j=0;j<cnt;j++)
					   printf("%x  ",val_buf[j]);

				   break;
			   case 3:
				   sbuf = (unsigned short *)val_buf;
				   for(j=0;j<(cnt >> 1);j++)
					   printf("%x  ",sbuf[j]);
				   break;
			   case 4:
			   case 5:
				   lbuf = (long *)val_buf;
				   for(j=0;j<(cnt >> 2);j++)
					   printf("%lx  ",lbuf[j]);
				   break;
			}
		   printf("\n");		
		   
		   }
		   else {
			   if (dir -> tag == 258) { /* Bits per Sample */
				   sbuf = (unsigned short *)val_buf;
				   value = sbuf[0] + sbuf[1] + sbuf[2];
				   printf("image pixel size = %x\n",value);
				   tga_entry (data_type,IM_PIX_SIZE,value);

				   
			   }
	
		   }
	   }
   }
}

swap_w(w)
long *w;
{
	long tmp1, tmp2;
	tmp1 = (long)(*w >> 16) & 0xFFFF;
	tmp2 = (long)(*w << 16);
	*w = tmp1 | tmp2;
}
prep_ifd(tifd,len)
IFD_ptr tifd;
long len;
{
	int i,j;
	unsigned short cnt;
	DIR_ptr	dir;
	long position;
	long *bufptr;
	for(i=0;i<tifd->ent_cnt;i++){
/*		j = i * tifd->ent_cnt;*/
		j = i * 12;
		dir = (DIR_ptr)(&(tifd->dir[j]));
		
/* Swap the Tag, Type, Length, and Value Offset
   fields of this directory entry */
		mu_swab_ip(dir,8);
		if(dir->type > 2)
			mu_swab_ip(&(dir->value),4);

/* Now, swap the words in the length field */
		swap_w(&(dir->len));
		cnt = dir->len * type_size[dir->type - 1];
/* Swap if type is long or rational */
		if(cnt >= 4 && dir->type > 3)  
			swap_w(&(dir->value));
/* Take care if pointer */
		else if (cnt > 4 ) swap_w(&(dir->value));

	}
}
prep_val(dir)
DIR_ptr dir;
{
	long position;
	unsigned short cnt;
	long *bufptr;
	int j;
	cnt = dir->len * type_size[dir->type - 1];
	position = lseek(Ifd,dir->value,SEEK_SET);
	val_buf = (unsigned char *)malloc(cnt);
	read(Ifd,val_buf,cnt);

			if(dir->type > 2){
				mu_swab_ip(val_buf,cnt);
/* long or rational */
				if(dir->type > 3){
					bufptr = (long *)val_buf;
					for(j=0;j<(cnt >> 2); j++)
					swap_w(&bufptr[j]);

				}
			}

}
//E*O*F TIFF.C//

echo x - TIFFGEN.C
cat > "TIFFGEN.C" << '//E*O*F TIFFGEN.C//'
/*
	tiffgen.c:
		tiff_open : opens tiff file.
		tiff_ifd : NON FUNCTIONAL : adds IFD's to tiff file
		tiff_entry : adds entries to IFD
		tiff_strip : adds strip data
		tiff_close : preps and writes out tiff file. closes.
		
	Graphics file format converter. Only does TARGA24(aka VISTA) and
	TIFF24 formats.


	89/ 3/20 : M.Guzman created

*/
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <string.h>
#include "gfc.h"
#include "tiffgen.h"
#include <gfcglob.h>

/* from here on stays in this file */

#define ESIZ		1024
#define ECNT		30
#define SCNT		30
#define MM		0x4d4d
#define II		0x4949
#define STRIPOFFS	273
#define STRIPBYTES	279

static char Ts[6] = { 0,1,1,2,4,8 };

#define TIFLOTAG	254
#define TIFHITAG	320
#define TIFLOTYP	TIF_BYTE
#define TIFHITYP	TIF_RATIONAL

/* global storage of passed data */

static char Ofn[13];
static int Motor, Ofd;

/* internal tiff data structures */

typedef struct {
	int	bord;
	int	vers;
	long	iofs;
} TIFHDR;

typedef struct {
	int	tag;
	int	typ;
	long	len;
	long	vofs;
} TE;

typedef struct {
	TE	e;
	int	vfd;
	int	usevo;
} TIFENT;

typedef struct {
	int	svfd[SCNT];
	int	styp[SCNT];
	long	sptr[SCNT];
	long	slen[SCNT];
} STRIP;

static TIFHDR H;
static TIFENT E[ECNT];
static STRIP S;
static int Ecnt, Scnt, Eswitch;
extern errno;
extern char Wbuf[];
/*--------------------------------------------------------------*/
/*	open_tiff : create a tiff file				*/
/*--------------------------------------------------------------*/

tiff_open( ofn, bord )
char *ofn;
int bord;
{
	
/* open output file */
	
	if (( Ofd = open( ofn, OPEN_MODE, OPEN_ACCESS )) < 0 ) {
		printf("Cannot create output file : %s\n",ofn);
		exit(0);
	}
	
/* check byte order */
	
	if  ( bord == INTEL )
		Motor = 0;
	else if ( bord == MOTOROLA )
		Motor = 1;
	else {
		printf("Illegal byte order specifier : %d\n",bord);
		exit(0);
	}	
	
/* fill in tiff header  */
	
	if ( Motor )
		H.bord = MM;
	else
		H.bord = II;
	H.vers = 42;
	H.iofs = (long)sizeof(H);
	
/* init entry counter, strip counter */
	
	Ecnt = Scnt = Eswitch = 0;

/* no return value */
	
}

/*--------------------------------------------------------------*/
/*	tiff_ifd :  add ifd to file				*/
/*--------------------------------------------------------------*/

tiff_ifd()
{
/* does nothing for now. reserved for the future */
}

/*--------------------------------------------------------------*/
/*	tiff_entry : add directory entry to ifd(default 0)	*/
/*--------------------------------------------------------------*/

tiff_entry( dir, tag, typ, vptr, len, vfd)
char *vptr;
int dir, tag, typ, vfd;
long len;
{
	long tot;
	
/* dir check : for the future, ignore dir for now */
	
/* entry check */

	if ( Ecnt >= ECNT ) {
		printf("Too many directory entries : >= %d\n",Ecnt+1);
		exit(0);
	}

/* STRIPOFFSETS & STRIPBYTECOUNTS are not legal, we do them ourselves later */
	
	if ( !Eswitch && (tag == STRIPOFFS || tag == STRIPBYTES) ) {
		printf("StripOffsets or StripByteCount fields not allowed\n");
		exit(0);
	}
		
/* sanity check */
	
	if ( tag < TIFLOTAG || tag > TIFHITAG ) {
		printf("Bad tag value : %d\n",tag);	
		exit(0);
	}
	
	if ( typ < TIFLOTYP || typ > TIFHITYP ) {
		printf("Bad type value : %d\n",typ);
		exit(0);
	}

/* round up len in case we are pointing to a old length char string */
	
	if ( typ == TIF_ASCII || typ == TIF_BYTE )
		len = 0xfffffffe & (len+1);
	
/* save data */

	E[Ecnt].e.tag = tag;
	E[Ecnt].e.typ = typ;
	E[Ecnt].e.len = len;
	E[Ecnt].vfd = vfd;
	
/* entry data bytes, maybe use tiff value offset field for data */
	
	tot = len * (long)Ts[typ];
	if ( tot <= 4L ) {
		E[Ecnt].usevo = 1;
		E[Ecnt].e.vofs = 0L;
		memmove(&E[Ecnt].e.vofs,vptr,(size_t)tot);
	}
	else {
		E[Ecnt].usevo = 0;
		E[Ecnt].e.vofs = (long)vptr;
		printf("Entry(%d:%d) pointer to data %lx\n",Ecnt,tag,vptr);
	}
	
/* increment entry, no return value */

	Ecnt++;
}

/*--------------------------------------------------------------*/
/*	tiff_strip : save info about image data			*/
/*--------------------------------------------------------------*/

tiff_strip( dir, typ, ptr, len, vfd )
int dir, vfd, typ;
char *ptr;
long len;
{
	
/* check for overflow */
	
	if ( Scnt > SCNT ) {
		printf("Exceeded internal TIFF strip storage : %d\n",Scnt);
		exit(0);
	}

/* save the data */	

	S.svfd[Scnt] = vfd;
	S.styp[Scnt] = typ;
	S.sptr[Scnt] = (long)ptr;
	S.slen[Scnt++] = len * (long)Ts[typ];
	
}

/*--------------------------------------------------------------*/
/*	tiff_close : write out tiff file			*/
/*--------------------------------------------------------------*/

tiff_close()
{
	int wamt, i, j, soindex, sousevo;
	long vofs, ptmp, dirsiz, bytes, total;
	TE *eptr, *soptr;

/* generate a couple of entries for the image strips */

	Eswitch = 1;
	tiff_entry( 0, STRIPBYTES, TIF_LONG, &S.slen[0], (long)Scnt, -1);
	tiff_entry( 0, STRIPOFFS,  TIF_LONG, &S.sptr[0], (long)Scnt, -1);
	
	printf("Entry count = %d\n",Ecnt);
	
/* maybe swap and write the TIFF header */
	
	if ( Motor )
		swap_header(&H);
	
	if ( (wamt = write(Ofd,&H,sizeof(H))) != sizeof(H)) {
		printf("TIFF header write error : %d\n",errno);
		exit(0);
	}
	
/* move in entry count and maybe swap it */
	
	memmove(Wbuf,&Ecnt,(size_t)2);
	if ( Motor )
		mu_swab_ip(Wbuf,2);

/* build the ifd. scan through the fields finding succsessive tag values */
/*   this really should be a sort but we are doing it brute force. some of */
/*   the data has been put into the value offset field already, just shove */
/*   those into output buffer, else calc a ptr to it for writing later on */


/* point to first entry pos, calc first entry value offset, init total */
	
	eptr = (TE *)&Wbuf[2];
	dirsiz = (sizeof(TE)*Ecnt)+6;
	vofs = dirsiz + sizeof(TIFHDR);

	for ( i=TIFLOTAG; i<=TIFHITAG; i++ ) {
		if ( (j = match_entry(i)) < 0 )
			continue;
		
/* found a tag. move it into the output buff */

		eptr->tag = E[j].e.tag;
		eptr->typ = E[j].e.typ;
		eptr->len = E[j].e.len;
		eptr->vofs = E[j].e.vofs;
		
/* if data is in vofs, processing for this entry is done, kill it */
		
		if ( E[j].usevo ) {
			E[j].e.tag = 0;
		}

/* calc new pointer into final file for data pointed to or in some file */

		else {		
			eptr->vofs = vofs;
			vofs += (eptr->len * Ts[eptr->typ]);
		}

/* maybe swap all entries except StripOffsets, remember where it is */

		if ( eptr->tag != STRIPOFFS )
			swap_entry(eptr,E[j].usevo);
		else {
			soindex = j;
			soptr = eptr;
			sousevo = E[j].usevo;
		}
		
/* next entry */
		eptr++;
	}

/* if the StripOffsets entry has only one value it is stored in the value */
/* offset field so update that value now before the ifd is written. the */
/* image data will be found after the entry value part of the tiff file */
	
	if ( E[soindex].usevo )
		soptr->vofs = vofs;
	else {
		for (i=0; i<Scnt; i++ )  {
			j = S.slen[i];
			S.slen[i] = vofs;
			vofs += j;
		}
	}
	
/* maybe swap the StripOffsets entry */

	if ( Motor )
		swap_entry(soptr,sousevo);
		
/* now we write out the ifd */
	
	if ( (wamt = write(Ofd,Wbuf,dirsiz)) != dirsiz) {
		printf("TIFF IFD write error : %d\n",errno);
		exit(0);
	}

/* scan and process data, only intact tag entries will show up */

	for ( i=TIFLOTAG; i<=TIFHITAG; i++ ) {
		if ( (j = match_entry(i)) < 0 )
			continue;

/* data should be pointed at or in a file */
		
		bytes = E[j].e.len * (long)Ts[E[j].e.typ];
		if ( E[j].vfd < 0 )
			process_vofs(E[j].e.tag,E[j].e.typ,E[j].e.vofs,
				bytes);
		else
			process_vdf(E[j].e.tag,E[j].e.typ,E[j].vfd,
				E[j].e.vofs,bytes);
	}
	
/* write out image data */
	
	for ( j=0; j<Scnt; j++ ) {
		if ( S.svfd[j] < 0 )
			process_sptr(S.styp[j],S.sptr[j],S.slen[j]);
		else
			process_svfd(S.styp[j],S.svfd[j],S.sptr[j],S.slen[j]);
	}

/* close file and return */
	
	close(Ofd);
	
}

static swap_header( h )
TIFHDR *h;
{
	mu_swab_ip(h,sizeof(TIFHDR));
	mu_swaw_ip(&h->iofs,2);
}

static swap_entry( e, usevo )
TE *e;
int usevo;
{
	if ( e->typ >= TIF_SHORT || !usevo )
		mu_swab_ip(&e->vofs,4);
	if ( e->typ >= TIF_LONG || !usevo )
		mu_swaw_ip(&e->vofs,2);
		
	mu_swab_ip(e,sizeof(TE)-4);
	mu_swaw_ip(&e->len,2);
}

static swap_data( typ, ptr, len )
int typ;
char *ptr;
long len;
{
	if ( typ >= TIF_SHORT )
		mu_swab_ip(ptr, len);
	if ( typ >= TIF_LONG )
		mu_swaw_ip(ptr, len/2);
}
	
static match_entry( tag )
int tag;
{
	int j, ret;
	
	ret = -1;
	for ( j=0; j<Ecnt; j++ )
		if ( E[j].e.tag == tag ) {
			ret = j;
			break;
		}

	return( ret );
}

static process_vofs( tag, typ, ptr, len )
int tag, typ;
char *ptr;
long len;
{
	int wamt, ramt, avl;
	
/* read the data in parts, maybe swap, write it out */

	printf("Tag(%d) pointer to data %lx, len(%ld)\n",tag,ptr,len);

	while ( len ) {
		avl = ( len < WBUFSIZ ? (int)len : WBUFSIZ );
		
/* move the data in */
		
		memmove(Wbuf,ptr,avl);

/* maybe swap the data */
	
		if ( Motor )
			swap_data(typ,Wbuf,avl);
	
/* write it out */
	
	if ((wamt=write(Ofd,Wbuf,avl)) != avl){
		printf("TIFF Entry(%d) data write error : %d\n",tag,errno);
		exit(0);
	}
	
/* reduce count */
	
		len -= (long)avl;
	}
}

static process_vdf( tag, typ, fd, ofs, len )
int tag, typ, fd;
long ofs, len;
{
	int wamt, avl, ramt;
	
/* read the data in parts, maybe swap, write it out */
	
	while ( len ) {
		avl = ( len < WBUFSIZ ? (int)len : WBUFSIZ );
		
/* read the data in */
		
		if ((ramt=read(fd,Wbuf,avl)) != avl){
			printf("TIFF Entry(%d) data read error : %d\n",
				tag,errno);
			exit(0);
		}

/* maybe swap the data */
	
		if ( Motor )
			swap_data(typ,Wbuf,avl);
	
/* write it out */
	
		if ((wamt=write(Ofd,Wbuf,avl) != avl)){
			printf("TIFF Entry(%d) data write error : %d\n",
				tag,errno);
			exit(0);
		}
	
/* reduce count */
	
		len -= (long)avl;
	}
}

static process_sptr( typ, ptr, len )
int typ;
char *ptr;
{
	int wamt, ramt, avl;
	
/* read the data in parts, maybe swap, write it out */
	
	while ( len ) {
		avl = ( len < WBUFSIZ ? (int)len : WBUFSIZ );
		
/* move the data in */
		
		memmove(Wbuf,ptr,avl);

/* maybe swap the data */
	
		if ( Motor )
			swap_data(typ,Wbuf,avl);
	
/* write it out */
	
	if ((wamt=write(Ofd,Wbuf,avl)) != avl){
		printf("TIFF Image data write error : %d\n",errno);
		exit(0);
	}
	
/* reduce count */
	
		len -= (long)avl;
	}
}

static process_svfd( typ, fd, ofs, len )
int typ, fd;
long ofs, len;
{
	int wamt, avl, ramt;
	
/* read the data in parts, maybe swap, write it out */
	
	while ( len ) {
		avl = ( len < WBUFSIZ ? (int)len : WBUFSIZ );
		
/* read the data in */
		
		if ((ramt=read(fd,Wbuf,avl)) != avl){
			printf("TIFF Image data read error : %d\n",errno);
			exit(0);
		}

/* maybe swap the data */
	
		if ( Motor )
			swap_data(typ,Wbuf,avl);
	
/* write it out */
	
		if ((wamt=write(Ofd,Wbuf,avl) != avl)){
			printf("TIFF Image data write error : %d\n",errno);
			exit(0);
		}
	
/* reduce count */
	
		len -= (long)avl;
	}
}
//E*O*F TIFFGEN.C//

echo x - TIFFGEN.H
cat > "TIFFGEN.H" << '//E*O*F TIFFGEN.H//'
/* byte order */

#define MOTOROLA	1
#define INTEL		0

/* tiff types */

#define TIF_BYTE	1
#define TIF_ASCII	2
#define TIF_SHORT	3
#define TIF_LONG	4
#define TIF_RATIONAL	5
//E*O*F TIFFGEN.H//

echo x - TT.C
cat > "TT.C" << '//E*O*F TT.C//'
static char *id = "$header : v1.0 experimental screen compiler\n";

/*	scmain.c : Main routine for screen compiler.

	88/ 8/17 : MAG created
		
*/

#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "sc.h"
#include "scglob.h"
#include "acrtc.h"
#include "string.h"

main ( argc, argv )
int argc;
char *argv[];
{
	char *titleptr, ofn[15], *pptr;
	int fret, ofd, ifd, ofdi, ifdi, i;
	
/* init */
	
	mu_error_init("err.cfg");
	
/* check for help */
	
	if ( argc < 2 ) {
		printf("usage : sc infile [outfile] [- ]\n\n");
		exit(0);
	}

/* process switches and find file names */

	titleptr = ".. none ..";
	ifdi = ofdi = 0;
	for ( i=1; i<argc; i++ ) {
		if ( argv[i][0] == '-' ) {
			switch( (int)argv[i][1] ) {

			case 't' :
				titleptr = argv[i+1];
				i++;
				break;
							
			default :
				printf("Illegal switch : -%c\n",argv[i][1]);
				break;
			}
		}
		else {
			if ( !ifdi )
				ifdi = i;
			else {
				if ( !ofdi )
					ofdi = i;
			}
		}
	}

/* open files */
	
	if ( ifdi ) {
		if ( (ifd = open(argv[ifdi], O_BINARY | O_RDONLY)) < 0 ) {
			printf("Cannot open input file : %s\n",argv[ifdi]);
			exit(0);
		}
	}
	else {
		printf("Missing input file name.\n");
		exit(0);
	}

/* build output file name */

	if ( ofdi )
		strcpy(ofn,argv[ofdi]);
	else {
		strcpy(ofn,argv[ifdi]);
		if ( (pptr = strchr(ofn,'.')) != NULL )
			strcpy(pptr,".m");
		else
			strcat(ofn,".m");
	}

	if ( !((int)strcmp(ofn,argv[ifdi])) ) {
		printf("Input and output filenames match!\n");
		exit(0);
	}
		
	if (( ofd = open(ofn,O_CREAT|O_RDWR|O_BINARY|O_TRUNC, S_IREAD|S_IWRITE))<0) {
		printf("Cannot create output file : %s\n",argv[ofdi]);
		exit(0);
	}
	
/* init buffers */
	
	mgd_obuf_init();

/* test */

	jy_test();
	
/* output file */
	
	if ( !(fret = setjmp(Jbuf)) )
		sc_output_file( ofd, titleptr );
	else 
		printf("Cannot write to output file : %s\n",ofn);
			
/* clean up */
	
	close(ifd);
	close(ofd);
	exit(0);
}

//E*O*F TT.C//

echo x - TTCNV.H
cat > "TTCNV.H" << '//E*O*F TTCNV.H//'
typedef struct {
	unsigned char	ncif,	/*Number of Characters in Identification Filed */
			cmt,	/* Color Map Type */
			itc,	/* Image type Code */
			cms[5];	/* Color Map Specification */
	unsigned short	x_org,	/* Lower Left Corner of the  Image */
			y_org,
			wi,	/* Width of Image */
			hi;	/* Heigth of Image */
	unsigned char	ips;	/* Image Pixel Size */
	unsigned char	idb;	/* Image Descriptor Byte */
	unsigned char	iidf[1];/* Image Identification Field */
/*	Color Map Data has 0-Bytes */
	unsigned char	*idf;	/* Image Data Field */
} TGA, *TGA_ptr;

typedef struct {
	unsigned short ent_cnt;   /* entry count */
	char dir[10000];
} IFD, *IFD_ptr;

typedef struct {
	unsigned short	tag;
	unsigned short	type;
	long 		len;
	long		*value;
} DIR, *DIR_ptr;

typedef struct {
	unsigned short byor;	/* byte order */
	unsigned short version;
	IFD *ifd;
}TFHDR, *TFHDR_ptr;

#define	NewSubfileType	254

#define SubfileType	255

#define ImageWidth	256

#define ImageLength	257

#define BitsPerSample	258

#define Compression	259

#define	PhotometricInterpretation	262

#define Threshholding	263

#define CellWidth	264

#define CellLength	265

#define	FillOrder	266
			
#define DocumentName	269

#define	ImageDescription	270

#define	Make		271

#define Model		272

#define	StripOffsets	273

#define	Orientation	274
			
#define SamplesPerPixel 277

#define	RowsPerStrip	278

#define	StripByteCounts	279

#define MinSampleValue	280

#define	MaxSampleValue	281

#define	XResolution	282

#define	YResolution	283

#define	PlanarConfiguration	284

#define	PageName	285

#define	XPosition	286

#define	YPosition	287

#define	FreeOffsets	288

#define	FreeByteCounts	289

#define	GrayResponseUnit	290

#define	GrayResponseCurve	291

#define	Group3Options	292

#define	Group4Option	293

#define	ResolutionUnit	296

#define	PageNumber	297

#define	ColorResponseCurves	301

#define	Software	305

#define	DateTime	306

#define	Artist		315

#define	HostComputer	316

#define	Predictor	317

#define	WhitePoint	318

#define	PrimaryChromaticities	319

#define	ColorMap	320
//E*O*F TTCNV.H//

echo x - arch.shar
cat > "arch.shar" << '//E*O*F arch.shar//'
//E*O*F arch.shar//

exit 0