home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume19 / fbm / part05 / fbps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-08  |  7.2 KB  |  261 lines

  1. /****************************************************************
  2.  * fbps.c: FBM Library 0.92 (Beta test) 27-Apr-89  Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  5.  * use this file in whole or in part provided that you do not sell it
  6.  * for profit and that this copyright notice is retained unchanged.
  7.  *
  8.  * fbps: Convert a grayscale image to a PostScript file
  9.  *
  10.  * USAGE
  11.  *    % fbps < image > postscript
  12.  *
  13.  * EDITLOG
  14.  *    LastEditDate = Thu Apr 27 10:06:15 1989 - Michael Mauldin
  15.  *    LastFileName = /usr2/mlm/src/misc/fbm/fbps.c
  16.  *
  17.  * HISTORY
  18.  * 27-Apr-89  Michael Mauldin (mlm) at Carnegie Mellon University
  19.  *    Beta release (version 0.92) mlm@cs.cmu.edu
  20.  *
  21.  * 25-Apr-89  Paul Milazzo (milazzo) at BBN
  22.  *    Added color postscript support
  23.  *
  24.  * 27-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  25.  *    Created.
  26.  *****************************************************************/
  27.  
  28. # include <stdio.h>
  29. # include <math.h>
  30. # include "fbm.h"
  31.  
  32. # define MAXWIDTH 7.0 /* inches */
  33. # define MAXHEIGHT 9.5 /* inches */
  34.  
  35. char *ps_chars();
  36.  
  37. # define USAGE \
  38. "Usage: fbps [-tT] [-pP] [ -s ] [ -w<width> ] < foo.fbm > foo.PS"
  39.  
  40. #ifndef lint
  41. static char *fbmid =
  42.     "$FBM fbps.c <0.92> 27-Apr-89  (C) 1989 by Michael Mauldin$";
  43. #endif
  44.  
  45. main (argc, argv)
  46. char *argv[];
  47. { register int i, j;
  48.   int rows, cols, rowlen;
  49.   double width = -1, height, llx, lly;
  50.   int bytcnt=0;
  51.   int dotitle=1, dosize=1, scribe=0;
  52.   char buf[BUFSIZ], *title=NULL, *creator=NULL;
  53.   long clock = time ((long *) NULL);
  54.   char *ctime ();
  55.   FBM image;
  56.  
  57.   /* Clear the memory pointer so alloc_fbm won't be confused */
  58.   image.cm  = image.bm  = (unsigned char *) NULL;
  59.  
  60.   /* Get the options */
  61.   while (--argc > 0 && (*++argv)[0] == '-')
  62.   { while (*++(*argv))
  63.     { switch (**argv)
  64.       { case 't':    dotitle = 1; break;
  65.     case 'T':    dotitle = 0; break;
  66.     case 'p':    dosize = 1; break;
  67.     case 'P':    dosize = 0; break;
  68.     case 's':    scribe++; break;
  69.     case 'w':    width = atof (*argv+1); SKIPARG; break;
  70.     default:    fprintf (stderr, "%s\n", USAGE);
  71.             exit (1);
  72.       }
  73.     }
  74.   }
  75.  
  76.   if (!read_bitmap (&image, (char *) NULL))
  77.   { exit (1); }
  78.  
  79.   if ((image.hdr.planes != 1 && image.hdr.planes != 3) || image.hdr.clrlen > 0)
  80.   { fprintf (stderr,
  81.          "Error:\tfbps only handles grayscale or unmapped color files\n");
  82.     fprintf (stderr, "\tUse the clr2gray filter to create grayscale first\n");
  83.     exit (1);
  84.   }
  85.  
  86.   if (image.hdr.bits == 1)
  87.   { fprintf (stderr, "Error:\tfbps cannot handle 1 bit deep bitmaps\n");
  88.     fprintf (stderr, "\tUse 'fbcat -P | pbm2ps' to convert %s\n",
  89.          "1bit files to Postscript");
  90.     exit (1);
  91.   }
  92.  
  93.   /* Get title */
  94.   if (image.hdr.title && image.hdr.title[0])
  95.   { title = image.hdr.title; }
  96.  
  97.   /* Get width and height */
  98.   rows = image.hdr.rows;
  99.   cols = image.hdr.cols;
  100.   rowlen = image.hdr.rowlen;
  101.  
  102.   /* Pick output size */
  103.   if (width < 0.0 || width > MAXWIDTH)
  104.   { width = MAXWIDTH; }
  105.   
  106.   height = width * image.hdr.aspect * (double) rows / cols;
  107.     
  108.   if (height > MAXHEIGHT)
  109.   { width = width * MAXHEIGHT / height; height = MAXHEIGHT; }
  110.   
  111.   /* Pick lower left corner */
  112.   if (scribe)
  113.   { llx = lly = 0.0;  }
  114.   else
  115.   { llx = (8.0 - width) / 2.0 + 0.5;
  116.     lly = (11.0 - height) / 2.0;
  117.   }
  118.  
  119.   fprintf (stderr,
  120.        "FBM to PS \"%s\" width %1.3lf inches, height %1.3lf inches\n",
  121.        title ? title : "(untitled)", width, height);
  122.  
  123.   /* Write out PostScript Header */
  124.   if (scribe)
  125.   { printf ("%%! Scribe @graphic style PostScript\n");
  126.     if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
  127.     if (creator) { printf ("%%%%Creator:  %s\n", ps_chars (creator)); }
  128.     printf ("%%%%CreationDate: %s", ctime (&clock));
  129.  
  130.     printf ("/inch { 72 mul } def\n");
  131.     printf ("/picstr %d string def\n\n", BYTESPERLINE);
  132.   }
  133.   else
  134.   { printf ("%%!\n");
  135.     if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
  136.     if (creator) { printf ("%%%%Creator:  %s\n", ps_chars (creator)); }
  137.     printf ("%%%%CreationDate: %s", ctime (&clock));
  138.     printf ("%%%%Pages: 1\n");
  139.     printf ("%%%%DocumentFonts:%s%s\n",
  140.         dotitle ? " Times-Bold" : "",
  141.         dosize ?  " Times-Roman" : "");
  142.     printf ("%%%%EndComments\n");
  143.     printf ("%%%%EndProlog\n");
  144.     printf ("%%%%Page: 1 1\n\n");
  145.  
  146.     printf ("/inch { 72 mul } def\n");
  147.     printf ("/picstr %d string def\n\n", BYTESPERLINE);
  148.  
  149.     if (dotitle && title)
  150.     { printf ("/Times-Bold findfont 14 scalefont setfont\n");
  151.       printf ("%lg inch %lg inch moveto\n", 
  152.         llx + width/2.0, lly + 0.125 + height);
  153.       printf ("(%s)\n", ps_chars (title));
  154.       printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n");
  155.     }
  156.   
  157.     if (dosize)
  158.     { printf ("/Times-Roman findfont 8 scalefont setfont\n");
  159.             printf ("%lg inch %lg inch moveto\n", llx + width, lly - 0.25);
  160.       sprintf (buf, "[ %d by %d pixels, %1.3lf %s, %1.2lf by %1.2lf inches ]",
  161.            image.hdr.cols, image.hdr.rows, image.hdr.aspect,
  162.            "aspect ratio", width, height);
  163.       printf ("(%s)\n", ps_chars (buf));
  164.       printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n");
  165.     }
  166.  
  167.   }
  168.  
  169.   printf ("gsave\n");
  170.  
  171.   if (llx != 0.0 || lly != 0.0)
  172.   { printf ("%lg inch %lg inch translate ", llx, lly); }
  173.   
  174.   printf ("%lg inch %lg inch scale\n", width, height);
  175.  
  176.   if (image.hdr.planes == 3) {
  177.     int plane;
  178.     int plnlen = image.hdr.plnlen;
  179.     int bits = image.hdr.bits;
  180.  
  181.     /* use QMS colorimage operator */
  182.  
  183.     printf ("/redScanLine %d string def\n", cols * 8 / bits);
  184.     printf ("/greenScanLine %d string def\n", cols * 8 / bits);
  185.     printf ("/blueScanLine %d string def\n", cols * 8 / bits);
  186.  
  187.     printf ("%d %d %d [%d 0 0 %d 0 %d]\n",
  188.         cols, rows, bits, cols, -rows, rows);
  189.     puts ("{currentfile redScanLine readhexstring pop}");
  190.     puts ("{currentfile greenScanLine readhexstring pop}");
  191.     puts ("{currentfile blueScanLine readhexstring pop}");
  192.     puts ("true 3 colorimage");
  193.  
  194.     for (j = 0; j < rows; j++) {
  195.         for (plane = 0; plane < 3; plane++) {
  196.         for (i = 0; i < cols; i++) {
  197.             printf ("%02x", image.bm[plane * plnlen + j * rowlen + i]);
  198.             if (++bytcnt % BYTESPERLINE == 0)
  199.             putchar ('\n');
  200.         }
  201.         bytcnt = 0;
  202.         putchar ('\n');
  203.         }
  204.     }
  205.   }
  206.   else {
  207.     printf ("%d %d 8 [%d 0 0 -%d 0 %d] ", cols, rows, cols, rows, rows);
  208.     printf ("{ currentfile picstr readhexstring pop }\n");
  209.     printf ("image\n");
  210.   
  211.     /* Write out bitmap */
  212.     for (j=0; j < rows; j++)  
  213.     { for (i=0; i < cols; i++)
  214.       { printf ("%02x", image.bm[j * rowlen + i]);
  215.  
  216.         if (++bytcnt % BYTESPERLINE == 0) putchar ('\n');
  217.       }
  218.   }
  219.  
  220.   }
  221.  
  222.   /* Pad so there are exactly BYTESPERLINE bytes in each line */
  223.   if (bytcnt % BYTESPERLINE)
  224.   { while (bytcnt++ % BYTESPERLINE) printf ("00");
  225.     printf ("\n");
  226.   }
  227.   
  228.   printf ("grestore\n");
  229.  
  230.   if (!scribe)
  231.   { printf ("\nshowpage\n\n");
  232.     printf ("%%%%Trailer\n");
  233.   }
  234.  
  235.   exit (0);
  236. }
  237.  
  238. /****************************************************************
  239.  * ps_chars: Put in proper escapes so an arbitrary string works
  240.  *         according to the PostScript definition of a literal
  241.  ****************************************************************/
  242.  
  243. char *ps_chars (txt)
  244. char *txt;
  245. { static char buf[512];
  246.   register char *s = buf;
  247.   char *index ();
  248.   
  249.   for (; *txt; txt++)
  250.   { if (index ("()\\", *txt))
  251.     { *s++ = '\\'; *s++ = *txt; }
  252.     else if (*txt < ' ' || *txt > '~')
  253.     { sprintf (s, "\\%03o", *txt & 0377); s += 4; }
  254.     else
  255.     { *s++ = *txt; }
  256.   }
  257.   *s = '\0';
  258.   s = buf;
  259.   return (s);
  260. }
  261.