ftp.nice.ch/pub/next/graphics/convertors/mpnttotiff.c

This is mpnttotiff.c in view mode; [Download] [Up]

/* Convert Macintosh screen shot (MPNT/PNTG) to NeXT TIFF
 * Eric P. Scott, San Francisco State University, October 1990
 *
 * This input for this is the data fork of a Mac file created
 * with Command-Shift-3
 *
 * "For more information see"
 *   Tag Image File Format Specification, Revision 5.0
 *   Macintosh Technical Note #86, MacPaint Document Format
 *   Macintosh Technical Note #171, _PackBits Data Format
 *
 * Small-screen Macs (e.g. SEs) save in the normal orientation
 * Large-screen Macs (e.g. IIs) rotate their bitmap--use -r option
 *
 * To compile:
 * cc -s -o mpnttotiff -O -bsd mpnttotiff.c -lsys_s
 */
#include <stdio.h>
#ifndef lint
static char sccsid[]="@(#)mpnttotiff  1.0  (SFSU) 10/24/90";
#endif

struct {
	long tiff_magic, tiff_firstifd;
	short tiff_ifdents;
	struct ifdent {
		short ifd_tag, ifd_type;
		long ifd_len, ifd_off;
	} tiff_ifd[8];
	long tiff_ifdchain;
} header={	/* warning: nonportable */
	0x4d4d002aL, 8L, 8, {
		{ 255, 3, 1L, 1L<<16 },		/* SubfileType */
		{ 256, 3, 1L, 720L<<16 },	/* ImageWidth */
		{ 257, 3, 1L, 576L<<16 },	/* ImageLength */
		{ 262, 3, 1L, 1L<<16 },		/* PhotometricInterpretation */
		{ 277, 3, 1L, 1L<<16 },		/* SamplesPerPixel */
		{ 284, 3, 1L, 2L<<16 },		/* PlanarConfiguration */
		{ 258, 3, 1L, 1L<<16 },		/* BitsPerSample */
		{ 273, 4, 1L, 110L }		/* StripOffsets */
	}, 0L
};
int rotate=0;

main(argc, argv)
int argc;
char *argv[];
{
	extern int optind;
	extern char *optarg;
	register unsigned char *q, *p;
	int c;
	long lbuf[12960];	/* space for 576x720x1 image */

	while ((c=getopt(argc, argv, "r"))!=EOF) switch (c) {
	case 'r':
		rotate++;
		break;
	default:
	usage:
		(void)fprintf(stderr, "Usage: %s [-r] paint-file tiff-file\n",
			*argv);
		(void)fputs("\t-r  rotate 90 degrees counterclockwise\n",
			stderr);
		exit(1);
		break;
	}

	if (argc-optind!=2) goto usage;
	if (strcmp(argv[optind], "-")&&!freopen(argv[optind], "r", stdin)) {
		perror(argv[optind]);
		exit(1);
	}
	(void)fread((char *)lbuf, 512, 1, stdin);
	if (*lbuf!=0L) {
		(void)fprintf(stderr,
			"%s: input isn't in a format I can deal with\n",
			*argv);
		exit(1);
	}

	p=(unsigned char *)&lbuf[sizeof lbuf/sizeof lbuf[0]];
	q=(unsigned char *)lbuf;
	bzero((char *)q, sizeof lbuf);
	while ((c=getchar())!=EOF) {	/* UnPackBits */
		/* I'm cheating: you're supposed to do this a row at a time */
		register int b;

		if ((c&=255)<=127) {
			do {
				if (q>=p) {
				ovfl:
					(void)fprintf(stderr,
"%s: internal buffer overflow\n", *argv);
					exit(1);
				}
				if ((b=getchar())==EOF) {
				tooshort:
					(void)fprintf(stderr,
"%s: EOF in sequence\n", *argv);
					exit(1);
				}
				*q++=b;
			} while (--c>=0);
		}
		else {
			c-=256;
			if ((b=getchar())==EOF) goto tooshort;
			do {
				if (q>=p) goto ovfl;
				*q++=b;
			} while (++c<=0);
		}
	}

	if (strcmp(argv[++optind], "-")&&!freopen(argv[optind], "w", stdout)) {
		perror(argv[optind]);
		exit(1);
	}
	if (!rotate) {	/* swap dimensions */
		header.tiff_ifd[1].ifd_off=576L<<16;
		header.tiff_ifd[2].ifd_off=720L<<16;
	}
	(void)fwrite((char *)&header, sizeof header, 1, stdout);

	if (rotate) {	/* rotate 90 degrees clockwise and invert */
		long obuf[180];

		p=(unsigned char *)&lbuf[12816];
		c=72; do {
			register int r;

			q=(unsigned char *)obuf;
			bzero((char *)q, sizeof obuf);
			r=90; do {
#define twist(m) \
	if ((*p&m)==0) *q=1; \
	if ((p[72]&m)==0) *q|=2; \
	if ((p[144]&m)==0) *q|=4; \
	if ((p[216]&m)==0) *q|=8; \
	if ((p[288]&m)==0) *q|=16; \
	if ((p[360]&m)==0) *q|=32; \
	if ((p[432]&m)==0) *q|=64; \
	if ((p[504]&m)==0) *q|=128
				twist(128); q+=90;
				twist(64); q+=90;
				twist(32); q+=90;
				twist(16); q+=90;
				twist(8); q+=90;
				twist(4); q+=90;
				twist(2); q+=90;
				twist(1); q-=629;
				p-=576;
			} while (--r>0);
			(void)fwrite((char *)obuf, sizeof obuf, 1, stdout);
			p+=51841;	/* 1+sizeof lbuf */
		} while (--c>0);
	}
	else {	/* just invert */
		p=(unsigned char *)&lbuf[sizeof lbuf/sizeof lbuf[0]];
		q=(unsigned char *)lbuf;
		do {
			putchar(*q++^255);
		} while (q<p);
	}
	(void)fflush(stdout);
	exit(0);
}

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