frew@huevos.UUCP (Jim Frew) (09/09/87)
Submission for comp.sources.misc: "suntops" converts Sun rasterfiles to PostScript images, which may then be spooled to a PostScript printer. For example: screendump | suntops | lpr prints an image of your screen. suntops has been developed on a Sun-3/50 running Sun UNIX release 3.4, with Adobe TranScript software driving an Apple LaserWriter Plus over a 9600 baud RS232 connection. Note that with a 9600 baud connection, it takes about 5 minutes for the LaserWriter to receive and process a full Sun screen dump (1152 by 900 pixels). I believe you get something similar to suntops when you buy TranScript directly from Sun (we didn't). Enjoy, James Frew CRSEO ARPA: frew%huevos@hub.ucsb.edu University of California UUCP: {pyramid,sdcsvax,ucbvax}!ucsbcsl!frew Santa Barbara, CA 93106 voice: 805-961-2309 "shar" archive follows: #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # Makefile # error.c # main.c # suntops.1 # suntops.c # suntops.h # This archive created: Fri Sep 4 10:57:17 1987 # By: Jim Frew () export PATH; PATH=/bin:$PATH echo shar: extracting "'Makefile'" '(534 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else sed 's/^X//' << \SHAR_EOF > 'Makefile' XPGM = suntops XSRCS = error.c main.c suntops.c XHDRS = suntops.h XOBJS = error.o main.o suntops.o XMAN = suntops.1 X XCFLAGS = -O XLDFLAGS = XLIBS = XBINDIR = /usr/local/bin XBINMODE = 755 XMANDIR = /usr/local/man/man1 XMANMODE = 444 XLINTFLAGS = -chapb X X$(PGM): $(OBJS) X $(CC) $(LDFLAGS) -o $(PGM) $(OBJS) $(LIBS) X Xinstall: $(PGM) $(MAN) X strip $(PGM) X mv $(PGM) $(BINDIR) X chmod $(BINMODE) $(BINDIR)/$(PGM) X cp $(MAN) $(MANDIR) X chmod $(MANMODE) $(MANDIR)/$(MAN) X Xclean: X rm -f $(PGM) $(OBJS) X Xlint: X lint $(LINTFLAGS) $(SRCS) X X$(OBJS): $(HDRS) SHAR_EOF if test 534 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 534 characters)' fi fi # end of overwriting check echo shar: extracting "'error.c'" '(225 characters)' if test -f 'error.c' then echo shar: will not over-write existing file "'error.c'" else sed 's/^X//' << \SHAR_EOF > 'error.c' X/* X * error -- print error message and exit X */ X X#include <stdio.h> X Xextern int errno; X Xvoid Xerror(s) X char *s; X{ X if (errno != 0) { X perror(s); X } X else { X (void) fprintf(stderr, "%s\n", s); X } X X exit(1); X} SHAR_EOF if test 225 -ne "`wc -c < 'error.c'`" then echo shar: error transmitting "'error.c'" '(should have been 225 characters)' fi fi # end of overwriting check echo shar: extracting "'main.c'" '(1087 characters)' if test -f 'main.c' then echo shar: will not over-write existing file "'main.c'" else sed 's/^X//' << \SHAR_EOF > 'main.c' X/* X * main -- driver for suntops X */ X X#include <stdio.h> X Xextern double atof(); Xextern char *optarg; Xextern int optind; X X#include "suntops.h" X Xmain(argc, argv) X int argc; X char **argv; X{ X FILE *fpi; X int opt; X double height; X int rotate; X double width; X X rotate = FALSE; X height = IMG_HEIGHT; X width = IMG_WIDTH; X X while ((opt = getopt(argc, argv, "h:rw:")) != EOF) { X switch (opt) { X X case 'r': X rotate = TRUE; X break; X X case 'h': X height = atof(optarg); X if (height <= 0.0 || height > PAGE_HEIGHT) { X error("-h: bad height"); X } X X break; X X case 'w': X width = atof(optarg); X if (width <= 0.0 || width > PAGE_WIDTH) { X error("-w: bad width"); X } X X break; X X default: X error( X "Usage: suntops [-r] [-h height] [-w width] [file]" X ); X } X } X X if (argv[optind] == NULL) { X fpi = stdin; X } X else { X fpi = fopen(argv[optind], "r"); X if (fpi == NULL) { X error(argv[optind]); X } X } X X suntops(fpi, PAGE_HEIGHT, PAGE_WIDTH, height, width, rotate, stdout); X X exit(0); X} SHAR_EOF if test 1087 -ne "`wc -c < 'main.c'`" then echo shar: error transmitting "'main.c'" '(should have been 1087 characters)' fi fi # end of overwriting check echo shar: extracting "'suntops.1'" '(1467 characters)' if test -f 'suntops.1' then echo shar: will not over-write existing file "'suntops.1'" else sed 's/^X//' << \SHAR_EOF > 'suntops.1' X.TH SUNTOPS 1 "29 August 1987" X.SH NAME Xsuntops \- convert Sun rasterfile to PostScript X.SH SYNOPSIS X.B suntops X.RB [ \-r ] X.RB [ \-h X.IR height ] X.RB [ \-w X.IR width ] X.RI [ file ] X.SH DESCRIPTION X.I Suntops Xconverts a Sun rasterfile to a PostScript image. XThe rasterfile is read from either the standard input or the specified X.IR file . XThe PostScript image is written to the standard output. X.SH OPTIONS X.TP X.B \-r XRotate the PostScript output 90 degrees. XUseful for printing landscape-mode rasterfiles (e.g. Sun X.IR screendump s) Xon portrait-mode printers (e.g. Apple LaserWriters). X.TP X.B \-h XSet the maximum output image height to X.I height Xinches (default 9). X.TP X.B \-w XSet the maximum output image width to X.I width Xinches (default 7.5). X.SH EXAMPLES XTo print the current Sun screen: X.IP Xscreendump\ |\ suntops \-r\ |\ lpr \-PPostScript X.SH DIAGNOSTICS X\*(lqself-explanatory\*(rq X.SH RESTRICTIONS XInput rasterfiles must be either 1 bit or 8 bits deep. X.SH FUTURE DIRECTIONS XSpecify page size on the command line. X.PP XAllow a \*(lqraw\*(rq output mode whereby the PostScript output is scaled to Xexactly match the resolution of a specific printer. XThis is supposed to print significantly faster. X.PP XProvide an alternative driver routine so that X.I suntops Xmay be invoked as Xa line printer filter, Xe.g.: X.IP Xlpr \-PPostScript \-v X.SH AUTHOR XJames Frew. X.PP XPlease send bug reports, Xfixes, Xor enhancements to frew@hub.ucsb.edu Xor Xucbvax!ucsbcsl!frew. X.SH BUGS SHAR_EOF if test 1467 -ne "`wc -c < 'suntops.1'`" then echo shar: error transmitting "'suntops.1'" '(should have been 1467 characters)' fi fi # end of overwriting check echo shar: extracting "'suntops.c'" '(4157 characters)' if test -f 'suntops.c' then echo shar: will not over-write existing file "'suntops.c'" else sed 's/^X//' << \SHAR_EOF > 'suntops.c' X/* X * suntops -- convert Sun rasterfile to PostScript image X */ X X#include <assert.h> X#include <rasterfile.h> X#include <stdio.h> X X#include "suntops.h" X Xstatic void Xxch(a, b) X double *a; X double *b; X{ X double temp; X X temp = *a; X *a = *b; X *b = temp; X} X Xvoid Xsuntops(fpi, h_page, w_page, h_img, w_img, rotate, fpo) X register FILE *fpi; /* rasterfile stdio pointer */ X double h_page; /* PostScript page height */ X double w_page; /* PostScript page width */ X double h_img; /* PostScript image height */ X double w_img; /* PostScript image width */ X int rotate; /* ? rotate output image 90 deg */ X register FILE *fpo; /* PostScript stdio pointer */ X{ X int hexdig[16]; /* hexadecimal digit map */ X double aspect; /* rasterfile aspect ratio */ X register int byte; /* current rasterfile data byte */ X register int *hexp; /* fast pointer to hexdig array */ X struct rasterfile ras; /* rasterfile header */ X X /* X * read rasterfile header X */ X /* NOSTRICT */ X if (fread((char *) (&ras), sizeof(ras), 1, fpi) != 1) { X error("can't read rasterfile header"); X } X X if (ras.ras_magic != RAS_MAGIC) { X error("input is not a Sun rasterfile"); X } X /* X * compute rasterfile aspect ratio X */ X if (rotate) { X xch(&h_img, &w_img); X xch(&h_page, &w_page); X } X X aspect = ras.ras_width; X aspect /= ras.ras_height; X /* X * adjust PostScript image size to preserve aspect ratio X */ X if (aspect >= w_img / h_img) { X h_img = w_img / aspect; X } X else { X w_img = h_img * aspect; X } X X assert(h_page >= h_img); X assert(w_page >= w_img); X /* X * rasterfile lines are padded to a multiple of 16 bits (see rasterfile(5)); X * adjust rasterfile line length accordingly X * X * initialize integer -> hexadecimal digit mapping X */ X switch (ras.ras_depth) { X X case 1: X if (ras.ras_width % 16 != 0) { X ras.ras_width += 16 - ras.ras_width % 16; X } X /* X * Sun black/white bitmap convention is opposite of PostScript, so reverse X * int->hex map X */ X hexdig[0] = 'f'; X hexdig[1] = 'e'; X hexdig[2] = 'd'; X hexdig[3] = 'c'; X hexdig[4] = 'b'; X hexdig[5] = 'a'; X hexdig[6] = '9'; X hexdig[7] = '8'; X hexdig[8] = '7'; X hexdig[9] = '6'; X hexdig[10] = '5'; X hexdig[11] = '4'; X hexdig[12] = '3'; X hexdig[13] = '2'; X hexdig[14] = '1'; X hexdig[15] = '0'; X X break; X X case 8: X ras.ras_width += ras.ras_width & 1; X /* X * normal int->hex map X */ X hexdig[0] = '0'; X hexdig[1] = '1'; X hexdig[2] = '2'; X hexdig[3] = '3'; X hexdig[4] = '4'; X hexdig[5] = '5'; X hexdig[6] = '6'; X hexdig[7] = '7'; X hexdig[8] = '8'; X hexdig[9] = '9'; X hexdig[10] = 'a'; X hexdig[11] = 'b'; X hexdig[12] = 'c'; X hexdig[13] = 'd'; X hexdig[14] = 'e'; X hexdig[15] = 'f'; X X break; X X default: X error("bad rasterfile depth"); X } X /* X * PostScript header X */ X (void) printf("%%!\n"); X /* X * if "rotate" set then rotate PostScript image 90 degrees X */ X if (rotate) { X (void) printf("90 rotate\n"); X (void) printf("0 -%d translate\n", ITOP(h_page)); X } X /* X * center the PostScript image on the output page X */ X (void) printf("%d %d translate\n", X ITOP(((w_page - w_img) / 2.0) + XTRANS_FUDGE), X ITOP((h_page - h_img) / 2.0)); X (void) printf("%d %d scale\n", ITOP(w_img), ITOP(h_img)); X /* X * I/O buffer for readhexstring X */ X (void) printf("/linebuf %d string def\n", X ras.ras_width / (8 / ras.ras_depth)); X /* X * set PostScript image parameters X */ X (void) printf("%ld %ld %d\n", X ras.ras_width, ras.ras_height, ras.ras_depth); X (void) printf("[%ld 0 0 -%ld 0 %ld]\n", X ras.ras_width, ras.ras_height, ras.ras_height); X (void) printf("{currentfile linebuf readhexstring pop}\n"); X /* X * image data follows X */ X (void) printf("image\n"); X /* X * convert rasterfile bytes to pairs of ASCII hexadecimal digits X */ X hexp = hexdig; X X while ((byte = getc(fpi)) != EOF) { X putc(hexp[HI_NYBBLE(byte)], fpo); X putc(hexp[LO_NYBBLE(byte)], fpo); X } X X if (ferror(fpi)) { X error("input error"); X } X X if (ferror(fpo)) { X error("output error"); X } X /* X * display PostScript image on output device X */ X (void) fprintf(fpo, "showpage\n"); X} SHAR_EOF if test 4157 -ne "`wc -c < 'suntops.c'`" then echo shar: error transmitting "'suntops.c'" '(should have been 4157 characters)' fi fi # end of overwriting check echo shar: extracting "'suntops.h'" '(410 characters)' if test -f 'suntops.h' then echo shar: will not over-write existing file "'suntops.h'" else sed 's/^X//' << \SHAR_EOF > 'suntops.h' X/* X * suntops.h -- header file for suntops program X */ X X#define PAGE_HEIGHT 11.0 X#define PAGE_WIDTH 8.5 X X#define IMG_HEIGHT 9.0 X#define IMG_WIDTH 7.5 X X#define ITOP(in) ( (int)((in) * 72.0) ) X X#define XTRANS_FUDGE (1.0 / 16.0) /* LaserWriter X bias */ X X#define HI_NYBBLE(i) ( ((i) >> 4) & 0xF ) X#define LO_NYBBLE(i) ( (i) & 0xF ) X X#define TRUE 1 X#define FALSE 0 X Xextern void error(); Xextern void suntops(); SHAR_EOF if test 410 -ne "`wc -c < 'suntops.h'`" then echo shar: error transmitting "'suntops.h'" '(should have been 410 characters)' fi fi # end of overwriting check # End of shell archive exit 0