home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * pbm2ps.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
- *
- * Copyright (C) 1989,1990 by Michael Mauldin. Permission is granted
- * to use this file in whole or in part for any purpose, educational,
- * recreational or commercial, provided that this copyright notice
- * is retained unchanged. This software is available to all free of
- * charge by anonymous FTP and in the UUNET archives.
- *
- * pbm2ps.c:
- *
- * USAGE
- * % pbm2ps [ flags ] arguments
- *
- * BUGS
- * Will blow up if the title has PostScript special characters
- * in it (especially unbalanced parens)
- *
- * EDITLOG
- * LastEditDate = Sun Jun 24 23:55:37 1990 - Michael Mauldin
- * LastFileName = /usr2/mlm/src/misc/fbm/pbm2ps.c
- *
- * HISTORY
- * 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
- * Package for Release 1.0
- *
- * 16-Jun-89 Michael Mauldin (mlm) at Carnegie Mellon University
- * Beta release (version 0.95) mlm@cs.cmu.edu
- *
- * 14-Sep-88 Michael Mauldin (mlm) at Carnegie-Mellon University
- * Created.
- *****************************************************************/
-
- # include <stdio.h>
- # include <ctype.h>
-
- # define MAXBAD 10
-
- # define USAGE "pbm2ps [ -s ] [ scale ] < pbm > postscript"
-
- unsigned char *bits;
- int w, h;
- char title[80];
-
- /****************************************************************
- * main: Read a pbm format file and write it out as PostScript
- ****************************************************************/
-
- #ifndef lint
- static char *fbmid =
- "$FBM pbm2ps.c <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \
- code available free from MLM@CS.CMU.EDU and from UUNET archives$";
- #endif
-
- main (argc, argv)
- char *argv[];
- { int scale = -1, scribe = 0;
-
- /* Get option */
- while (--argc > 0 && (*++argv)[0] == '-')
- { while (*++(*argv))
- { switch (**argv)
- { case 's': scribe++; break;
- default: fprintf (stderr, "Usage: %s\n", USAGE);
- exit (1);
- }
- }
- }
-
- if (argc > 0 && (scale = atoi (argv[0])) < 1)
- { fprintf (stderr, USAGE); exit (1); }
-
- if (read_pbm (stdin) && write_ps (scale, scribe)) exit (0);
-
- exit (1);
- }
-
- /****************************************************************
- * read_pbm: Read a pbm bitmap into character array 'bits', setting
- * width, height, and title
- ****************************************************************/
-
- read_pbm (rfile)
- FILE *rfile;
- { int ch;
- register unsigned char *bmp, *tail;
- int badcnt=0;
-
- if ((ch = getc (rfile)) != 'P' || (ch = getc (rfile)) != '1')
- { fprintf (stderr, "bad magic number, input not PBM file\n");
- return (0);
- }
-
- title[0] = '\0';
-
- if ((w = pbm_getint (stdin)) < 0 || (h = pbm_getint (stdin)) < 0)
- { return (0); }
-
- bits = (unsigned char *) malloc (w*h);
-
- bmp = bits;
- tail = &bmp[h*w];
-
- /* Read bits, inverting so that 1=white and 0=black */
- while (bmp < tail && (ch = getc (rfile)) != EOF)
- { if (ch == '0') *bmp++ = 1;
- else if (ch == '1') *bmp++ = 0;
- else if (ch == '#') eatcomment ();
- else if (isspace (ch)) /* ignore it */ ;
- else if (++badcnt < MAXBAD)
- { fprintf (stderr, "Ignoring junk character '%c'\n", ch); }
- else
- { fprintf (stderr, "Too many junk characters, bye!\n"); exit (1); }
- }
-
- if (ch == EOF)
- { fprintf (stderr, "premature EOF, read %d of %d bits in [%dx%d]\n",
- (bmp - bits), (tail - bits), w, h);
- return (0);
- }
-
- return (1);
- }
-
- /*****************************************************************
- * pbm_getint: Read a number from a PBM file, ignoring comments
- *****************************************************************/
-
- pbm_getint (rfile)
- FILE *rfile;
- { register int ch;
- register int val = 0;
-
- while ((ch = getc (rfile)) != EOF)
- { if (ch == '#') eatcomment ();
- else if (isspace (ch)) /* ignore it */ ;
- else if (isdigit (ch)) break;
- else
- { fprintf (stderr, "Found junk character '%c' in header\n", ch);
- return (-1);
- }
- }
-
- while (isdigit (ch))
- { val = val*10 + ch - '0';
- ch = getc (rfile);
- }
-
- return (val);
- }
-
- /*****************************************************************
- * eatcomment: Read comments and look for titles
- *****************************************************************/
-
- eatcomment ()
- { char cmtbuf[80];
- register char *s;
-
- /* Read rest of line, remove trailing newline and skip over leading spaces */
- fgets (cmtbuf, sizeof (cmtbuf), stdin);
- cmtbuf[strlen (cmtbuf) - 1] = '\0';
- for (s=cmtbuf; isspace (*s); s++) ;
-
- /* If the comment contains the title, squirrel it away */
- if (!strncmp (s, "Title: ", 7)) strcpy (title, s+7);
- fprintf (stderr, "Reading '%s'\n", title);
- }
-
- /****************************************************************
- * write_ps: Write out a 1 bit deep bitmap as a PostScript file
- *
- * Output is centered with at least 1" left margin, 1/2" right,
- * top and bottom margins.
- *
- * The title is printed in 14 pt Times-Bold centered at the top.
- * One half inch at the top is reserved for the title
- ****************************************************************/
-
- # define BYTESPERLINE 32
- # define PSRES 300 /* printer resolution, dots per inch */
- # define PPINCH 72 /* Points per inch */
- # define PAGW 8.5 /* page width 8.5 inches */
- # define PAGH 11.0 /* page height 11 inches */
- # define MAXW 7.0 /* maximum image width 7 inches */
- # define MAXH 9.5 /* maximum image height 9.5 inches */
- # define LMRG 1.0 /* left margin 1 inche */
- # define BMRG 0.5 /* bottom margin 1/2 inche */
- # define TMRG 0.125 /* Title margin, 1/8 inch */
- # define FSIZ 14 /* Font size for title (before scaling to 300 dpi) */
-
- write_ps (scale, scribe)
- int scale, scribe;
- { register int x, y, k, byte, bytes=0;
- register unsigned char *bmp = bits;
- int dotsx, dotsy;
- double pwidth, pheight, ctrx, ctry;
-
- /* Pick the largest scale factor that makes the image fit */
- if (scale < 1)
- { dotsx = (int) MAXW * PSRES / w;
- dotsy = (int) MAXH * PSRES / h;
- scale = (dotsx < dotsy) ? dotsx : dotsy;
- if (scale < 1) scale = 1;
- }
-
- fprintf (stderr, "pbm2ps: scale %d\n", scale);
-
- /* Determine width and height of output in inches */
- pwidth = (double) w * scale;
- pheight = (double) h * scale;
- ctrx = ((double) MAXW / 2.0 + LMRG) * PSRES;
- ctry = ((double) MAXH / 2.0 + BMRG) * PSRES;
-
- printf ("%%%! %s\n\n", title[0] ? title : "PBM to PostScript");
- printf ("%lg %lg scale\n", (double) PPINCH / PSRES, (double) PPINCH / PSRES);
- if (title[0])
- { printf ("/centershow { dup stringwidth pop");
- printf (" 2 div 0 exch sub 0 rmoveto show } def\n");
- printf ("/Times-Bold findfont %lg scalefont setfont\n",
- (double) FSIZ * PSRES / PPINCH);
- printf ("%lg %lg moveto\n",
- ctrx, ctry + pheight / 2.0 + TMRG*PSRES);
- printf ("(%s) centershow\n\n", title);
- }
-
- printf ("/picstr 32 string def\n");
-
- if (!scribe)
- { printf ("%lg %lg translate\n", ctrx - pwidth / 2, ctry - pheight / 2); }
- printf ("%lg %lg scale\n", pwidth, pheight);
- printf ("%d %d 1 [ %d 0 0 -%d 0 %d ] ", w, h, w, h, h);
- printf ("{ currentfile picstr readhexstring pop }\n");
- printf ("image\n");
-
- for (y=0; y<h; y++)
- { for (x=0; x<w; x += 8)
- { byte = 0;
- for (k=0; k<8; k++)
- { byte = (byte << 1) | (((x+k) < w) ? *bmp++ : 0); }
-
- printf ("%02x", byte);
- if (++bytes % BYTESPERLINE == 0) printf ("\n");
- }
- }
-
- /* Pad so there are exactly BYTESPERLINE bytes in each line */
- if (bytes % BYTESPERLINE)
- { while (bytes++ % BYTESPERLINE) printf ("00");
- printf ("\n");
- }
-
- if (!scribe) printf ("showpage\n");
-
- return (1);
- }
-