keves@net1.ucsd.edu (Brian Keves) (01/23/88)
This is the followup I promised concerning SUN raster file to Postscript conversions. The first letter gives some information, and the last two give source code. The first source, called suntops, is, in my opinion, superior to the second. This is because it is written with unix in mind, and I was able to integrate it into my Transcript software without any problems. I hope you enjoy, and I wish to thank all of the people who sent me replies. ----------------- Brian Keves ARPA: keves@sdcsvax.ucsd.edu P.O. Box 12238 UUCP: sdcsvax!keves La Jolla, CA 92037-0620 BITNET: keves@ucsd PHONE: 619-534-3839 Please leave a message ORGANIZATION: Lab for Mathematics and Statistics @ UCSD Any opinions expressed are strictly my own and do not necessarily reflect the opinions of my employer or UC Regents. ----------------- From: lou@aramis.rutgers.edu (Lou Steinberg) Subject: Re: Request for raster to Postscript program (SUN) In article <4483@sdcsvax.UCSD.EDU> keves@net1.ucsd.edu (Brian Keves) writes: > I need a program to convert SUN raster output to Postscript. On my sun3, at least, man pssun gives: NAME pssun - convert a Sun raster-format file to a POSTSCRIPT file. ... etc. I -think- this is a standard sun program. [Quite a few people said this, but in fact it is actually an add on from Adobe Systems. BWK] -- Lou Steinberg uucp: {pretty much any major site}!rutgers!aramis.rutgers.edu!lou arpa: lou@aramis.rutgers.edu ----------------- #! /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 # suntops.1 # suntops.h # error.c # main.c # suntops.c # This archive created: Sun Jan 17 12:51:43 1988 # By: (super-user) () export PATH; PATH=/bin:$PATH echo shar: extracting "'Makefile'" '(680 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 = -chab XSHARFLAGS = -cvpX 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 Xshar: $(PGM).shar X X$(PGM).shar: Makefile $(MAN) $(HDRS) $(SRCS) X shar $(SHARFLAGS) Makefile $(MAN) $(HDRS) $(SRCS) >$(PGM).shar X X$(OBJS): $(HDRS) SHAR_EOF if test 680 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 680 characters)' fi chmod +x 'Makefile' fi # end of overwriting check echo shar: extracting "'suntops.1'" '(1835 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.\" $Header: suntops.1,v 1.3 87/11/05 09:41:51 frew Exp $ X.TH SUNTOPS 1 "05 November 1987" X.SH NAME Xsuntops \- convert Sun rasterfile to PostScript X.SH SYNOPSIS X.B suntops X.RB [ \-ir ] 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 \-i XInvert the quantization of the printed image (i.e., Xreverse the output gray scale). 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 X.B \-i Xoption suggested by Philippe Schnoebelen. X.PP XPlease send bug reports, Xfixes, Xor enhancements to frew@hub.ucsb.edu Xor Xucbvax!ucsbcsl!frew. X.SH BUGS XThe X.B \-r Xoption is VERY slow X(e.g., Xup to 45 MINUTES!). XThis appears to be the fault of the LaserWriter's X.B rotate Xoperator, Xwhen applied to large bitmaps. SHAR_EOF if test 1835 -ne "`wc -c < 'suntops.1'`" then echo shar: error transmitting "'suntops.1'" '(should have been 1835 characters)' fi chmod +x 'suntops.1' fi # end of overwriting check echo shar: extracting "'suntops.h'" '(417 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 FALSE 0 X#define TRUE (~FALSE) X Xextern void error(); Xextern void suntops(); SHAR_EOF if test 417 -ne "`wc -c < 'suntops.h'`" then echo shar: error transmitting "'suntops.h'" '(should have been 417 characters)' fi chmod +x 'suntops.h' 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 chmod +x 'error.c' fi # end of overwriting check echo shar: extracting "'main.c'" '(1186 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 inverse; X int rotate; X double width; X X inverse = FALSE; X rotate = FALSE; X height = IMG_HEIGHT; X width = IMG_WIDTH; X X while ((opt = getopt(argc, argv, "h:irw:")) != EOF) { X switch (opt) { X X case 'i': X inverse = TRUE; X break; 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 [-ir] [-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, inverse, rotate, X stdout); X X exit(0); X} SHAR_EOF if test 1186 -ne "`wc -c < 'main.c'`" then echo shar: error transmitting "'main.c'" '(should have been 1186 characters)' fi chmod +x 'main.c' fi # end of overwriting check echo shar: extracting "'suntops.c'" '(4402 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, inverse, 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 inverse; /* ? inverse : forward hex map */ 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 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 inverse X * int->hex map X */ X inverse = ~inverse; X break; X X case 8: X ras.ras_width += ras.ras_width & 1; X break; X X default: X error("bad rasterfile depth"); X } X /* X * initialize int->hex map X */ X if (inverse) { X /* X * inverse 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 else { 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 /* 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} X X#ifndef lint Xstatic char rcsid[] = "$Header: suntops.c,v 1.2 87/09/14 12:41:52 frew Exp $"; X X#endif SHAR_EOF if test 4402 -ne "`wc -c < 'suntops.c'`" then echo shar: error transmitting "'suntops.c'" '(should have been 4402 characters)' fi chmod +x 'suntops.c' fi # end of overwriting check # End of shell archive exit 0 # ---------------------------------------------------------------------------- # James Frew (805)961-8413 frew@hub.ucsb.edu # CSL, UCSB, Santa Barbara, CA 93106 ucbvax!ucsbcsl!frew ----------------- From: Lap@UDEL.EDU Subject: Re: Raster to PS Brian, The source code for rf2ps follows. I and my colleages have found it useful, but it hasn't been too extensively tested, and is basically a hack. If you find it worthy, feel free to post it to the net (I don't seem to have access). If you have problems with it, please let me know, also please contact me if you'd like to see any modifications or extensions. Good luck... (just compile with 'cc'): --- cut here ----- /* RF2PS -- By Larry Pearlstein University of Delaware Non-commercial use and distribution is allowed. */ /* Usage: rf2ps filename > PSfile Converts filename from SUN rasterfile format to PostScript suitable for printing. */ #define TRUE -1 #define FALSE 0 #define PlotScale 4096.0 #include <stdio.h> FILE *fp; double AppleScaleX,AppleScaleY; int invertFlag; double scalex(x) int x; { double y; return( ((double) x / PlotScale) * AppleScaleX); } double scaley(y) int y; { return( ((double) y / PlotScale) * AppleScaleY); } getint() { int x; char c1,c2,c3,c4; fscanf(fp,"%c%c%c%c",&c1,&c2,&c3,&c4); x = ( (((unsigned) c1) & 0xff) << 24) + ( (((unsigned) c2) & 0xff) << 16) + ( (((unsigned) c3) & 0xff) << 8) + (((unsigned) c4) & 0xff); /* printf("%02x %02x %02x %02x %08x\n",c1,c2,c3,c4,x); */ return(x); } Parse() { struct { int ras_magic; int ras_width; int ras_height; int ras_depth; int ras_length; int ras_type; int ras_maptype; int ras_maplength; } rasterfile; char c; int i,count; char dummy; unsigned size; char *malloc(); char *myPointer,*bufPtr; int lines,chars; int pixperbyte,hres,vres; int nbytes; rasterfile.ras_magic = getint(); rasterfile.ras_width = getint(); rasterfile.ras_height = getint(); rasterfile.ras_depth = getint(); rasterfile.ras_length = getint(); rasterfile.ras_type = getint(); rasterfile.ras_maptype = getint(); rasterfile.ras_maplength = getint(); pixperbyte = rasterfile.ras_depth; hres = rasterfile.ras_width; vres = rasterfile.ras_height; nbytes = (hres * vres * pixperbyte)/8; for (i=0; i<rasterfile.ras_maplength; ++i) fscanf(fp,"%c",&dummy); myPointer = malloc((unsigned) (nbytes)); bufPtr = myPointer; for (i=0; i < nbytes; ++i) { fscanf(fp,"%c",&c); if (invertFlag == TRUE) *bufPtr++ = c; else *bufPtr++ = ~c; } printf("save\n"); printf("/picstr 2 string def\n"); printf("1 72 mul 2.25 72 mul translate\n"); printf("%f %f scale\n",AppleScaleX,AppleScaleY); printf("/doimage {\n"); printf("%d %d %d\n",rasterfile.ras_width,rasterfile.ras_height,rasterfile.ras_depth); printf("[ %d 0 0 %d 0 0 ]\n",rasterfile.ras_width,rasterfile.ras_height); printf("{ currentfile picstr readhexstring pop }\n"); printf("image showpage restore } def\n"); printf("doimage\n"); /* Print out hex numbers, 32 to a line */ count = 0; for (lines = 0; lines < vres; ++lines) { for (chars = 0; chars < (hres * pixperbyte)/8; ++chars) { printf("%02x",0xff & (int) *(myPointer + ((vres - 1) - lines) * ((hres * pixperbyte)/8) + chars) ); if (++count == 32) { count = 0; printf("\n"); } } } if (count != 0) printf("\n"); } main(argc,argv) int argc; char *argv[]; { double Xin,Yin; extern int optind; extern char *optarg; int I; AppleScaleX = (72.0 * 6.5); AppleScaleY = (72.0 * 6.5); invertFlag = FALSE; while ( (I = getopt(argc,argv,"x:y:i") ) != EOF) { switch (I) { case 'x': sscanf(optarg,"%lf",&Xin); AppleScaleX = 72.0 * Xin; break; case 'y': sscanf(optarg,"%lf",&Yin); AppleScaleY = 72.0 * Yin; break; case 'i': invertFlag = TRUE; break; default: break; } } /* See if any file name given */ if (optind == argc) fp = stdin; else fp = fopen(argv[optind],"r"); Parse(); } ----------------- Brian Keves ARPA: keves@sdcsvax.ucsd.edu P.O. Box 12238 UUCP: sdcsvax!keves La Jolla, CA 92037-0620 BITNET: keves@ucsd