home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
fbm
/
src
/
pbm2ps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-24
|
8KB
|
257 lines
/*****************************************************************
* 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);
}