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