ftp.nice.ch/pub/next/graphics/convertors/tifftoeps.README

This is the README for tifftoeps.c [Download] [Browse] [Up]

From uucp Thu Feb 22 03:31 PST 1990
>From uunet!watmath!ccng.waterloo.edu!rheiger  Thu Feb 22 01:28:57 1990 remote from dbi
Received: from watmath.UUCP by uunet.uu.net (5.61/1.14) with UUCP 
	id AA03817; Thu, 22 Feb 90 01:38:09 -0500
Received: from ccng.waterloo.edu by watmath.waterloo.edu with SMTP
	id <AA22525>; Thu, 22 Feb 90 00:33:34 EST
Received: by ccng.waterloo.edu
	for epsilon@wet
	id <AA25527>; Thu, 22 Feb 90 00:33:28 EST
Date: Thu, 22 Feb 90 00:33:28 EST
From: "Richard H. E. Eiger" <dbi!uunet!watmath!ccng.waterloo.edu!rheiger>
Message-Id: <9002220533.AA25527@ccng.waterloo.edu>
To: wet!epsilon
Subject: tiff2eps :  modified
Return-Receipt-To: dbi!uunet!watmath!ccng.waterloo.edu!rheiger
Status: R

Hi

Many, many thanks for your tiff2eps source it came in very handy for something
I needed to do. Unfortunately I don't have a MAC and the only way I can scan
pictures is with a handy scanner on my PC (I'd rather get a scanner for my
NeXT, but it's still not out).

So I needed to read little endian tiff files and while I was at it, I
decided to include the capability to read 32773 compressed files as well.
The feature of showing some parameters above and below the eps-image is
inteded for archiving and out of curiosity (same goes for the added tags
recognized).

I was really in a hurry to get the thing working, so it's not nice code but it
works on all kind of tiff files from NeXT and PC I've tried so far.

I assume you have extended the program yourself already since you wrote it
in September. Anyway I thought you might be interested. Since I'm not
expereinced with SCCS I didn't change the id string.

You may do whatever you like with this code. I didn't want to post this on the
net since it's grown quite a bit and it's originally yours, so you decide.

What's missing:
	- color and/or alpha
	- some tags
	- graceful handling of errors and defaults
	- handling of dithering (but that's discouraged anyway)

Many thanks again.
		Richard

Richard H. E. Eiger	(Foreign student from Switzerland)
rheiger@ccng.waterloo.edu

--------------------------------------------------------------------------
/*
 * tifftoeps - convert AppleScanned .tiff file to EPSF
 * Eric P. Scott, San Francisco State University, September 1989
 *
 * Disclaimer: this is a cheap hack; it does not attempt to
 * handle arbitrary .tiff files, nor does it make use of all the
 * information available to it.  In particular, the XResolution
 * and YResolution tags are ignored.  Heck, it doesn't even
 * accept little-endian TIFF...
 *
 * Future versions may (will?) support other kinds of scanners.
 *
 * Extension by Richard H. E. Eiger (RHE^2)
 *
 * 19. Feb. 90	Code to support little-endian
 *		Code to support some more tags (ie. XRes & YRes influence PostScript !!
 *              Code to support 32773 Compression Scheme
 *              Image Info written above and below eps image (if selected at 
 *                                                             compile-time
 *                                                             ->#undef NO_INFO)
 *
 */

#include <stdio.h>
#include <string.h>
#include <assert.h>



#define LITTLE_END 1
#define BIG_END   -1

/* PS uses inch/72 units ( = mm/2.835)	*/
#define PS_metric 72

#ifdef NO_INFO
#define FONTSIZE 0
#else
#define FONTSIZE 3
#endif




int endian = 0;

static char sccsid[]="@(#)tifftoeps   1.0  (SFSU)  9/15/89";

int iwidth=0, ilen=0, invert=255, compr = 1;
long stripoff=0L, strip_b_count=0L,strips_p_image=0L;
short str_off_typ,str_b_typ;

int vsiz[6] = {{255},{sizeof(unsigned char)},{sizeof(unsigned char)},
			{sizeof(unsigned short)},{sizeof(long)},{2*sizeof(long)}};
			
struct ifdent {
	unsigned short ifd_tag;
	unsigned short ifd_type;
	long ifd_len;
	union {
		unsigned long ifd_long;
		unsigned short ifd_short[2];
		unsigned char ifd_byte[4];
	} ifd_off;
};

void quit(int rc, char *outf)
{
    extern int unlink(char *);
    
    if(strcmp(outf,"-"))
	unlink(outf);
    exit(rc);
}

#ifndef NO_INFO
unsigned char *unparen(unsigned char *s)
{
    int parcount;
    unsigned char *t,*tt;
    
    if(s == (unsigned char *)0)
	return ("");
	
    t = (char *)s;
    parcount = 0;
    while(*s++)
	if((*s == '(') || (*s == ')'))
	    parcount++;
    
    if(parcount != 0){
	s = (unsigned char *)t;
	tt = t = (unsigned char *)malloc(strlen(s)+1 + parcount);
	assert(t != (char *)0);
	while(*s){
	    if((*s == '(') || (*s == ')'))
		*t++ = '\\';
	    *t++ = *s++;
	}
	*t = '\0';
	t = tt;
	free(s);
    }
    return (t);
}
#endif /* NO_INFO */


int readid(FILE *f)
{
    long id;
    
    if(fread(&id, sizeof(id), 1, f) != 1) {
	perror("fread in readid");
	exit(1);
    }
    return (id==0x4d4d002a ? BIG_END : (id == 0x49492a00 ? LITTLE_END : 0));
}

void longfread(long *l, size_t n, FILE *f)
{
    unsigned char *from, *to;
    unsigned char buf;
    
    for(;n;n--){
	from = (unsigned char *)l;
	if(fread(l,sizeof(long),1,f) != 1) {
	    perror("fread in longfread");
	    exit(1);
	}
	if(endian == LITTLE_END){
	    to = from + sizeof(long) - 1;
	    while(from < to){
		buf = *from;
		*from++ = *to;
		*to-- = buf;
	    }
	}
	l++;
    }
}
	
void shortfread(unsigned short *l, size_t n, FILE *f)
{
    unsigned char *from, *to;
    unsigned char buf;
    
    for(;n;n--){
	from = (unsigned char *)l;
	if(fread(l,sizeof(short),1,f) != 1) {
	    perror("fread in shortfread");
	    exit(1);
	}
	if(endian == LITTLE_END){
	    to = from + sizeof(short) - 1;
	    while(from < to){
		buf = *from;
		*from++ = *to;
		*to-- = buf;
	    }
	}
	l++;
    }
}
	
int get_tiff_img_byte(FILE *f,char *ofname)
{
    static long bytes_left=0,stripstart,i,position=0;
    int c,j;
    static int curstrip=0;
    static unsigned char *unpacked=(unsigned char *)0;
    unsigned short shtemp;
    
    if(bytes_left==0){
	if(strips_p_image<=0){
	    return(EOF);
	}
	if(strips_p_image>1){
	    if (fseek(stdin, strip_b_count + curstrip * (str_b_typ==3 ? sizeof(short) :
		sizeof(long)), 0)<0L) {
		    perror("fseek");
		    quit(1,ofname);
	    }
	    if(str_b_typ==3){
		shortfread(&shtemp,1,f);
		bytes_left = (long)shtemp;
	    }
	    else{
		longfread(&bytes_left,1,f);
	    }
	}
	else{
	    bytes_left = strip_b_count;
	}
	if(strips_p_image>1){
	    if (fseek(stdin, stripoff + curstrip * (str_off_typ==3 ? sizeof(short) :
		sizeof(long)), 0)<0L) {
		    perror("fseek");
		    quit(1,ofname);
	    }
	    if(str_off_typ==3){
		shortfread(&shtemp,1,f);
		stripstart = (long)shtemp;
	    }
	    else{
		longfread(&stripstart,1,f);
	    }
	}
	else{
	    stripstart = stripoff;
	}
	if (fseek(stdin, stripstart, 0)<0L) {
		perror("fseek");
		quit(1,ofname);
	}
	strips_p_image--;
	curstrip++;
    }
    switch(compr){
    case 1:
    	c = fgetc(f);
	break;
    case 32773:
	if(position==0){
	    if(unpacked != (unsigned char *)0){
		free(unpacked);
	    }
	    unpacked = (unsigned char *)malloc(bytes_left);
	    assert(unpacked != (unsigned char *)0);
	    /* start unpacking	*/
	    i = 0;
	    while(i<bytes_left){
		c = fgetc(f);
		if(c == EOF){
		    fprintf(stderr,"Invalid TIFF-File. Missing data.\n");
		    quit(4,ofname);
		}
		if((c>=0) && (c<=127)){
		    for(j=0;j<=c;j++)
			unpacked[i++] = fgetc(f);
		}
		else{
		    if(c!=128){
			j = 1-(int)(signed char)c;
			c = fgetc(f);
			while(j--)
			    unpacked[i++] = c;
		    }
		}
	    }
	}
	c = unpacked[position++];
	break;
    default:
    	fprintf(stderr,"This error can never hapen!!\n");
	quit(5,ofname);
	break;
    }
    bytes_left--;
    return(c);
}
	    
	


int ifditemfread(struct ifdent *l, size_t n, FILE *f)
{
    long buf;
    
    for(;n;n--){
	shortfread(&(l->ifd_tag),1,f);
	shortfread(&(l->ifd_type),1,f);
	longfread(&(l->ifd_len),1,f);
	if(l->ifd_len*vsiz[l->ifd_type]<sizeof(long)){
	    switch(l->ifd_type){
	    case 1:
	    case 2:
		if(fread(&(l->ifd_off.ifd_byte[0]), sizeof(unsigned char),
			 l->ifd_len,f) !=1 ){
		    perror("fread in ifditemread");
		    return(1);
		}
		if(fread((char *)&buf,sizeof(unsigned char),
			4-l->ifd_len,f)!=4-l->ifd_len){
		    perror("fread in ifditemread");
		    return(1);
		}
    
		break;
	    case 3:
		shortfread(&(l->ifd_off.ifd_short[0]),2-l->ifd_len,f);
		if(l->ifd_len < 2)
		    shortfread((unsigned short *)&buf,1,f);
		break;
	    default:
		fprintf(stderr,"ifdfread: unsupported type %d tag %d len %d.\n",
		l->ifd_type,l->ifd_tag,l->ifd_len);
		return(2);
	    }
	}
	else {
	    longfread((long *)&(l->ifd_off.ifd_long),1,f);
	}
	l++;
    }
    return(0);
}
	

    

int main(int argc, char *argv[])
{
	register int i;
	register long value;
	long sig, ifdoff,rows_p_strip=0L;
	unsigned short ifditems,bits;
	unsigned short values[2],res_unit,cel_len,cel_wid,thresh;
	unsigned char valuec[4];
	struct ifdent *ifdp;
	char *resolname[4]={"NA","Undef.","\"","cm"};
	char *thrname[4]={"NA","line art","dithered","error diffused"};
	long xres[2],yres[2],white[2],primchrom[2],xscale,yscale;
	unsigned char *artist,*datetime,*hostcomputer,
			*imagedesc,*make,*model,*software;

	artist = datetime = hostcomputer = (unsigned char *)0;
	imagedesc = make = model = software = (unsigned char *)0;
	res_unit = 0;
	thresh = 0;
	cel_len = cel_wid = 0;
	xres[0] = xres[1] = yres[0] = yres[1] = 0L;

 	if (argc!=3) {
		fprintf(stderr, "Usage: %s tiff-file eps-file\n", *argv);
		exit(1);
	}
	if (strcmp(argv[1], "-")&&!freopen(argv[1], "r", stdin)) {
		perror(argv[0]);
		exit(1);
	}
	if (strcmp(argv[2], "-")&&!freopen(argv[2], "w", stdout)) {
		perror(argv[2]);
		exit(1);
	}
	if (!(endian = readid(stdin))) {
	    fprintf(stderr, "%s: that's not a TIFF file!\n", argv[0]);
	    quit(1,argv[2]);
	}
	longfread(&ifdoff, 1, stdin);
	if (fseek(stdin, ifdoff, 0)<0L) {
		perror("fseek");
		quit(1,argv[2]);
	}
	shortfread(&ifditems, 1, stdin);
	if (!(ifdp=(struct ifdent *)malloc(ifditems*sizeof (struct ifdent)))) {
		perror("malloc");
		quit(1,argv[2]);
	}
	if(ifditemfread(ifdp, ifditems, stdin))
	    quit(3,argv[2]);
	for (i=0;i<ifditems;i++) {
		switch (ifdp->ifd_type) {
		case 1:
		case 2:
			if(ifdp->ifd_len > 4){
			    if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
				    perror("fseek");
				    quit(1,argv[2]);
			    }
			}
			else {
			    valuec[0] = ifdp->ifd_off.ifd_byte[0];
			    valuec[1] = ifdp->ifd_off.ifd_byte[1];
			    valuec[2] = ifdp->ifd_off.ifd_byte[2];
			    valuec[3] = ifdp->ifd_off.ifd_byte[3];
			}
			break;
		case 3:
			if(ifdp->ifd_len > 2){
			    if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
				    perror("fseek");
				    quit(1,argv[2]);
			    }
			}
			else {
			    values[0]=ifdp->ifd_off.ifd_short[0];
			    values[1]=ifdp->ifd_off.ifd_short[1];
			}
			break;
		case 4:
			if(ifdp->ifd_len > 1){
			    if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
				    perror("fseek");
				    quit(1,argv[2]);
			    }
			}
			else
			    value=ifdp->ifd_off.ifd_long;
			break;
		case 5:
			if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
				perror("fseek");
				quit(1,argv[2]);
			}
			break;
		default: /* ifdp->ifd_off.ifd_long is offset */
			value=0L;	/* do The Wrong Thing(tm) */
			break;
		}
