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