home *** CD-ROM | disk | FTP | other *** search
-
- /*+
- Name: prpcx.c
- Author: Kent J. Quirk
- Abstract: This program prints .PCX files (as created by PC Paintbrush
- and other software) on a PostScript printer by converting
- them to a PS-compatible image. The user can scale and
- position the image.
-
- Modified for ANSI C headers & autoscale: WJHinkle 5 June 1992
-
- -*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define BUFSIZE 100
-
- #include "pcx.h"
-
- typedef struct {
- int xpos;
- int ypos;
- int width;
- int height;
- int scale;
- int autoscale;
- int invert;
- int prt_res;
- int dumphdr;
- } MAPPING;
-
- /**** c o p y _ p s _ h e a d e r ****
- Abstract: Opens the PS header file and copies it to the output.
- Parameters: Filename of the current file (the .PS extension is added
- here) and the output file pointer.
- Returns: 0 if successful, 1 if failure.
- ****************************/
- char *copy_ps_header(char *name, FILE *outfile, char *stop)
- {
- static char buf[BUFSIZE];
- char *bp;
- static FILE *f = NULL;
- if (f == NULL)
- {
- strcpy(buf, name);
- if ((bp = strchr(buf, '.')) != NULL)
- *bp = 0;
- strcat(buf, ".ps"); /* open file with this name but .ps ext */
- if ((f = fopen(buf, "r")) == NULL)
- {
- fprintf(stderr, "Unable to open PostScript header file '%s'\n",
- buf);
- return(NULL);
- }
- }
- else
- {
- fputs(buf, outfile);
- }
- while (fgets(buf, BUFSIZE, f) != NULL)
- {
- if ((stop != NULL) && (strncmp(buf, stop, strlen(stop)) == 0))
- return(buf); /* bail out right now */
- fputs(buf, outfile);
- }
- fclose(f);
- f = NULL;
- return(NULL);
- }
-
- /**** d o f i l e ****
- Abstract: Processes a single PCX file.
- Parameters: char *filename - the input PCX filename (.PCX optional)
- MAPPING *map - the structure containing page position info
- char *psname - the PostScript prologue (.PS will be forced)
- FILE *outfile - the open output file
- Returns: 0 if successful, 1 if no file generated
- ****************************/
- int dofile(char *filename, MAPPING *map, char *psname, FILE *outfile)
- {
- FILE *f;
- PCX_HDR hdr;
- WORD i, j, xsize, ysize;
- BYTE *lineptr = NULL;
- char *t;
- char buf[BUFSIZE];
- long bbox_x, bbox_y;
- strcpy(buf, filename);
- if (strchr(buf, '.') == NULL)
- strcat(buf, ".pcx"); /* add .PCX if needed */
- if ((f = fopen(buf, "rb")) == NULL)
- {
- fprintf(stderr, "Unable to open '%s'\n", buf);
- return(1);
- }
- if (pcx_read_header(&hdr, f) == NULL)
- {
- fprintf(stderr, "Unable to read header for file '%s'.\n", buf);
- fclose(f);
- return(1);
- }
- if (map->dumphdr)
- {
- pcx_print_header(&hdr, stdout);
- return(1);
- }
- if (hdr.nplanes != 1)
- {
- fprintf(stderr, "Only able to read monochrome .PCX files.\n");
- fclose(f);
- return(1);
- }
- xsize = hdr.lorightx - hdr.upleftx + 1;
- ysize = hdr.lorighty - hdr.uplefty + 1;
-
- if (map->autoscale && hdr.display_xres)
- map->width = (long)map->prt_res * (long)map->width / hdr.display_xres;
- if (map->autoscale && hdr.display_yres)
- map->height = (long)map->prt_res * (long)map->height / hdr.display_yres;
-
- t = copy_ps_header(psname, outfile, "%%BoundingBox");
- bbox_x = (long)xsize * (long)map->width * (long)map->scale / 10000L;
- bbox_y = (long)ysize * (long)map->height * (long)map->scale / 10000L;
- bbox_x += map->xpos;
- bbox_y += map->ypos;
- sprintf(t, "%%%%BoundingBox: %d %d %ld %ld\n", map->xpos, map->ypos,
- bbox_x, bbox_y);
- t = copy_ps_header(psname, outfile, NULL);
-
- fprintf(outfile, "/bmap_wid %d def\n", xsize);
- fprintf(outfile, "/bmap_hgt %d def\n", ysize);
- fprintf(outfile, "/bpp %d def\n", hdr.bpp);
- fprintf(outfile, "/res %d def\n\n", map->prt_res);
- fprintf(outfile, "/x %d def\n", map->xpos);
- fprintf(outfile, "/y %d def\n\n", map->ypos);
- fprintf(outfile, "/scy %d 100 div def\n", map->height);
- fprintf(outfile, "/scx %d 100 div def\n", map->width);
- fprintf(outfile, "/scg %d 100 div def\n\n", map->scale);
- fprintf(outfile, "scaleit\n");
- fprintf(outfile, "imagedata\n\n");
-
- for (i=0; i<ysize; i++)
- {
- lineptr = pcx_next_line(&hdr, lineptr, f);
- if (map->invert) /* invert if necessary */
- for (j=0; j < xsize/8; j++)
- lineptr[j] = ~lineptr[j];
- for (j=0; j < xsize/8; j++)
- fprintf(outfile, "%02X", lineptr[j]);
- fprintf(outfile, "\n");
- }
- fprintf(outfile, "\nshowit\n\004");
- free(lineptr);
- fclose(f);
- return(0);
- }
-
- /**** u s a g e ****
- Abstract: Prints a usage message and dies.
- Parameters: None
- Returns: Never returns.
- ****************************/
- void usage(void)
- {
- printf("PRPCX: by Kent Quirk\n");
- printf(" Given a .PCX file, this program creates a PostScript file \n");
- printf(" which will print the image.\n");
- printf(" PRPCX [-wW] [-hH] [-xX] [-yY] [-sS] [-rR] [-d] [-i] filename\n");
- printf(" Options include: (units) [default]\n");
- printf(" -sSCA set overall scale factor (percent) [100]\n");
- printf(" -wWID set horizontal scale factor (percent) [100]\n");
- printf(" -hHGT set vertical scale factor (percent) [100]\n");
- printf(" -xPOS set horizontal position (points from left) [0]\n");
- printf(" -yPOS set vertical position (points from bottom) [0]\n");
- printf(" -rRES set printer resolution (dpi) [300]\n");
- printf(" -a auto-scale PCX dpi resolution to printer's [off]\n");
- printf(" -d dump PCX file info to stdout [off]\n");
- printf(" -i invert image [off]\n");
- printf(" -oFIL set output filename, or use SET PRPCX=filename\n");
- printf(" The defaults print the image at one pixel per device pixel\n");
- printf(" at the lower left corner of the page.\n");
- printf(" PRPCX.PS must be in the same directory as PRPCX.EXE.\n");
- exit(1);
- }
-
- /**** m a i n ****
- The main routine for PRPCX. Sets defaults, parses command line,
- and calls dofile().
- ****************************/
- int main(int argc, char *argv[])
- {
- int i;
- MAPPING map;
- FILE *outfile = stdout;
- char *outfname = NULL;
- char *filename = NULL;
- map.xpos = map.ypos = 0;
- map.width = map.height = map.scale = 100;
- map.autoscale = 0;
- map.invert = 0;
- map.prt_res = 300;
- map.dumphdr = 0;
- if (argc < 2)
- usage();
- for (i=1; i<argc; i++)
- {
- if (argv[i][0] == '-' || argv[i][0] == '/')
- {
- switch (argv[i][1])
- {
- case 'x': case 'X':
- map.xpos = atoi(argv[i]+2);
- break;
- case 'y': case 'Y':
- map.ypos = atoi(argv[i]+2);
- break;
- case 'h': case 'H':
- map.height = atoi(argv[i]+2);
- break;
- case 'w': case 'W':
- map.width = atoi(argv[i]+2);
- break;
- case 's': case 'S':
- map.scale = atoi(argv[i]+2);
- break;
- case 'r': case 'R':
- map.prt_res = atoi(argv[i]+2);
- break;
- case 'a': case 'A':
- map.autoscale = !map.autoscale;
- break;
- case 'i': case 'I':
- map.invert = !map.invert;
- break;
- case 'd': case 'D':
- map.dumphdr = 1;
- break;
- case 'o': case 'O':
- outfname = argv[i]+2;
- break;
- case '?':
- usage();
- break;
- default:
- fprintf(stderr, "Unknown option %s\n", argv[i]);
- usage();
- break;
- }
- }
- else /* process a file */
- {
- filename = argv[i];
- }
- }
- if ((outfname != NULL) || ((outfname = getenv("PRPCX")) != NULL))
- {
- if ((outfile = fopen(outfname, "w")) == NULL)
- {
- fprintf(stderr,"Unable to open output file %s", outfname);
- exit(1);
- }
- }
- i = dofile(filename, &map, argv[0], outfile);
- fclose(outfile);
- return(i);
- }
-
-