home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
fbm
/
src
/
fbps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-24
|
8KB
|
287 lines
/****************************************************************
* fbps.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.
*
* fbps: Convert a grayscale image to a PostScript file
*
* USAGE
* % fbps < image > postscript
*
* EDITLOG
* LastEditDate = Mon Jun 25 00:04:03 1990 - Michael Mauldin
* LastFileName = /usr2/mlm/src/misc/fbm/fbps.c
*
* HISTORY
* 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
* Package for Release 1.0
*
* 26-Aug-89 Paul Milazzo (milazzo) at BBN
* Beta release (version 0.96)
* Added rotation, big paper option
*
* 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
* Beta release (version 0.94) mlm@cs.cmu.edu
*
* 25-Apr-89 Paul Milazzo (milazzo) at BBN
* Added color postscript support
*
* 27-Aug-88 Michael Mauldin (mlm) at Carnegie-Mellon University
* Created.
*****************************************************************/
# include <stdio.h>
# include <math.h>
# include "fbm.h"
# define PAPERWIDTH 8.5 /* inches */
# define BIGPAPERWIDTH 11 /* inches */
# define PAPERHEIGHT 11 /* inches */
# define BIGPAPERHEIGHT 14 /* inches */
char *ps_chars();
# define USAGE \
"Usage: fbps [-tT] [-pP] [-b] [-r] [ -s ] [ -w<width> ] < foo.fbm > foo.PS"
#ifndef lint
static char *fbmid =
"$FBM fbps.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[];
{ register int i, j;
int rows, cols, rowlen;
double paperwidth, paperheight;
double maxwidth, maxheight;
double width = -1, height, llx, lly;
int bytcnt=0;
int bigpaper=0, dotitle=1, dosize=1, rotate=0, scribe=0;
char buf[BUFSIZ], *title=NULL, *creator=NULL;
long clock = time ((long *) NULL);
char *ctime ();
FBM image;
/* Clear the memory pointer so alloc_fbm won't be confused */
image.cm = image.bm = (unsigned char *) NULL;
/* Get the options */
while (--argc > 0 && (*++argv)[0] == '-')
{ while (*++(*argv))
{ switch (**argv)
{ case 't': dotitle = 1; break;
case 'T': dotitle = 0; break;
case 'p': dosize = 1; break;
case 'P': dosize = 0; break;
case 'r': rotate++; break;
case 'b': bigpaper++; break;
case 's': scribe++; break;
case 'w': width = atof (*argv+1); SKIPARG; break;
default: fprintf (stderr, "%s\n", USAGE);
exit (1);
}
}
}
if (!read_bitmap (&image, (char *) NULL))
{ exit (1); }
if ((image.hdr.planes != 1 && image.hdr.planes != 3) || image.hdr.clrlen > 0)
{ fprintf (stderr,
"Error:\tfbps only handles grayscale or unmapped color files\n");
fprintf (stderr, "\tUse the clr2gray filter to create grayscale first\n");
exit (1);
}
if (image.hdr.bits == 1)
{ fprintf (stderr, "Error:\tfbps cannot handle 1 bit deep bitmaps\n");
fprintf (stderr, "\tUse 'fbcat -P | pbm2ps' to convert %s\n",
"1bit files to Postscript");
exit (1);
}
/* Get title */
if (image.hdr.title && image.hdr.title[0])
{ title = image.hdr.title; }
/* Get width and height */
rows = image.hdr.rows;
cols = image.hdr.cols;
rowlen = image.hdr.rowlen;
paperwidth = bigpaper ? BIGPAPERWIDTH : PAPERWIDTH;
paperheight = bigpaper ? BIGPAPERHEIGHT : PAPERHEIGHT;
maxwidth = (rotate ? paperheight : paperwidth) - 1.5;
maxheight = (rotate ? paperwidth : paperheight) - 1.5;
/* Pick output size */
if (width < 0.0 || width > maxwidth)
{ width = maxwidth; }
height = width * image.hdr.aspect * (double) rows / cols;
if (height > maxheight)
{ width = width * maxheight / height; height = maxheight; }
/* Pick lower left corner */
if (scribe)
{ llx = lly = 0.0; }
else
{ llx = (paperwidth - (rotate ? height : width)) / 2.0;
lly = rotate ? width + (paperheight - width) / 2.0 :
(paperheight - height) / 2.0;
}
fprintf (stderr,
"FBM to PS \"%s\" width %1.3lf inches, height %1.3lf inches\n",
title ? title : "(untitled)", width, height);
/* Write out PostScript Header */
if (scribe)
{ printf ("%%! Scribe @graphic style PostScript\n");
if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
if (creator) { printf ("%%%%Creator: %s\n", ps_chars (creator)); }
printf ("%%%%CreationDate: %s", ctime (&clock));
printf ("/inch { 72 mul } def\n");
printf ("/picstr %d string def\n\n", BYTESPERLINE);
}
else
{ printf ("%%!\n");
if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
if (creator) { printf ("%%%%Creator: %s\n", ps_chars (creator)); }
printf ("%%%%CreationDate: %s", ctime (&clock));
printf ("%%%%Pages: 1\n");
printf ("%%%%DocumentFonts:%s%s\n",
dotitle ? " Times-Bold" : "",
dosize ? " Times-Roman" : "");
printf ("%%%%EndComments\n");
printf ("%%%%EndProlog\n");
printf ("%%%%Page: 1 1\n\n");
printf ("/inch { 72 mul } def\n");
printf ("/picstr %d string def\n\n", BYTESPERLINE);
if (dotitle && title)
{ printf ("/Times-Bold findfont 14 scalefont setfont\n");
printf ("%lg inch %lg inch moveto\n",
llx + width/2.0, lly + 0.125 + height);
printf ("(%s)\n", ps_chars (title));
printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n");
}
if (dosize)
{ printf ("/Times-Roman findfont 8 scalefont setfont\n");
printf ("%lg inch %lg inch moveto\n", llx + width, lly - 0.25);
sprintf (buf, "[ %d by %d pixels, %1.3lf %s, %1.2lf by %1.2lf inches ]",
image.hdr.cols, image.hdr.rows, image.hdr.aspect,
"aspect ratio", width, height);
printf ("(%s)\n", ps_chars (buf));
printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n");
}
}
printf ("gsave\n");
if (llx != 0.0 || lly != 0.0)
{ printf ("%lg inch %lg inch translate ", llx, lly); }
if (rotate)
{ fputs ("-90 rotate ", stdout); }
printf ("%lg inch %lg inch scale\n", width, height);
if (image.hdr.planes == 3) {
int plane;
int plnlen = image.hdr.plnlen;
int bits = image.hdr.bits;
/* use QMS colorimage operator */
printf ("/redScanLine %d string def\n", cols * 8 / bits);
printf ("/greenScanLine %d string def\n", cols * 8 / bits);
printf ("/blueScanLine %d string def\n", cols * 8 / bits);
printf ("%d %d %d [%d 0 0 %d 0 %d]\n",
cols, rows, bits, cols, -rows, rows);
puts ("{currentfile redScanLine readhexstring pop}");
puts ("{currentfile greenScanLine readhexstring pop}");
puts ("{currentfile blueScanLine readhexstring pop}");
puts ("true 3 colorimage");
for (j = 0; j < rows; j++) {
for (plane = 0; plane < 3; plane++) {
for (i = 0; i < cols; i++) {
printf ("%02x", image.bm[plane * plnlen + j * rowlen + i]);
if (++bytcnt % BYTESPERLINE == 0)
putchar ('\n');
}
bytcnt = 0;
putchar ('\n');
}
}
}
else {
printf ("%d %d 8 [%d 0 0 -%d 0 %d] ", cols, rows, cols, rows, rows);
printf ("{ currentfile picstr readhexstring pop }\n");
printf ("image\n");
/* Write out bitmap */
for (j=0; j < rows; j++)
{ for (i=0; i < cols; i++)
{ printf ("%02x", image.bm[j * rowlen + i]);
if (++bytcnt % BYTESPERLINE == 0) putchar ('\n');
}
}
}
/* Pad so there are exactly BYTESPERLINE bytes in each line */
if (bytcnt % BYTESPERLINE)
{ while (bytcnt++ % BYTESPERLINE) printf ("00");
printf ("\n");
}
printf ("grestore\n");
if (!scribe)
{ printf ("\nshowpage\n\n");
printf ("%%%%Trailer\n");
}
exit (0);
}
/****************************************************************
* ps_chars: Put in proper escapes so an arbitrary string works
* according to the PostScript definition of a literal
****************************************************************/
char *ps_chars (txt)
char *txt;
{ static char buf[512];
register char *s = buf;
char *index ();
for (; *txt; txt++)
{ if (index ("()\\", *txt))
{ *s++ = '\\'; *s++ = *txt; }
else if (*txt < ' ' || *txt > '~')
{ sprintf (s, "\\%03o", *txt & 0377); s += 4; }
else
{ *s++ = *txt; }
}
*s = '\0';
s = buf;
return (s);
}