home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1341 < prev    next >
Internet Message Format  |  1990-12-28  |  5KB

  1. From: phillips@pacific.cs.ubc.ca (George Phillips)
  2. Newsgroups: alt.sources
  3. Subject: PBM to Postscript converter
  4. Message-ID: <7871@ubc-cs.UUCP>
  5. Date: 16 May 90 01:33:25 GMT
  6.  
  7. Here is a filter which converts portable bitmaps (PBM) files into
  8. Postscript.  You'll need the PBM+ toolkit to compile the program
  9. (which you can get from expo.lcs.mit.edu in contrib/pbmplus.tar.Z or
  10. from any comp.sources.misc archive site).  pbmtolps doesn't use
  11. the image operator of Postscript but instead converts the image
  12. into raster lines (as suggested by someone in comp.lang.postscript).
  13. This means faster printing on most Postscript printers, but device
  14. independence gets thrown out the window (well, not too far out).
  15. Bitmaps that are the end result of some sort of dithering process
  16. will not work very well so don't try it on those types of images.
  17. On the other hand, the clustered dot dither of pgmtopbm looks ok.
  18. It should be great for typical fax data like images of text.
  19.  
  20. It generates encapsulated Postscript to the extent that a NeXT
  21. understands it.  It probably doesn't conform to the standard.
  22.  
  23. In short, it's a hack, but you can print things quicker with it.
  24.  
  25. --
  26. George Phillips phillips@cs.ubc.ca {alberta,uw-beaver,uunet}!ubc-cs!phillips
  27.  
  28.  
  29. /*
  30.  * pbmtolps -- convert a Portable BitMap into Postscript.  The
  31.  * output Postscript uses lines instead of the image operator to
  32.  * generate a (device dependent) picture which will be imaged
  33.  * much faster.
  34.  *
  35.  * The Postscript path length is constrained to be less that 1000
  36.  * points so that no limits are overrun on the Apple Laserwriter
  37.  * and (presumably) no other printers.
  38.  *
  39.  * To do:
  40.  *    make sure encapsulated format is correct
  41.  *    repitition of black-white strips
  42.  *    make it more device independent (is this possible?)
  43.  *
  44.  * Author:
  45.  *    George Phillips <phillips@cs.ubc.ca>
  46.  *    Department of Computer Science
  47.  *    University of British Columbia
  48.  */
  49.  
  50. #include <stdio.h>
  51. #include "pbm.h"
  52.  
  53. main(argc, argv)
  54. int        argc;
  55. char*    argv[];
  56. {
  57.     FILE*    fp;
  58.     bit*    bits;
  59.     int        row;
  60.     int        col;
  61.     int        rows;
  62.     int        cols;
  63.     int        format;
  64.     int        white;
  65.     int        black;
  66.     char*    name;
  67.     float    dpi = 300.0;
  68.     float    sc_rows;
  69.     float    sc_cols;
  70.     int        i;
  71.     char*    usage = "[ -dpi n ] [ pbmfile ]";
  72.  
  73.     pm_progname = argv[0];
  74.  
  75.     i = 1;
  76.     if (i < argc && !strcmp(argv[i], "-dpi")) {
  77.         if (i == argc - 1)
  78.             pm_usage(usage);
  79.         sscanf(argv[i + 1], "%f", &dpi);
  80.         i += 2;
  81.     }
  82.  
  83.     if (i < argc - 1)
  84.         pm_usage(usage);
  85.  
  86.     if (i == argc) {
  87.         fp = stdin;
  88.         name = "noname";
  89.     }
  90.     else
  91.         fp = pm_openr(name = argv[i]);
  92.  
  93.     pbm_readpbminit(fp, &cols, &rows, &format);
  94.     bits = pbm_allocrow(cols);
  95.  
  96.     sc_rows = (float)rows / dpi * 72.0;
  97.     sc_cols = (float)cols / dpi * 72.0;
  98.     
  99.     puts("%!PS-Adobe-2.0 EPSF-2.0");
  100.     puts("%%Creator: pbmtolps");
  101.     printf("%%%%Title: %s\n", name);
  102.     printf("%%%%BoundingBox: %f %f %f %f\n",
  103.         306.0 - sc_cols / 2.0,
  104.         396.0 - sc_rows / 2.0,
  105.         306.0 + sc_cols / 2.0,
  106.         396.0 + sc_rows / 2.0);
  107.     puts("%%EndComments");
  108.     puts("%%EndProlog");
  109.     puts("gsave");
  110.  
  111.     printf("%f %f translate\n", 306.0 - sc_cols / 2.0, 396.0 + sc_rows / 2.0);
  112.     printf("72 %f div dup neg scale\n", dpi);
  113.     puts("/a { 0 rmoveto 0 rlineto } def");
  114.     puts("/b { 0 row 1 add dup /row exch def moveto } def");
  115.     puts("/c { a b } def");
  116.     puts("/m { currentpoint stroke newpath moveto a } def");
  117.     puts("/n { currentpoint stroke newpath moveto b } def");
  118.     puts("/o { currentpoint stroke newpath moveto c } def");
  119.     puts("/row 0 def");
  120.     puts("newpath 0 0 moveto");
  121.  
  122.     for (row = 0; row < rows; row++) {
  123.         pbm_readpbmrow(fp, bits, cols, format);
  124.         /* output white-strip+black-strip sequences */
  125.         for (col = 0; col < cols; ) {
  126.             for (white = 0; col < cols && bits[col] == PBM_WHITE; col++)
  127.                 white++;
  128.             for (black = 0; col < cols && bits[col] == PBM_BLACK; col++)
  129.                 black++;
  130.             
  131.             if (black != 0)
  132.                 addstrip(white, black);
  133.         }
  134.         nextline();
  135.     }
  136.     puts("stroke grestore showpage");
  137.     puts("%%Trailer");
  138.  
  139.     pm_close(fp);
  140.  
  141.     exit(0);
  142. }
  143.  
  144. static int prev_white = -1;
  145. static int prev_black = -1;
  146. static char cmd = '\0';
  147. static int run = 1;
  148.  
  149. addstrip(white, black)
  150. int white;
  151. int black;
  152. {
  153.     if (cmd) {
  154. #ifdef RUN
  155.         if (white == prev_white && black == prev_black)
  156.             run++;
  157.         else {
  158.             if (run == 1)
  159. #endif
  160.                 printf("%d %d %c ", prev_black, prev_white, morepoints(cmd, 2));
  161. #ifdef RUN
  162.             else
  163.                 /* of course, we need to give a new command */
  164.                 printf("%d %d %d %c ",
  165.                     prev_white, prev_black, run,
  166.                     morepoints(cmd + 'f' - 'a', 2 * run));
  167.             run = 1;
  168.         }
  169. #endif
  170.     }
  171.     
  172.     prev_white = white;
  173.     prev_black = black;
  174.     cmd = 'a';
  175. }
  176.  
  177. nextline()
  178. {
  179.     /* need to check run, should have an outcommand */
  180.     if (cmd)
  181.         printf("%d %d %c\n", prev_black, prev_white, morepoints('c', 3));
  182.     else
  183.         printf("%c\n", morepoints('b', 1));
  184.     cmd = '\0';
  185. }
  186.  
  187. static int pointcount = 2;
  188.  
  189. morepoints(cmd, howmany)
  190. char    cmd;
  191. int        howmany;
  192. {
  193.     pointcount += 2;
  194.     if (pointcount > 1000) {
  195.         pointcount = 2;
  196.         cmd += 'm' - 'a';
  197.     }
  198.     return(cmd);
  199. }
  200.