/**********     Analyze Tags *************/
		switch (ifdp->ifd_tag) {
		case 255:	/* SubfileType - not recommended (ignored)	*/
			break;
		case 256:	/* ImageWidth */
			iwidth=values[0];
			break;
		case 257:	/* ImageLength */
			ilen=values[0];
			break;
		case 258:	/* BitsPerSample */
			bits=values[0];
			break;
		case 259:	/* Compression */
			compr = values[0];
			if ((values[0]!=1) && (values[0]!=32773)) {
				fprintf(stderr, "%s: Compression=%ld\n",
					argv[1], values[0]);
				quit(1,argv[2]);
			}
			break;
		case 262:	/* PhotometricInterpretation */
			switch (values[0]) {
			case 0:
				invert=255;
				break;
			case 1:
				invert=0;
				break;
			default:
				fprintf(stderr,
					"%s: PhotometricInterpretation=%ld\n",
						 argv[0], values[0]);
				if (values[0]==5)
				    fputs("\tI don't grok alpha\n",stderr);
				quit(1,argv[2]);
				break;
			}
			break;
		case 263:	/* Thresholding - not recommended */
			thresh = values[0];
			break;
		case 264:	/* CellWidth - not recommended	*/
			cel_wid = values[0];
			break;
		case 265:	/* CellLength - not recommended	*/
			cel_len = values[0];
			break;
		case 270:	/* Image description */
			imagedesc = malloc(ifdp->ifd_len+1);
			assert(imagedesc != (unsigned char *)0);
			if(ifdp->ifd_len>4){
			    if(fread((char *)imagedesc,sizeof(unsigned char),
			    	ifdp->ifd_len,stdin) != ifdp->ifd_len){
				perror("Reading image description");
				free(imagedesc);
				imagedesc = (unsigned char *)0;
			    }
			}
			else
			    strcpy(imagedesc,ifdp->ifd_off.ifd_byte);
			if(imagedesc != (unsigned char *)0)
			    imagedesc[ifdp->ifd_len] = '\0';
			break;
		case 271:	/* Make */
			make = malloc(ifdp->ifd_len+1);
			assert(make != (unsigned char *)0);
			if(ifdp->ifd_len>4){
			    if(fread((char *)make,sizeof(unsigned char),
			    	ifdp->ifd_len,stdin) != ifdp->ifd_len){
				perror("Reading Make");
				free(make);
				make = (unsigned char *)0;
			    }
			}
			else
			    strcpy(make,ifdp->ifd_off.ifd_byte);
			if(make != (unsigned char *)0)
			    make[ifdp->ifd_len] = '\0';
			break;
		case 272:	/* Model */
			model = malloc(ifdp->ifd_len+1);
			assert(model != (unsigned char *)0);
			if(ifdp->ifd_len>4){
			    if(fread((char *)model,sizeof(unsigned char),
			    	ifdp->ifd_len,stdin) != ifdp->ifd_len){
				perror("Reading Model");
				free(model);
				model = (unsigned char *)0;
			    }
			}
			else
			    strcpy(model,ifdp->ifd_off.ifd_byte);
			if(model != (unsigned char *)0)
			    model[ifdp->ifd_len] = '\0';
			break;
		case 273:
			stripoff=(long)ifdp->ifd_type==3 ? values[0] : value;
			break;
		case 277:	/* SamplesPerPixel */
			if (values[0]!=1) {
				fprintf(stderr, "%s: SamplesPerPixel=%ld\n",
					argv[0], values[0]);
				quit(1,argv[2]);
			}
			break;
		case 278:	/* RowsPerStrip		*/
			rows_p_strip=(long)ifdp->ifd_type==3 ? values[0] : value;
			break;
		case 279:	/* StripByteCount		*/
			strip_b_count=(long)ifdp->ifd_type==3 ? values[0] : value;
			break;
		case 282:/* XResolution RATIONAL	*/
			longfread((long *)&xres,2,stdin);
			break;
		case 283:/* YResolution			*/
			longfread((long *)&yres,2,stdin);
			break;

		case 284:	/* PlanarConfiguration */
			break;

		case 296:/* Resolution Unit		*/
			res_unit = values[0];
			break;
		case 305:	/* Software */
			software = malloc(ifdp->ifd_len+1);
			assert(software != (unsigned char *)0);
			if(ifdp->ifd_len>4){
			    if(fread((char *)software,sizeof(unsigned char),
			    	ifdp->ifd_len,stdin) != ifdp->ifd_len){
				perror("Reading Software");
				free(software);
				software = (unsigned char *)0;
			    }
			}
			else
			    strcpy(software,ifdp->ifd_off.ifd_byte);
			if(software != (unsigned char *)0)
			    software[ifdp->ifd_len] = '\0';
			break;
		case 306:	/* DateTime */
			datetime = malloc(ifdp->ifd_len+1);
			assert(datetime != (unsigned char *)0);
			if(ifdp->ifd_len>4){
			    if(fread((char *)datetime,sizeof(unsigned char),
			    	ifdp->ifd_len,stdin) != ifdp->ifd_len){
				perror("Reading DateTime");
				free(datetime);
				datetime = (unsigned char *)0;
			    }
			}
			else
			    strcpy(datetime,ifdp->ifd_off.ifd_byte);
			if(datetime != (unsigned char *)0)
			    datetime[ifdp->ifd_len] = '\0';
			break;
		case 315:	/* Artist */
			artist = malloc(ifdp->ifd_len+1);
			assert(artist != (unsigned char *)0);
			if(ifdp->ifd_len>4){
			    if(fread((char *)artist,sizeof(unsigned char),
			    	ifdp->ifd_len,stdin) != ifdp->ifd_len){
				perror("Reading Artist");
				free(artist);
				artist = (unsigned char *)0;
			    }
			}
			else
			    strcpy(artist,ifdp->ifd_off.ifd_byte);
			if(artist != (unsigned char *)0)
			    artist[ifdp->ifd_len] = '\0';
			break;
		case 316:	/* HostComputer */
			hostcomputer = malloc(ifdp->ifd_len+1);
			assert(hostcomputer != (unsigned char *)0);
			if(ifdp->ifd_len>4){
			    if(fread((char *)hostcomputer,sizeof(unsigned char),
			    	ifdp->ifd_len,stdin) != ifdp->ifd_len){
				perror("Reading HostComputer");
				free(hostcomputer);
				hostcomputer = (unsigned char *)0;
			    }
			}
			else
			    strcpy(hostcomputer,ifdp->ifd_off.ifd_byte);
			if(hostcomputer != (unsigned char *)0)
			    hostcomputer[ifdp->ifd_len] = '\0';
			break;
		case 318:/* WhitePoint			*/
			longfread((long *)&white,2,stdin);
			break;
		case 319:/* PrimaryChromaticities	*/
			longfread((long *)&primchrom,2,stdin);
			break;
		default:
			fprintf(stderr,"%s:Unknown tag %d - ignored\n",
			    argv[0],ifdp->ifd_tag);
			break;
		}
		ifdp++;
	}
	if (iwidth<=0L) {
		fprintf(stderr, "%s: missing ImageWidth\n", argv[0]);
		quit(1,argv[2]);
	}
	if (ilen<=0L) {
		fprintf(stderr, "%s: missing ImageLength\n", argv[0]);
		quit(1,argv[2]);
	}
	if (bits<=0L) {
		fprintf(stderr, "%s: missing BitsPerSample\n", argv[0]);
		quit(1,argv[2]);
	}
	sig=(((long)iwidth*bits+7L)/8L)*ilen;
	if (stripoff<=0L) {
		fprintf(stderr, "%s: missing StripOffsets\n", argv[0]);
		quit(1,argv[2]);
	}
	if (rows_p_strip<=0L) {
		strips_p_image = 1;
	}
	else{
		strips_p_image = (ilen + rows_p_strip - 1)/rows_p_strip;
	}
	if(strip_b_count==0){
	     if(strips_p_image==1){
		 strip_b_count = sig;
	     }
	     else{
		 fprintf(stderr,"Can't handle multiple strips without bytecount.\n");
		 quit(1,argv[2]);
	     }
	 }
