Date: Tue, 26 Jan 93 15:19:07 EST From: george@mech.seas.upenn.edu (George Jefferson) Subject: ps2eps-mac this is version 1.3 of my ( unix based ) package for converting postscript -> mac format eps with screen preview. new features include: 1 major bug fix. ( would crash when converting large images ) color support ( off by default, to reduce file size ) robust recognition of all sorts of wierd bounding box line formats ( atend, decimal numbers, etc ) more informative ( imho ) error reporting. pbmtoepsi.c is now included in this distribution. ( still needs pbmplus to compile though ) unix "man" page requires ghostscript, and the pbmplus package. george jefferson george@mech.seas.upenn.edu for the archivists, replaces mac/util/unix/ps2eps1.1.shar @umich info-mac/unix/ps2eps-11.shar @sumex BTW, the name ps2eps is already taken ( by several programs, sigh ) if ps2eps-mac1.3.shar is too long, go with ps2epsmac13.shar or ps2epsmac13.sh or ps2mac13.sh thanks. ---------ps2eps-mac1.3.shar----cut here--- #! /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: # README # ps2eps-mac # ps-pict2macb.c # makefile # test.ps # er_echo.c # st_echo # ps2eps-mac.m # pbmtoepsi.c # test.eps.bin.uu # This archive created: Thu Jun 11 10:40:57 1992 export PATH; PATH=/bin:$PATH if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' ps2eps-mac takes an arbitrary postscript file ( even sort of works with macintosh laserwriter driver dumps.. ) and creates an 'encapsulated postscript with embedded pict' file in macbinary format. This file can be included in certain programs ( eg Word5 ) that support the format, and you will get a 72dpi screen preview image, but postscript quality output on your postscript printer. Note that there is no way to represent multi page documents using the embeded pict format. so far it has been used sucessfully with MSWord 5 and its 'draw' module ( does _not_ work with MSW4 or lower ) OzTeX Kalidagraph a short list, sigh -- anything else? to make use of this program you need ghostscript and pbmplus ..and you need to know how to transfer a macbinary file to your macintosh in a nutshell -- set your unix transfer program to 'binary' and your macintosh transfer program to 'macbinary' quick and dirty usage is simply ps2eps-mac file.ps -which produces file.eps.bin -which when transferred to your mac will be named "file.eps" by default this will be a Word5 file, double clicking on this file will open it in word5, with a nice screen image. You can easily change the type/creator by setting shell variables so that the eps file will open in your favorite eps compatible program. notes----------- usage ps2eps-mac [ options ] file.ps options can be any of.. -q -> quiet mode, overwrites scratch files without asking -batch -> same as -q -d -> where to put the output file, can be "stdout" to pipe output to stdout ( automatically sets "-q" and sends errors to a log file ) -pipe, eqivalent to "-d stdout" -log logfile -> send output messages to logfile -debug n -> change debug level to n -widen n or -widen unset -> override default widenbox value environment variables setenv EPSTYPE EPSF setenv EPSCREATOR MSWD to set the type and creator of the macintosh file the defaults are EPSF,MSWD which let me double click to open the file in MSWord 5, the defaults are defined in ps-pict2macbin.c be sure that the following are on your path, or are in the $ps2epsdir directory list ps-pict2macbin er_echo <well, you could live without this..> ( in the ps2eps-mac shell archive ) pnmcrop _or_ pnmcut < pnmcut works better i think, get both if you can > pbmtoepsi ppmtopict ( export.lcs.mit.edu ; contrib/pbm* ) gs ( prep.ai.mit.edu ; pub/gnu/ghost* ) macps ( sumex-aim.stanford.edu ; info-mac/unix ) macps is needed if the original ps file is a macintosh laserwriter driver dump acknowledgements -- in addition to the above programs, I learned a lot ( and maybe borrowed some code.. ) from mcvert macbin ps2epsf Doug Crabill may notice that this shell script bears some resemblence to his script ( which creates a pc compatable file ) the man page was contributed by jc@msc.edu known bugs translating line endings with tr is bound to mess up any binary stuff in the source postscript -- try playing with the translate options if someone knows a foolproof way to do line ending translation, please give me a call... explination of options that can be set in the ps2eps-mac script { for csh novices... a shell variable can be 'set' set x or set to a value set x = 1 or set to a list set x = ( 1 A 4.5 ) the line, #set x is commented out, thus ( unless previously set ) x is 'unset' in this program, all of the variables in the options section may be 'set' or 'unset'. Some of them - where indicated - must be set to values, if they are set. } #set ps2epsdir = ( /usr/new/bin ) add directories to your search path. you might need here the directorys containing gs, pbm stuff, the ps-pict2macbin executable line ending translation options -- a concern only if your ps contains very long lines or binary data ( included fonts and such ) #set notranslate leave unix line endings everywhere notranslate _does_not_work_ with msword. -- does it work with anything??? #set notransfile set notranslatefile to put mac line endings on only the first two lines of the file -- this is a little wierd but it seems to work. I am really curious if this is ok with ps interpreters like freedom of the press. This 'aint gonna work when the existing bounding box is used ( see bbinfo below ) #set havemacps uncomment only if you have macps and you might be processing a mac laserwriter driver generated file ( beware, you are on thin ice.. ) typically your 'eps' file will only print from a mac running a certain laserwriter driver. #set noshowpage uncomment to add line to undefine showpage in the postscript [/showpage {} def] only necessary if.. 1)your ps contains showpage 2) your mac application doesn't like it ( eg Word ) ..but it should never hurt.. ( yea right ) #set density = 72 do not use this -- changing the density changes the _size_ not the resolution of the pict image , sigh. If somone 'fixes' ppmtopict to have a resolution option me and my deskwriter will be greatful. ( value required, if set ) set widenbox = 1 the bounding box sometimes chops off edges of picture, this uses a hack to widen the bb by $widenbox points an error will result if the 'new' bounding box goes beyond the edge of ghostscripts 'page' -- if your ps draws at the origin then you cant widen the box ( try using a translate in the source ps ) note -- set widenbox = 0 is not exactly the same as leaving widenbox unset -- pnmcut is used rather than pnmcrop ( in priciple the same result by a different method ) widenbox can now be defined on the command line as well ( see usage ) whatever you do with it here is the default. ( value required, if set *integer only* ) #set bbinfo with bbinfo not set, use the bounding box in the original ps file ( if one exists ) -- requires widenbox to be set as well. bbinfo unset, and widenbox = 0 leaves the postscript 'data fork' completely original if the original file contains a bounding box. Of course, if the existing bounding box is wrong you will get garbage. set widenboxbb = 0 if set, widenboxbb overrides widenbox in cases where existing bounding box is used ( typically this should be zero I guess. ) widenbox still must be set to something for this to happen. ie. the default operation is no bounding box in original file -> calculate a box and widen by 1 point bounding box in original file -> use it, no modification at all to postscript ( value required, if set ) please inform me, if you have problems with widenbox, as the pnmcrop method of cropping the pict will be left out of future versions if it is not needed. set error = er_echo error reporting program, in case the default er_echo does not compile, there is a csh script st_echo. st_echo does not work with -log or -pipe ( value required ) #set log ps2eps.log direct output to a log file rather than standard error. This really just gets passed to $error can be set with "-log file" on the command line (value required if set ) set debuglev = 1 default debug level, passed to $error 0 -> only fatal error messages 1 -> lets you know what is going on 3 -> possably interesting stuff 4 ( or higher ) -> very verbose can be overridden with "-debug n" on the command line (value required if set ) #set quiet make "-q" on by default ( overwrites files without asking ) this cannot be overriden on the command line more usage notes are in the shell script 'ps2eps-mac' this shell archive contains makefile -- enter 'make' to compile.. ps2eps-mac -- executable shell script ps-pict2macbin.c -- source for macbinary creating utility test.ps -- simple test file test-ex.eps.bin.uu -- example macbinary, created from test.ps README -- this file er_echo.c -- error handling c program pbmtoepsi.c -- additional pbmplus source ps2eps-mac.1 -- unix man page version history initial release 4/4/92 george jefferson george@mech.seas.upenn.edu v.0.1 4/5/92 added options to modify line ending translation in ps2eps-mac script ( same action by default ) v.0.2 4/5/92 added code to widen the bounding box -- by 1 pt as default better test.ps v.0.3 4/6/92 corrections to documentation change default file type to EPSF fixed info header bug pad resource fork to 128 byte bound ( suntar choked... ) v.0.4 now looks for a bounding box line in the source file and uses it rather than using ppmtoepsi to calculate.. this feature is 'on' by default ( see bbinfo option ) explination of most options moved to this file from the shell script v.0.5 I _think_ the bounding box is now calculated correctly in all cases. v.0.6 added er_echo.c, which lets me do nice error reporting ( if er_echo fails to work, it is a bit superfluous, unset $error ) v.0.7 bypass ftime, for sysv machines v.0.8 more sysv compatabilty modification shortened ps-pict2macbin.c to ps-pict2macb.c v.0.9 added pbmtoepsi source to distribution v.0.91 fixed time() bug which caused crash on sun3's v.1.0 included st_echo, although i dont know of any problems with er_echo added man page, now i think we are ready to send to some ftp sites. v.1.1 recognises gs2.4 multi-page output, aborts with an apropriate message. v.1.2 compatability with several different BoundingBox formats ( atend ) non - integer values box:x ( no space ) makes sure first line is %!PS-Adobe even more saninty checking. repaired major bug in ps-pict2macb.c, which caused mac to crash with large images. more output options v.1.3 color support. fixed ftp output SHAR_EOF fi # end of overwriting check if test -f 'ps2eps-mac' then echo shar: will not over-write existing file "'ps2eps-mac'" else cat << \SHAR_EOF > 'ps2eps-mac' #!/bin/csh -f #creates a macintosh "postscript with pict preview" file #in macbinary format. ( transfer to a mac in binary/macbinary enabled mode ) # ###options, change defaults by uncommenting "#" lines _SEE_README_ ###_any_ of these options may be 'unset' or commented out #set ps2epsdir = ( /usr/new/bin ) # add to search path #set notranslate #do not translate any line endings #set notransfile #put mac line ending on only first two lines #set havemacps #pass through macps if necessary #set noshowpage #undefine showpage in eps file #set density = 72 #dont change this, it doesn't work :-( set widenbox = 1 #add n points extra white space around image #set bbinfo #do not look for existing bounding box set widenboxbb = 0 #widenbox used when using existing bounding box set error = er_echo #turn on error reporting #set log = ps2eps.log #write to log rather than stderr set debuglev = 1 #default debug level ( 0 = none, 5 = all ) #set quiet #make -q on by default ###end of options, end of even mildly interesting notes set colors = ppm1run if($?debuglev == 0)set debuglev = 0 set destdir = '.' while( $#argv > 0 ) switch ( $1 ) case -exec set destdir = o.command set command = "$2" shift breaksw case -widen set widenbox = $2 if( $widenbox == unset )unset widenbox shift breaksw case -8 set colors = ppm8run breaksw case -24 set colors = ppm24run breaksw case -q case -batch set quiet breaksw case -d set destdir = $2 shift breaksw case -ftp set ftp = $2 shift set destdir = o.ftp breaksw case -pipe set destdir = stdout case -debug set debuglev = $2 shift breaksw case -log set logfile = $2 shift breaksw default set source = $1 #full path name of original ps file breaksw endsw shift end if( $?source == 0 )then echo no input file specified exit else if( ! -f $source )then echo $source not found exit else if( `head -1 $source | grep '^%\\!' | wc -l` == 0)then echo $source is not a postscript file exit endif if( $destdir == stdout )then set quiet if( $?logfile == 0 )set logfile = ps2eps-mac.log endif if( $?error == 1 && $?logfile == 1 )then rm -f $logfile set error = ( $error -log $logfile ) endif if( $?error == 0 )set error = er_echo ##debug if( "`which $error[1] | wc -w`" != 1 )goto errorok #then ##debug echo error, $error[1] is not on your path if( "`which st_echo | wc -w`" != 1 )then set error = st_echo else echo fatal error, st_echo is not on your path either exit endif ##debug errorok: #endif set error = ( $error -off $debuglev ) if( $debuglev >= 4 )then ##debug $error -level 4 shell variables... ##debug set | $error -cat -level 4 ##debug $error -level 4 environment variables... ##debug printenv | $error -cat -level 4 ##debug $error -level 4 directory listing... ##debug /bin/ls -l | $error -cat -level 4 ##debug endif ##debug if( $?ps2epsdir == 1 )then set path = ( $ps2epsdir $path ) endif set psfile = $source:t #original file without pathname set name = $psfile:r #root name ( .ps removed ) $error -level 2 reading $source to create ${name}.eps.bin ##debug set ppm = ${name}.ppm #ghostscript output set eps = ${name}.eps #name of mac file to be created set pict = ${eps}.pict #pict data output by ppmtopict set dat = ${eps}.ps #data fork, %%boundin box added and line ends changed set bin = ${eps}.bin #macbinary file set save = ${pict}-save #temporary copy of original set fls = ( $eps $ppm $pict $dat $bin $save ) set np = 1 while( -f ${name}.${np}ppm || $np < 4 ) set fls = ( $fls ${name}.${np}ppm ) @ np = $np + 1 end set destroy foreach i ( $fls ) if( -f $i )then if( $?quiet == 0 )echo $i will be over written or deleted set destroy = ( $destroy $i ) endif end set q = y if( "$destroy" != "" && $?quiet == 0 )then echo -n "continue y/n? " set q = $< endif if( $q != y )exit foreach i ( $destroy ) $error -level 1 removing $i -level 3 "`/bin/ls -l $i`" ##debug rm -f $i end if( $psfile != $source )cp $source $psfile if( $?widenbox == 0 || $?bbinfo == 1 )goto nobbox # do we need to look further than 20 lines? set bbinfo = `head -20 $psfile | grep '%%BoundingBox:' | head -1 | sed -e 's/%%BoundingBox:/ /'` if( $#bbinfo == 0 )goto nobbox if( `echo $bbinfo | grep atend | wc -l` != 0 )then $error -level 1 looking for %%BoundingBox at the end of the file set bbinfo = `cat $psfile | grep '%%BoundingBox:' | tail -1 | sed -e 's/%%BoundingBox:/ /'` set append endif if( $#bbinfo != 4 )then $error -level 1 seems to be a %%BoundingBox line but there is a problem so it will be ignored $bbinfo set bbinfo = ( ) goto nobbox endif echo $bbinfo | grep '\.' if( `echo $bbinfo | grep '\.' | wc -l` != 0 )then $error -level 1 bounding box contains non-integers -- trying to fix $error -n -level 2 $bbinfo foreach jj ( 1 2 3 4 ) set ibb = `echo "$bbinfo[$jj] / 1" | bc` if( $jj <= 2 )set bbinfo[$jj] = $ibb if( $jj >= 3 && $bbinfo[$jj] != $ibb )@ bbinfo[$jj] = $ibb + 1 end set append $error -level 2 " to " $bbinfo endif $error -level 1 using bounding box information from source file %%BoundingBox: $bbinfo ##debug if(`head -1 $psfile |egrep '^%\\!PS-Adobe-' |wc -l` == 0 )then #this is the minimum header required by msword5 ( yes case sensative ) $error -level 2 "the header on this ( eps ) input file is not quite correct so we will be appending a new one" set append endif if( $?widenboxbb == 0 )set widenboxbb = $widenbox set widenbox = $widenboxbb if( $widenbox != 0)$error -level 1 widened by $widenbox ##debug nobbox: if( $?havemacps == 1 && `grep '%%IncludeProcSet: "(AppleDict md)"' $psfile | wc -l` != 0 )then mv $psfile $save $error -level 1 running macps on file -- only for ghostscript ##debug macps $save > $psfile set macpsed endif if( $?density == 0 )set density = 72 $error -level 1 running ghostscript.... ##debug gs -dNODISPLAY pstoppm.ps << DGC | $error -cat -level 3 $density $density ppmsetdensity ($name) $colors DGC if( -f $ppm && ! -z $ppm )goto gsdone #then if( -f ${name}.1ppm )then set npages = ( ${name}.*ppm ) $error -level 0 sorry, this file apparently contains $#npages pages $error -level 0 you can not create multi page eps-pict files rm -f $npages else $error -level 0 fatal error, no output from ghostscript if( $debuglev < 3)$error -level 0 re-run using -debug 3 or higher to see ghostscript errors endif exit gsdone: #endif $error -level 1 ghostscript done ##debug if ( $?macpsed == 1)mv $save $psfile set translate = "tr '\012' '\015'" if( $?notranslate == 1)set translate = "cat -" switch ( $?widenbox ) case 1 if( $#bbinfo != 4 )then if( $colors != ppm1run )goto colorerror $error -level 1 getting bounding box info from pbmtoepsi ##debug set bbinfo = ( `pbmtoepsi $ppm | head -2 | tail -1` ) $error -level 2 pbmtoepsi says $bbinfo ##debug @ bbinfo[3] = $bbinfo[3] - 1 # I think the pbmtoepsi box is @ bbinfo[4] = $bbinfo[4] + 1 # not quite correct $error -level 2 "'fixed' to be " $bbinfo ##debug shift bbinfo set append endif while( $widenbox > 0 && ( $bbinfo[1] - $widenbox < 0 || $bbinfo[2] - $widenbox < 0 ) ) $error -level 1 -n cant widen box by $widenbox ##debug @ widenbox = $widenbox - 1 $error -level 1 .... using $widenbox ##debug end if( $widenbox > 0 )then set append $error -level 1 widening bounding box by $widenbox ##debug @ bbinfo[1] = $bbinfo[1] - $widenbox @ bbinfo[2] = $bbinfo[2] - $widenbox @ bbinfo[3] = $bbinfo[3] + $widenbox @ bbinfo[4] = $bbinfo[4] + $widenbox endif if( $?noshowpage == 1 )set append if( $?append == 1 )then echo "%\!PS-Adobe-2.0 EPSF-1.2" | $translate > $dat echo "%%BoundingBox: $bbinfo" | $translate >> $dat $error -level 2 will append bounding box info to postscipt ##debug if( $?reportheader == 0 )goto norep #then $error -level 0 first two lines of the file should be: $error -level 0 "%\!PS-Adobe-2.0 EPSF-1.2" $error -level 0 "%%BoundingBox: $bbinfo" norep: #endif else touch $dat $error -level 2 postscipt bounding box left alone ##debug endif breaksw default if( $colors != ppm1run )goto colorerror $error -level 1 writing eps header using pbmtoepsi directly ##debug pbmtoepsi $ppm | head -2 | $translate > $dat if( $? reportheader == 1 )pbmtoepsi $ppm | head -2 | $error -level 0 -cat breaksw endsw if( $?noshowpage == 1 )then echo "/showpage {} def" | $translate >> $dat $error -level 1 "/showpage {} def" added to postscript ##debug endif if( $?notransfile == 1)set translate = "cat -" if( "$translate" != "cat -")$error -level 1 translating line endings on postscript file ##debug cat $psfile | $translate >> $dat if( $psfile != $source )rm -f $psfile if( $?widenbox == 1 )then @ xwide = $bbinfo[3] - $bbinfo[1] @ yhi = $bbinfo[4] - $bbinfo[2] set xcut = $bbinfo[1] @ ycut = - $yhi + $bbinfo[2] $error -level 2 pict bounding box $bbinfo ##debug set bber = "fatal bounding box error" ##debug if( $xcut < 0 )set bber = ( $bber ": x = $xcut out of bounds" ) ##debug if( $xwide < 8 )set bber = ( $bber ": xwidth = $xwide less than 8 is too small" ) ##debug if( $yhi + $ycut > 0 )set bber = ( $bber ": y out of bounds" ) ##debug if( $yhi <= 0 )set bber = ( $bber ": height = $yhi is too small" ) ##debug if( $#bber == 1 )goto boxok #then ##debug $error -level 0 $bber ; exit ##debug boxok: #endif ##debug $error -level 1 writing pict file using pnmcut,ppmtopict ##debug $error -level 2 pnmcut $xcut $ycut $xwide $yhi $ppm ##debug ( pnmcut $xcut $ycut $xwide $yhi $ppm | ppmtopict - > $pict ) |& \ $error -cat -level 2 else $error -level 1 writing pict file using pnmcrop,ppmtopict ##debug ( pnmcrop $ppm | ppmtopict - > $pict ) |& $error -cat -level 2 endif if( ! -f $pict || -z $pict )then $error -level 0 fatal error pict not created ls -l $pict $ppm if( $debuglev < 2)$error -level 0 re-run with \"-debug 2\" exit endif if( $debuglev >= 3)$error -level 3 removing "`/bin/ls -l $ppm`" ##debug rm -f $ppm set iftype ifcreator if( $?EPSTYPE != 0 )then set iftype = ( -type $EPSTYPE ) endif if( $?EPSCREATOR != 0 )then set ifcreator = ( -creator $EPSCREATOR ) endif $error -level 1 writing macbinary file ##debug ps-pict2macb $eps $iftype $ifcreator |& $error -cat -level 2 if($debuglev >= 3)then ##debug $error -level 3 removing "`/bin/ls -l $pict`" ##debug $error -level 3 removing "`/bin/ls -l $dat`" ##debug endif ##debug rm -f $pict $dat switch ( $destdir ) case . $error -level 1 macbinary file $bin saved in current directory ##debug breaksw case stdout cat $bin if($debuglev >= 3)$error -level 3 removing "`/bin/ls -l $bin`" ##debug rm -f $bin $error -level 1 macbinary written to stdout ##debug breaksw case o.command $error -level 2 $command $command $bin rm -f $bin breaksw case o.ftp echo $ftp ftp $ftp << endftp |& $error -cat -level 1 bin quote macb enabled put $bin ls $name.eps endftp rm -f $bin breaksw default if( -d $destdir && -w $destdir )then mv $bin $destdir $error -level 1 output macbinary file is $destdir/$bin ##debug else $error -level 1 invalid destination directory $destdir macbinary file $bin left in current directory ##debug endif breaksw endsw exit colorerror: $error -level 1 warning attempt to create color preview when source $error -level 1 file has no bounding box. - running in b/w mode $error -level 1 to determine a bounding box $error -level 1 \( you should add the bb by hand to create a color image \) set colors = ppm1run set reportheader goto nobbox SHAR_EOF chmod +x 'ps2eps-mac' fi # end of overwriting check if test -f 'ps-pict2macb.c' then echo shar: will not over-write existing file "'ps-pict2macb.c'" else cat << \SHAR_EOF > 'ps-pict2macb.c' /* ps-pict2macbin.c george jefferson george@mech.seas.upenn.edu */ /* initial release 4/4/92 */ /* usage ps-pict2macbin file [-type TYPE ] [ -creator CREATOR ] */ /* combines "file.ps" and "file.pict" to form "file.bin" */ /* file.bin is a macbinary format file, with macintosh name "file" */ /* and creation/modification dates set to the current time of */ /* day ( anybody care? ) */ /* if type and creator are not specified, they are set to EPSF and MSWD */ /* because _I_ use word5 */ /* I see no reason to provide options to change the file names, */ /* but it could easily be done */ /* "file.ps" is taken to be the data fork, no assumptions are made here */ /* about its format, however it is presumably postscript code -- It seems */ /* to be necessary to convert line endings to macintosh endings ( ^M ) */ /* I think it more appropriate to do that conversion externally ( eg tr ) */ /* */ /* "file.pict" is a pict data file, which is massaged into the resource */ /* fork Its format _is_ important here. */ /* ppmtopict output is assumed, which ( for no apparent reason ) contains */ /* lots of null bytes prior to the actual data.. */ /* ( in other words this program will not work with other types of */ /* resources ) */ /* the format of the pict resource fork can be found in IM 1, page 128-131*/ /* many assumptions are 'hard wired' into this program -- eg we have */ /* exactly one resource, of type PICT */ /* */ /* It will be painfully obvious that this is the work of a novice C */ /* programmer, in fact the program is originally done in FORTRAN and (hand)*/ /* converted ( note the lack of struct's and such ) */ /* anyway, it works on several sun4-ish machines around here, your milage */ /* may vary */ #include <stdio.h> #include <sys/types.h> #ifdef notimeb #else #include <sys/timeb.h> #endif main (argc,argv) int argc; char **argv; { int i,j,ksize; unsigned long mtim=0,ctim=0,unixtime,sizef,realsizef; int ireslength,idatalength,ipad; FILE *pic,*bin, *ps; char outname[30],inname[30],word[4],byte[1],zero[1]; char ftyp[4]; char fcrea[4]; char macname[63], basename[30], psname[30], bbuf[128]; extern unsigned long time2mac(); if( argc <= 1 ) { fprintf(stderr, "usage ps-pict2macbin.c file.ps [ -type TYPE ][-creator CRTR ]\n"); exit(); } strcpy(basename,argv[1]); strcpy(inname,basename);strcat(inname,".pict"); strcpy(outname,basename);strcat(outname,".bin"); bzero(macname,63); strcpy(macname,basename); strcpy(psname,basename);strcat(psname,".ps"); fprintf(stderr,"opening pict file %s \n",inname); if( (pic=fopen(inname,"r")) == NULL ) {fprintf(stderr,"error opening file\n");exit();} fprintf(stderr,"opening output file %s \n",outname); if( (bin=fopen(outname,"w")) == NULL ) {fprintf(stderr,"error opening file\n");exit();} fprintf(stderr,"opening ps file %s \n",psname); if( (ps=fopen(psname,"r")) == NULL ) {fprintf(stderr,"error opening file\n");exit();} for(i=1;i<=128;i++)write_one(bin,0); /*leave room for info */ /* copy ps file over to binary */ idatalength=0;i=0; while (fread(byte, sizeof(*byte), 1, ps) > 0) { if(++i==129)i=1; ++idatalength; fwrite(byte, sizeof(*bbuf), 1, bin); } fclose(ps); for(i=i;i<128;i++)write_one(bin,0); /*pad to next 128 byte boundary */ /* write the pict resource from the pict data file */ fread(byte,sizeof(*byte),1,pic);i=1; while( strlen(byte)==0 ){fread(byte,sizeof(*byte),1,pic);i++;} ksize=256*ibyte(byte); fread(byte,sizeof(*byte),1,pic); ksize=ksize+ibyte(byte); /* length of actual resource data */ sizef=ftell(pic);fseek(pic,0l,2);realsizef=ftell(pic)-i+1;fseek(pic,sizef,0); if(ksize != realsizef)fprintf(stderr,"real length %i not reported length %i fixing...\n",realsizef,ksize); ireslength=256+realsizef+4+50; /* total length of resource fork */ write_header(bin,realsizef); for(i=1;i<=112;i++)write_one(bin,0); for(i=1;i<=128;i++)write_one(bin,0); /*reserver stuff */ write_four(bin,realsizef); /* length of resource data */ write_two(bin,ksize); /* length of resource data */ for( j=1;j<=realsizef-2;j++){ fread(byte,sizeof(*byte),1,pic); fwrite(byte,sizeof(*byte),1,bin); } /* resource map */ write_header(bin,realsizef);/* copy of header */ write_four(bin,0);write_two(bin,0); /* 6 null bytes ( reserved ) */ write_two(bin,0); /* attributes*/ write_two(bin,28); /* offset from beginning of map to type list */ write_two(bin,28+22); /* beg map to name list */ /* type list */ write_two(bin,0); /* only one resource type */ strcpy(word,"PICT"); fwrite(word,sizeof(word),1,bin);/* resource type */ write_two(bin,0); /* only one pict */ write_two(bin,10); /* begining of type list to reference list */ /* reference list */ write_two(bin,256); /* resource id */ write_one(bin,-1);write_one(bin,-1); /* no name for resource */ write_one(bin,0); /* attributes */ write_two(bin,0);write_one(bin,0) ; /* 3 byte offset within resourc */ write_four(bin,0); /* reserved */ /* pad file to nearest 128 byte boundary */ ipad=(ireslength/128+1)*128-ireslength; for(i=1;i<=ipad;i++)write_one(bin,0); /* this is the end of the resource fork, and the end of the file */ /* macbinary info header */ fseek(bin,0l,0);/* rewind so that we can write the info header */ write_one(bin,0); /* zero */ write_one(bin,strlen(macname)); /* length of file name */ fwrite(macname,sizeof(macname),1,bin); /* name padded to 63 bytes */ bcopy("MSWD",fcrea,4); bcopy("EPSF",ftyp,4); for( i=1;i<argc;i++ ) { if( strcmp(argv[i],"-type") == 0 )bcopy(argv[++i],ftyp,4); if( strcmp(argv[i],"-creator") == 0 )bcopy(argv[++i],fcrea,4); } fwrite(ftyp,sizeof(ftyp),1,bin);/* file type */ fwrite(fcrea,sizeof(fcrea),1,bin);/* file creator */ write_one(bin,1); /* should this be a zero? */ write_one(bin,0); write_four(bin,0);write_two(bin,0); write_one(bin,0); write_one(bin,0); write_four(bin,idatalength); /* length og data file */ write_four(bin,ireslength); /* length of resource file */ unixtime = time(&unixtime); ctim=time2mac(unixtime); write_four(bin,ctim); write_four(bin,mtim); /* all done */ } write_header(iu,kbytes) FILE *iu;int kbytes; { write_four(iu,256);/*c 4 bytes -> length of header+system+application, always 16+112+128=256*/ /*c next four bytes -> length of pict data + header + 4 bytes for size*/ write_four(iu,256+kbytes+4); /*c next four -> length of data*/ write_four(iu,kbytes+4); /*c next four -> length of map ( always same )*/ write_four(iu,50); } write_one(iu,k) int k ; FILE *iu ; { unsigned char byte[1]; byte[0]=k; fwrite(byte,sizeof(*byte),1,iu); } ibyte( b ) char *b; { int ibyte; ibyte=b[0]; if(ibyte < 0 )ibyte=ibyte+256; return(ibyte); } write_four(iu,k) unsigned long k ; FILE *iu ; { int k1,k2,l,n[4]; unsigned char byte[1]; n[0]=16777216;n[1]=65536;n[2]=256;n[3]=1; k1=0; for(l=0;l<4;l++) { k2=(k-k1)/n[l]; byte[0]=k2; fwrite(byte,sizeof(*byte),1,iu); k1=k1+k2*n[l]; } } write_two(iu,k) int k ; FILE *iu ; { int k1,k2,l,n[2]; unsigned char byte[1]; n[0]=256;n[1]=1; k1=0; for(l=0;l<2;l++) { k2=(k-k1)/n[l]; byte[0]=k2; fwrite(byte,sizeof(*byte),1,iu); k1=k1+k2*n[l]; } } #ifndef sysv typedef unsigned long ulong; /* 4 bytes */ #endif /* 'borrowed' from mcvert */ /* Convert Unix time (GMT since 1-1-1970) to Mac time (local since 1-1-1904) */ #define MACTIMEDIFF 0x7c25b080 /* Mac time of 00:00:00 GMT, Jan 1, 1970 */ /* Compatibility issues */ #ifdef BSD #define long2mac (ulong) htonl #else #define long2mac #endif ulong time2mac(time) ulong time; { #ifdef notimeb return long2mac( time + MACTIMEDIFF ); #else struct timeb tp; ftime(&tp); return long2mac(time + MACTIMEDIFF - 60 * (tp.timezone /*- 60 * tp.dstflag*/)); #endif } /* correcting for daylight savings time needs to be improved. */ SHAR_EOF fi # end of overwriting check if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else cat << \SHAR_EOF > 'makefile' version=1.3 # ccflags: # on sysv machines that do not have the timeb struct or ftime() # -Dnotimeb # system v unix # -Dsysv # bsd unix # -DBSD # i dont need any flags on my sparc.. ccflags= #to compile pbmtoepsi here ( rather than properly including it into the #pbmplus directory ) define the full path to the pbmplus directory #and run "make pbmtoepsi" pbmdirectory=/usr/tools/pbmplus #files to be included in the shell archive by "make shar" shfiles= README ps2eps-mac ps-pict2macb.c makefile test.ps er_echo.c st_echo ps2eps-mac.m pbmtoepsi.c #name of the shell archive archversion=ps2eps-mac${version}.shar all : ps-pict2macb er_echo ; uudecode test.eps.bin.uu ps-pict2macb : ps-pict2macb.o ; cc -o ps-pict2macb ps-pict2macb.o er_echo : er_echo.o ; cc -o er_echo er_echo.o shar : ${archversion} update : update${version}.shar clean : ; rm -f *.o *~ *# *-log *.bin *.ppm *.pict *.eps.* *.uu ${archversion} : ${shfiles} test.eps.bin ; uuencode test.eps.bin test.eps.bin > test.eps.bin.uu echo "---------${archversion}----cut here---" > ${archversion} shar ${shfiles} test.eps.bin.uu >> ${archversion} update${version}.shar : ps-pict2macb.c ps2eps-mac ../ps2macchanges ; cp ../ps2macchanges update${version}.shar echo "--------- update${version}.shar----cut here---" >>update${version}.shar shar ps2eps-mac ps-pict2macb.c >> update${version}.shar ps-pict2macb.o : ps-pict2macb.c ; cc ${ccflags} -c ps-pict2macb.c pbmtoepsi : pbmtoepsi.o ; cc -o pbmtoepsi pbmtoepsi.o ${pbmdirectory}/pbm/libpbm.a # the -Djustbb flag creates a 'crippled' pbmtoepsi which stops after reporting # the bounding box ( makes it just a little faster ) # remove it if you want to use pbmtoepsi for other things. pbmtoepsi.o : pbmtoepsi.c ; cc ${ccflags} -Djustbb -I${pbmdirectory} -I${pbmdirectory}/pbm -c pbmtoepsi.c er_echo.o : er_echo.c ; cc ${ccflags} -c er_echo.c test.eps.bin : ps-pict2macb ps2eps-mac test.ps ; ps2eps-mac test.ps new : ${archversion} ; cp ${archversion} .tmp-${archversion} rm -f * mv .tmp-${archversion} ${archversion} sh ${archversion} fast : fastps2eps-mac #removes all debugging code and comments #saves < 1 second run time, sigh fastps2eps-mac : ps2eps-mac ; echo "#!/bin/csh -f" > fastps2eps-mac sed -e '/^.*##debug.*$$/ d' -e '/^#.*/ d' ps2eps-mac >> fastps2eps-mac chmod u+x fastps2eps-mac SHAR_EOF fi # end of overwriting check if test -f 'test.ps' then echo shar: will not over-write existing file "'test.ps'" else cat << \SHAR_EOF > 'test.ps' %! 100 100 translate /l { lineto } def 1 1 moveto 9 1 l 9 9 l 1 1 l 1 9 l 5 13 l 9 9 l 1 9 l 9 1 l stroke SHAR_EOF fi # end of overwriting check if test -f 'er_echo.c' then echo shar: will not over-write existing file "'er_echo.c'" else cat << \SHAR_EOF > 'er_echo.c' /* er_echo.c george jefferson george@mech.seas.upenn.edu 4/12/92 */ /* replacement for the unix standard echo which writes to standard error */ /* rather than standard out. */ /* i wrote this 'cause brain-dead csh has no way to redirect to stderr, sigh */ /* if there is a better way ( besides using sh! ) i'd sure like to know.. */ /* */ /* accepts a -n flag to suppress a newline, just like the real echo */ /* */ /* creeping featuritis... the following flags are also recognised */ /* */ /* -cat -> read from standard input, write to standard output */ /* */ /* '-level n` sets the output level to n ( default 0 ) */ /* '-off n` sets the debug level to n ( default 0 ) */ /* output is supressed whenever the 'off' level is lower than t output level */ /* examples might help.... */ /* er_echo -off 1 my dog has -level 2 ticks and -level 1 fleas */ /* my dog has fleas */ /* er_echo -off 2 my dog has -level 2 ticks and -level 1 fleas */ /* my dog has ticks and fleas */ /* if combined with -cat, the _last_ occurance of each of these flags is used*/ /* */ /* -log outputfile -> output is _appended_ to outputfile */ /* rather than going to stderr */ /* multiple -log arguments are processed until a valid one is found */ /* eg er_echo "-log /etc/passwd -log a -log b hi" */ /* writes to "a" ( unless u r root! ) */ #include <stdio.h> main (argc,argv) int argc; char **argv; { int i,newline=1,iout=0,cat=0; FILE *logfile; char *byte[1],debug[3],off[3]; logfile=stderr; for( i = 1 ; i < argc ; i++ ) if( strcmp(argv[i],"-log") == 0 && ( logfile=fopen(argv[++i],"a") ) != NULL )break; if( ( logfile ) == NULL )logfile=fopen("/dev/null","a"); /* we were trying to redirect, I guess */ /* dont want to see this message */ strcpy(off,"0");strcpy(debug,"0"); for( i = 1 ; i < argc ; i++ ) { if( strcmp(argv[i],"-cat") == 0 )cat=1; else if(strcmp(argv[i],"-level") == 0 )strcpy(debug,argv[++i]); else if(strcmp(argv[i],"-off") == 0 )strcpy(off,argv[++i]); } if( cat == 1 && strcmp(off,debug) >= 0 ) /*write input to output */ { while(i=read(0,byte,1) != 0 ) { fprintf(logfile,"%s",byte); } exit(0); } else if( cat == 1) /* just dump input */ { while(i=read(0,byte,1) != 0 ); exit(0); } else /* write command line arguments to output */ { strcpy(off,"0");strcpy(debug,"0"); for( i = 1 ; i < argc ; i++ ) { if(strcmp(argv[i],"-n") == 0 )newline=0; else if(strcmp(argv[i],"-off") == 0 )strcpy(off,argv[++i]); else if(strcmp(argv[i],"-level") == 0 )strcpy(debug,argv[++i]); else if(strcmp(argv[i],"-cat") == 0 ); else if(strcmp(argv[i],"-log") == 0 )i++; else if(strcmp(off,debug) >= 0 ) { if(iout++!=0)fprintf(logfile," "); fprintf(logfile,"%s",argv[i]); } } if(newline != 0 && iout != 0 )fprintf(logfile,"\n"); exit(0); } } SHAR_EOF fi # end of overwriting check if test -f 'st_echo' then echo shar: will not over-write existing file "'st_echo'" else cat << \SHAR_EOF > 'st_echo' #!/bin/csh -f # see er_echo.c for an explination of usage.. set off = 0 set level = 0 while ( $#argv > 0 ) switch ( "$1" ) case -log breaksw case -level set level = $2 shift breaksw case -off set off = $2 shift breaksw case -cat set cat breaksw default if( $level <= $off )echo -n "$1 " set out breaksw endsw shift end if( $?out == 1 )echo " " if( $?cat == 0)exit if( $level <= $off )exec cat - exec cat - >/dev/null SHAR_EOF chmod +x 'st_echo' fi # end of overwriting check if test -f 'ps2eps-mac.m' then echo shar: will not over-write existing file "'ps2eps-mac.m'" else cat << \SHAR_EOF > 'ps2eps-mac.m' .TH ps2eps-mac 1 "Thu May 14 1992" .SH NAME ps2eps-mac \- converts arbitrary single page PostScript images to MacBinary EPS with PICT preview .SH SYNOPSIS \fBps2eps-mac [ -q | -batch ][ -8 | -24 ] [ \-widen \fI<n>\fB | \-widen unset ] [ \-debug \fI<level>\fB ] [ \-log \fI<logfile>\fB ] [ \-d \fI<directory>\fB | \-pipe | \-exec \fI<command>\fB | \-ftp \fI<ip>\fB ] \fIfile.ps\fR .SH DESCRIPTION \fBps2eps-mac\fR Version 1.0 takes an arbitrary PostScript file and creates an Encapsulated PostScript file in MacBinary format. This EPS file contains an embedded PICT resource which, when read by certain Mac programs (for example, MSWord5 and MacDraw Pro), will be displayed on the Mac screen, allowing for easy annotation of the image. When the output is printed, however, the PICT preview bitmap will be discarded and the actual, crisp PostScript will be sent to the printer instead. .LP By default, executing the command \fIps2eps-mac file.ps\fR will produce a file named \fIfile.eps.bin\fR. Transferred to a Mac via ftp (with "MacBinary" enabled on the Mac end and "binary" enabled on the UNIX end), the file will be re-named \fIfile.eps\fR. .LP When converting to MacBinary format, the default file type and file creator are listed as \fIEPSF\fR and \fIMSWD\fR, respectively. This means that double-clicking on the \fIfile.eps\fR Mac file will open the file with MSWord5. To change the default file type, set your \fBEPSTYPE\fR environment variable before running \fIps2eps-mac\fR; to change the default file creator, set \fBEPSCREATOR\fR. .SH OPTIONS .IP "\fb\-batch" 5 Do not prompt for approval when overwriting output or scratch files. .IP "\fb\-q" 5 Synonym for -batch .IP "\fB\-8" 5 .IP "\fB\-24" 5 Generate 8 or 24 bit ( color ) preview image. .IP "\fB\-widen \fI<n>\fR" 5 Set the amount (in points) by which to widen the BoundingBox. If the input file already contains a BoundingBox, -widen is ignored and the original box is assumed to be correct. Default: 1 point. .IP "\fB\-widen unset" 5 Use a simpler method of calculating the BoundingBox. This disables several features including the ability to widen the BoundingBox, and the utilization of existing BoundingBox information. This option will avoid some kinds of errors. .IP "\fB\-debug \fI<level>\fR" 5 Set the level of debug messages, from 0 (none) to 5 (all). Default: 1. .IP "\fB\-log \fI<logfile>\fR" 5 Set the name of the logfile in which to place debug messages. Default: messages are sent to stderr. .SH OUTPUT PROCESSING FLAGS These flags are mutually exclusive. If more than one is used, the last one specified on the command line is applied. Default: place output in the current directory. None of these options prevents the writing of scratch files to the current directory. .IP "\fB\-ftp \fI<ip>\fR" 5 Transfer output to specified ip address via ftp, then delete output. Assumes that no password is required to ftp ( see netrc(5) ) and issues commands to put NCSA telnet into macbinary mode. .IP "\fB\-exec \fI<command>\fR" 5 Execute \fI<command>\fR on output file, then delete output. Multi word commands must be quoted. Example -exec "sz -b" .IP "\fB\-pipe" 5 Send output macbinary to standard output. If a logfile name isn't given with the \fB\-log\fR option, errors are sent to \fIps2eps-mac.log\fR. .IP "\fB\-d \fI<directory>\fR" 5 Set the name of the directory in which to place the output file. "\fB\-d\fR stdout" is equivalent to \fB\-pipe\fR. .SH BUGS At the default debug level (1) some errors which result in an EPS file with no preview image are not reported. Debug = 2 may be a better default. .LP Color images require a %%BoundingBox: line in the source file, and cannot be created with \fI-widen unset\fR, or any setting which causes pbmtoepsi to run. 24 bit images may be stripped to 8 bit by ppmtopict. .LP The \fIps2eps-mac\fR script uses \fItr\fR to translate line endings. This is bound to mess up any binary stuff in the source PostScript, such as included fonts. You could try editing the script and playing around with the translation options. If you find a foolproof way to do the line ending translation, please send mail to george@mech.seas.upenn.edu. .SH AUTHOR George Jefferson, george@mech.seas.upenn.edu SHAR_EOF fi # end of overwriting check if test -f 'pbmtoepsi.c' then echo shar: will not over-write existing file "'pbmtoepsi.c'" else cat << \SHAR_EOF > 'pbmtoepsi.c' /* pbmtoepsi.c ** ** by Doug Crabill, based heavily on pbmtoascii ** ** Converts a pbm file to an encapsulated PostScript style bitmap. ** Note that it does NOT covert the pbm file to PostScript, only to ** a bitmap to be added to a piece of PostScript generated elsewhere. ** ** Copyright (C) 1988 by Jef Poskanzer. ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. */ /* modified by george jefferson george@mech.seas.upenn.edu ** when compiled with -Djustbb this program quits after reporting ** the bounding box information ** i have added exactly three lines, all marked /*jbb*/ */ #include "pbm.h" #if !defined(MAXINT) #define MAXINT (0x7fffffff) #endif main( argc, argv ) int argc; char *argv[]; { FILE *ifd; register bit **bits; int rows, cols, row, col, tot, count; int top = MAXINT, bottom = -MAXINT, left = MAXINT, right = -MAXINT; pbm_init( &argc, argv ); if ( argc > 2 ) pm_usage( "[pbmfile]" ); if ( argc == 2 ) ifd = pm_openr( argv[1] ); else ifd = stdin; bits = pbm_readpbm( ifd, &cols, &rows ); pm_close( ifd ); for (row = 0; row < rows; row++) { for (col = 0; col < cols; col++) { if (bits[row][col] == PBM_BLACK) { if (row < top) { top = row; } if (row > bottom) { bottom = row; } if (col < left) { left = col; } if (col > right) { right = col; } } } } printf("%%!PS-Adobe-2.0 EPSF-1.2\n"); printf("%%%%BoundingBox: %d %d %d %d\n", left, rows - bottom, right, rows - top); #ifndef justbb printf("%%%%BeginPreview: %d %d 1 %d\n", right - left + 1, bottom - top + 1, bottom - top + 1); for (row = top; row <= bottom; row++) { printf("%% "); count = 0; for (col = left; col <= right; col += 4) { tot = 0; if (bits[row][col] == PBM_BLACK) { tot += 8; } if (bits[row][col+1] == PBM_BLACK) { tot += 4; } if (bits[row][col+2] == PBM_BLACK) { tot += 2; } if (bits[row][col+3] == PBM_BLACK) { tot++; } printf("%x", tot); count++; } printf((count % 2) == 0 ? "\n" : "0\n"); } printf("%%%%EndImage\n"); printf("%%%%EndPreview\n"); #else justbb printf("%%%%End modified pbmtoepsi header\n"); /*justbb*/ #endif justbb exit( 0 ); } SHAR_EOF fi # end of overwriting check if test -f 'test.eps.bin.uu' then echo shar: will not over-write existing file "'test.eps.bin.uu'" else cat << \SHAR_EOF > 'test.eps.bin.uu' begin 644 test.eps.bin M AT97-T+F5P<P M !%4%-&35-71 $ "B " M6*9<WC@ E(5!3+4%D M;V)E+3(N,"!%4%-&+3$N,@TE)4)O=6YD:6YG0F]X.B Q,# @.3D@,3$Q(#$Q M- TE(0TQ,# @,3 P('1R86YS;&%T90TO;"![(&QI;F5T;R!](&1E9@TQ(#$@ M;6]V971O#3D@,2!L#3D@.2!L#3$@,2!L#3$@.2!L#34@,3,@; TY(#D@; TQ M(#D@; TY(#$@; US=')O:V4-#0T M M ! B8 $F ,@ M M M M M M 2(!(@ #P + !$"_PP _____P L M / $ "@ #P + )B "P #P + 2 M $@ @ 0 ( $ !____ M____ / L \ "P O8!!_T! 0 _ $)_@$# $! /T!"@(! M 0#] 0 _@$) 0$ ^P$" $!!@ !^ 0L" 0 _0$# $ 0P* 0 ! $! M $! $,!0$ 0$ /X! 0 !# 4! $! #^ 0$ 0P* 0 ! $! $! $+ M @$ /T! P ! $) 0$ ^P$" !!P !^0 ! 0$"]@$ _P 0 (F ! M)@ #( < #( %!)0U0 * 0#__P B end SHAR_EOF fi # end of overwriting check # End of shell archive exit 0