home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 19 Printer / 19-Printer.zip / PRPCX2.ZIP / PRPCX.C < prev    next >
Text File  |  1992-06-05  |  9KB  |  271 lines

  1.  
  2. /*+
  3.     Name:       prpcx.c
  4.     Author:     Kent J. Quirk
  5.     Abstract:   This program prints .PCX files (as created by PC Paintbrush
  6.                 and other software) on a PostScript printer by converting
  7.                 them to a PS-compatible image.  The user can scale and
  8.                 position the image.
  9.  
  10.     Modified for ANSI C headers & autoscale: WJHinkle 5 June 1992
  11.  
  12. -*/
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #define BUFSIZE 100
  19.  
  20. #include "pcx.h"
  21.  
  22. typedef struct {
  23.     int xpos;
  24.     int ypos;
  25.     int width;
  26.     int height;
  27.     int scale;
  28.     int autoscale;
  29.     int invert;
  30.     int prt_res;
  31.     int dumphdr;
  32. } MAPPING;
  33.  
  34. /**** c o p y _ p s _ h e a d e r ****
  35.     Abstract:   Opens the PS header file and copies it to the output.
  36.     Parameters: Filename of the current file (the .PS extension is added
  37.                 here) and the output file pointer.
  38.     Returns:    0 if successful, 1 if failure.
  39. ****************************/
  40. char *copy_ps_header(char *name, FILE *outfile, char *stop)
  41. {
  42.     static char buf[BUFSIZE];
  43.     char *bp;
  44.     static FILE *f = NULL;
  45.     if (f == NULL)
  46.     {    
  47.         strcpy(buf, name);
  48.         if ((bp = strchr(buf, '.')) != NULL)
  49.             *bp = 0;
  50.         strcat(buf, ".ps");             /* open file with this name but .ps ext */
  51.         if ((f = fopen(buf, "r")) == NULL)
  52.         {
  53.             fprintf(stderr, "Unable to open PostScript header file '%s'\n",
  54.                 buf);
  55.             return(NULL);
  56.         }
  57.     }
  58.     else
  59.     {
  60.         fputs(buf, outfile);
  61.     }
  62.     while (fgets(buf, BUFSIZE, f) != NULL)
  63.     {
  64.         if ((stop != NULL) && (strncmp(buf, stop, strlen(stop)) == 0))
  65.             return(buf);                /* bail out right now */
  66.         fputs(buf, outfile);
  67.     }
  68.     fclose(f);
  69.     f = NULL;
  70.     return(NULL);
  71. }
  72.  
  73. /**** d o f i l e ****
  74.     Abstract:   Processes a single PCX file.
  75.     Parameters: char *filename - the input PCX filename (.PCX optional)
  76.                 MAPPING *map - the structure containing page position info
  77.                 char *psname - the PostScript prologue (.PS will be forced)
  78.                 FILE *outfile - the open output file
  79.     Returns:    0 if successful, 1 if no file generated
  80. ****************************/
  81. int dofile(char *filename, MAPPING *map, char *psname, FILE *outfile)
  82. {
  83.     FILE *f;
  84.     PCX_HDR hdr;
  85.     WORD i, j, xsize, ysize;
  86.     BYTE *lineptr = NULL;
  87.     char *t;
  88.     char buf[BUFSIZE];
  89.     long bbox_x, bbox_y;
  90.     strcpy(buf, filename);
  91.     if (strchr(buf, '.') == NULL)
  92.         strcat(buf, ".pcx");     /* add .PCX if needed */
  93.     if ((f = fopen(buf, "rb")) == NULL)
  94.     {
  95.         fprintf(stderr, "Unable to open '%s'\n", buf);
  96.         return(1);
  97.     }
  98.     if (pcx_read_header(&hdr, f) == NULL)
  99.     {
  100.         fprintf(stderr, "Unable to read header for file '%s'.\n", buf);
  101.         fclose(f);
  102.         return(1);
  103.     }
  104.     if (map->dumphdr)
  105.     {
  106.         pcx_print_header(&hdr, stdout);
  107.         return(1);
  108.     }
  109.     if (hdr.nplanes != 1)
  110.     {
  111.         fprintf(stderr, "Only able to read monochrome .PCX files.\n");
  112.         fclose(f);
  113.         return(1);
  114.     }
  115.     xsize = hdr.lorightx - hdr.upleftx + 1;
  116.     ysize = hdr.lorighty - hdr.uplefty + 1;
  117.  
  118.     if (map->autoscale && hdr.display_xres)
  119.         map->width = (long)map->prt_res * (long)map->width / hdr.display_xres;
  120.     if (map->autoscale && hdr.display_yres)
  121.         map->height = (long)map->prt_res * (long)map->height / hdr.display_yres;
  122.     
  123.     t = copy_ps_header(psname, outfile, "%%BoundingBox");
  124.     bbox_x = (long)xsize * (long)map->width  * (long)map->scale / 10000L;
  125.     bbox_y = (long)ysize * (long)map->height * (long)map->scale / 10000L;
  126.     bbox_x += map->xpos;
  127.     bbox_y += map->ypos;
  128.     sprintf(t, "%%%%BoundingBox: %d %d %ld %ld\n", map->xpos, map->ypos,
  129.             bbox_x, bbox_y);
  130.     t = copy_ps_header(psname, outfile, NULL);
  131.         
  132.     fprintf(outfile, "/bmap_wid %d def\n", xsize);
  133.     fprintf(outfile, "/bmap_hgt %d def\n", ysize);
  134.     fprintf(outfile, "/bpp %d def\n", hdr.bpp);
  135.     fprintf(outfile, "/res %d def\n\n", map->prt_res);
  136.     fprintf(outfile, "/x %d def\n", map->xpos);
  137.     fprintf(outfile, "/y %d def\n\n", map->ypos);
  138.     fprintf(outfile, "/scy %d 100 div def\n", map->height);
  139.     fprintf(outfile, "/scx %d 100 div def\n", map->width);
  140.     fprintf(outfile, "/scg %d 100 div def\n\n", map->scale);
  141.     fprintf(outfile, "scaleit\n");
  142.     fprintf(outfile, "imagedata\n\n");
  143.  
  144.     for (i=0; i<ysize; i++)
  145.     {
  146.         lineptr = pcx_next_line(&hdr, lineptr, f);
  147.         if (map->invert)                 /* invert if necessary */
  148.             for (j=0; j < xsize/8; j++)
  149.                 lineptr[j] = ~lineptr[j];
  150.         for (j=0; j < xsize/8; j++)
  151.             fprintf(outfile, "%02X", lineptr[j]);
  152.         fprintf(outfile, "\n");
  153.     }
  154.     fprintf(outfile, "\nshowit\n\004");
  155.     free(lineptr);
  156.     fclose(f);
  157.     return(0);
  158. }
  159.  
  160. /**** u s a g e ****
  161.     Abstract:   Prints a usage message and dies.
  162.     Parameters: None
  163.     Returns:    Never returns.
  164. ****************************/
  165. void usage(void)
  166. {
  167.     printf("PRPCX:  by Kent Quirk\n");
  168.     printf("   Given a .PCX file, this program creates a PostScript file \n");
  169.     printf("    which will print the image.\n");
  170.     printf(" PRPCX [-wW] [-hH] [-xX] [-yY] [-sS] [-rR] [-d] [-i] filename\n");
  171.     printf("   Options include:         (units) [default]\n");
  172.     printf("   -sSCA  set overall scale factor (percent) [100]\n");
  173.     printf("   -wWID  set horizontal scale factor (percent) [100]\n");
  174.     printf("   -hHGT  set vertical scale factor (percent) [100]\n");
  175.     printf("   -xPOS  set horizontal position (points from left) [0]\n");
  176.     printf("   -yPOS  set vertical position (points from bottom) [0]\n");
  177.     printf("   -rRES  set printer resolution (dpi) [300]\n");
  178.     printf("   -a     auto-scale PCX dpi resolution to printer's [off]\n");
  179.     printf("   -d     dump PCX file info to stdout [off]\n");
  180.     printf("   -i     invert image [off]\n");
  181.     printf("   -oFIL  set output filename, or use SET PRPCX=filename\n");
  182.     printf("   The defaults print the image at one pixel per device pixel\n");
  183.     printf("   at the lower left corner of the page.\n");
  184.     printf("   PRPCX.PS must be in the same directory as PRPCX.EXE.\n");
  185.     exit(1);
  186. }
  187.  
  188. /**** m a i n ****
  189.     The main routine for PRPCX.  Sets defaults, parses command line,
  190.     and calls dofile().
  191. ****************************/
  192. int main(int argc, char *argv[])
  193. {
  194.     int i;
  195.     MAPPING map;
  196.     FILE *outfile = stdout;
  197.     char *outfname = NULL;
  198.     char *filename = NULL;
  199.     map.xpos = map.ypos = 0;
  200.     map.width = map.height = map.scale = 100;
  201.     map.autoscale = 0;
  202.     map.invert = 0;
  203.     map.prt_res = 300;
  204.     map.dumphdr = 0;
  205.     if (argc < 2)
  206.         usage();
  207.     for (i=1; i<argc; i++)
  208.     {
  209.         if (argv[i][0] == '-' || argv[i][0] == '/')
  210.         {
  211.             switch (argv[i][1]) 
  212.             {
  213.             case 'x':  case 'X':
  214.                 map.xpos = atoi(argv[i]+2);
  215.                 break;
  216.             case 'y':  case 'Y':
  217.                 map.ypos = atoi(argv[i]+2);
  218.                 break;
  219.             case 'h':  case 'H':
  220.                 map.height = atoi(argv[i]+2);
  221.                 break;
  222.             case 'w':  case 'W':
  223.                 map.width = atoi(argv[i]+2);
  224.                 break;
  225.             case 's':  case 'S':
  226.                 map.scale = atoi(argv[i]+2);
  227.                 break;
  228.             case 'r': case 'R':
  229.                 map.prt_res = atoi(argv[i]+2);
  230.                 break;
  231.             case 'a': case 'A':
  232.                 map.autoscale = !map.autoscale;
  233.                 break;
  234.             case 'i': case 'I':
  235.                 map.invert = !map.invert;
  236.                 break;
  237.             case 'd': case 'D':
  238.                 map.dumphdr = 1;
  239.                 break;
  240.             case 'o': case 'O':
  241.                 outfname = argv[i]+2;
  242.                 break;
  243.             case '?':
  244.                 usage();
  245.                 break;
  246.             default:
  247.                 fprintf(stderr, "Unknown option %s\n", argv[i]);
  248.                 usage();
  249.                 break;
  250.             }
  251.         }
  252.         else                    /* process a file */
  253.         {
  254.             filename = argv[i];
  255.         }
  256.     }
  257.     if ((outfname != NULL) || ((outfname = getenv("PRPCX")) != NULL))
  258.     {
  259.         if ((outfile = fopen(outfname, "w")) == NULL)
  260.         {
  261.             fprintf(stderr,"Unable to open output file %s", outfname);
  262.             exit(1);
  263.         }
  264.     }
  265.     i = dofile(filename, &map, argv[0], outfile);
  266.     fclose(outfile);
  267.     return(i);
  268. }
  269.  
  270.  
  271.