/*****************************************************
*
* If tags XResolution and/or YResolution are present (and != 0) they are used to size
* the image to the original size.
* If you don't want that feature, just set xscal = iwidth and yscale = ilen.
*
******************************************************/	
	if((xres[1]==0L) || (xres[0]/xres[1] == 0L))
	    xscale = iwidth;
	else
	    xscale = (PS_metric*iwidth)/(xres[0]/xres[1]);
	if((yres[1]==0L) || (yres[0]/yres[1] == 0L))
	    yscale = ilen;
	else
	    yscale =  (PS_metric*ilen)/(yres[0]/yres[1]);
	fputs("%!PS-Adobe-2.0 EPSF-1.2\n%%Creator:tifftoeps\n\
%%Origin:0 720\n%%BoundingBox: 0 0 ", stdout);
	printf("%ld %ld", xscale, yscale+2*(FONTSIZE+4));
	fputs("\n%%DocumentFonts: Helvetica",stdout);
	fputs("\n%%EndComments\n/picstr ", stdout);
	printf("%ld", ((long)iwidth*bits+7L)/8L);
	printf(" string def\ngsave\n0 %d translate\n1 1 scale\n",(FONTSIZE+2));
#ifndef NO_INFO
	printf("gsave\n");
#endif
	printf("%ld %ld scale\n%d %d %d\n", xscale, yscale, iwidth, ilen, bits);
	printf("[%d 0 0 %d neg 0 %d]\n", iwidth, ilen, ilen);
	fputs("{currentfile picstr readhexstring pop}\nimage", stdout);
	value=0L; while ((i=get_tiff_img_byte(stdin,argv[2]))!=EOF) {
		if (value>=sig) break;
		if ((value&31)==0) putchar('\n');
		printf("%02X", i^invert);
		value++;
	}
	if(value<sig){
	    fprintf(stderr,"Insufficient data read %ld expected %ld.\n",value,sig);
	}
#ifndef NO_INFO
	fputs("\n\n\ngrestore\n", stdout);
	printf("0 -%d moveto\n/Helvetica %d selectfont\n",FONTSIZE+2,FONTSIZE);
	fputs("0 setgray\n",stdout);
	printf("(File : %s   ",argv[1]);
	if(imagedesc != (unsigned char *)0)
	    printf("I-desc : %s  ",unparen(imagedesc));
	if(datetime != (unsigned char *)0)
	    printf("Date : %s  ",unparen(datetime));
	if(artist != (unsigned char *)0)
	    printf("Artist : %s  ",unparen(artist));
	if(cel_wid > 0)
	    printf("CelWid : %d  ",cel_wid);
	if(cel_len > 0)
	    printf("CelLen : %d  ",cel_len);
	printf("thr : %s  Bits : %d",thrname[thresh],bits);
	printf(") show\n");

	printf("0 %d moveto\n(",yscale+2);
	if(hostcomputer != (unsigned char *)0)
	    printf("Host : %s  ",unparen(hostcomputer));
	if(model != (unsigned char *)0)
	    printf("Model : %s  ",unparen(model));
	if(make != (unsigned char *)0)
	    printf("Make : %s  ",unparen(make));
	if(software != (unsigned char *)0)
	    printf("Software : %s  ",unparen(software));
	    
	if((xres[1]!=0L) && (yres[0]!=0L)){
	    printf("  XRes x YRes : %g x %g [%s] Pixels: %d x %d",
		    (double)xres[0]/(double)xres[1],(double)yres[0]/(double)yres[1],
		    resolname[res_unit],iwidth,ilen);
	}
	printf(") show\n");
#endif /* NO_INFO */
	exit(0);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.