home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 15
/
CD_ASCQ_15_070894.iso
/
news
/
683
/
hpgl312
/
hp2xx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-18
|
27KB
|
1,028 lines
/*
Copyright (c) 1991 - 1993 Heinz W. Werntges. All rights reserved.
Distributed by Free Software Foundation, Inc.
This file is part of HP2xx.
HP2xx is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing. Refer
to the GNU General Public License, Version 2 or later, for full details.
Everyone is granted permission to copy, modify and redistribute
HP2xx, but only under the conditions described in the GNU General Public
License. A copy of this license is supposed to have been
given to you along with HP2xx so you can know your rights and
responsibilities. It should be in a file named COPYING. Among other
things, the copyright notice and this notice must be preserved on all
copies.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
/** hp2xx : A converter of HPGL files into popular raster and vector formats
**
** xx = mf (MetaFont), eps (PostScript), pcl (HP-PCL Level3),
** pre(view), pcx (PaintBrush-Format), img (GEM),
** pic (ATARI bitmap), pbm (Portable Bitmap), ...
**
** (c) 1992, 1993 Heinz W. Werntges and the HP2xx team
**
** Author:
**
** HWW Heinz W. Werntges (werntges@convex.rz.uni-duesseldorf.de)
** Fruchtstr. 2, 4000 Duesseldorf 1, Germany
**
**
** Amiga stuff & PBM & ILBM by:
**
** CHL Claus H. Langhans (Claus_Langhans@wildcat.fido.de)
** Unter den Nussbaeumen 19, 6233 Kelkheim (Ts.), Germany
**
**
** Atari stuff & IMG by:
**
** NM Norbert Meyer (sorry - no email)
** Reinhold-Schneider-Str. 83, 4000 Duesseldorf 13
**
** AS Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de)
**
** JE Joern Eggers (II040EG@DTHAC11.bitnet)
**
**
** X11 previewer by:
**
** MSch Michael Schoene (michael@nero.uni-bonn.de)
** Karolinger Str. 81, 4000 Duesseldorf 1, Germany
**
**
** Many thanks to all the other fine people who supported HP2xx by testing,
** correcting, porting, suggesting improvements, and otherwise spending
** their time on HP2xx, especially:
**
** -- Michael Schmitz
** & Gerhard Steger for their invaluable help with VAX/VMS,
** -- Horst Szillat for his contributions to OS2 and PM programming,
** -- Juergen Gross for access to a HP 9000 machine
** -- Roland Emmerich for proofreading, beta-testing, and his HGC support
** -- Jon Gillian for valuable suggestions
**-------------------------------------------------------------------------
**/
/** hp2xx.c:
**
** 91/01/12 V 1.00 HWW PC version
** 91/01/17 V 1.01 HWW Disk swapping added
** 91/01/19 V 1.02 HWW Reorganized: mf mode revived, pcx mode added
** 91/01/29 V 1.03 HWW SUN portation; HP-specials added
** 91/01/31 V 1.04 HWW (-F) FF added
** 91/02/01 V 1.05 HWW Flag -S added (Deskjet specials)
** 91/02/15 V 1.06 HWW stdlib.h & VAX_C supported
** 91/02/19 V 2.01 HWW file unchanged, but new package release!
** 91/06/09 V 2.10 HWW (beta) More options; options x & y changed to o & O
** 91/06/15 V 2.11 HWW (beta) VGA option added; PCX bug (on SUN) removed
** 91/06/20 V 2.12 HWW Rotate (-r) option & Copyright added
** 91/06/20 V 2.12b HWW Minor reformatting
** 91/06/29 V 2.13a HWW PostScript support
** 91/08/28 V 2.14 HWW ATARI 32K format added (prelim.)
** 91/10/15 V 2.14c HWW atari & stad formats; hwtools.h eliminated
** 91/10/20 V 2.14d HWW ATARI-->pic (packing removed)
** 91/10/24 V 2.15 HWW ATARI-->pic stable now; "LT;" & "LT0;" supported
** 91/11/22 V 2.16b HWW "SPn;" support
** 92/01/12 V 2.17 HWW HPGL scanner improved, to_ps() debugged, ps --> eps,
** More portabel code (ATARI acknowledged)
** 92/02/06 V 2.18e HWW Better parser, IMG & various previews supported,
** preview control via -h, -w; -W removed!
** 92/02/21 V 2.19d HWW LB etc. supported, PG; (option -P) added
** 92/03/03 V 2.20c HWW Modes added: -m epic,em,pac(ATARI) / LB bugs fixed
** 92/04/15 V 2.20d HWW Width & height treated symmetrically now
** 92/04/28 V 2.20e HWW -m pre: -d, -D effective again, default 75; PBM added
** 92/05/02 V 2.21a HWW -m pre is default now. New opt: -l logfile
** 92/05/19 V 3.00c HWW Color support (VGA preview), multiple input files
** 92/05/25 V 3.00f HWW Color support (more modes)
** 92/06/09 V 3.01d HWW XT,YT,TL,SM supported; ATARI update acknowledged;
** Mode list added for easier expansion; debugged
** 92/10/20 V 3.02a HWW LT now fully supported
** 92/11/08 V 3.02b HWW Page range allowed
** 92/12/10 V 3.02c HWW Mode "cad" added; DJ version: bug fix extended;
** 92/12/12 V 3.02d HWW 2 bug fixes for option -f
** 92/12/16 V 3.03a HWW Option -t (+truesize) added
** 92/12/27 V 3.03b HWW -S int (for Deskjet color support)
** 93/01/02 V 3.10a HWW Source brushed up; ready for distribution
** 93/02/08 V 3.12a HWW Support of Joern Eggers' cs mode added (ATARI only)
** HAS_X11, HAS_SUNVIEW: added/modified
** 93/04/13 V 3.12b HWW UC added (A. Treindl), small changes; CMYK added,
** New previewer selection scheme
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "bresnham.h"
#include "hp2xx.h"
#include "getopt.h"
/**
** When adding your special mode, add a symbol here.
** Please not the alphabetical order (and keep it).
**/
typedef enum{
XX_CAD, XX_CS, XX_EM, XX_EPIC, XX_EPS, XX_ILBM, XX_IMG, XX_MF,
XX_PBM, XX_PCL, XX_PCX, XX_PAC, XX_PIC, XX_PRE,
XX_TERM /* Dummy: terminator */
} hp2xx_mode;
/**
** When adding your special mode, add a line here.
** Please not the alphabetical order (and keep it).
**/
static struct {
hp2xx_mode mode;
char *modestr;
} ModeList[] = {
{XX_CAD, "cad"}, /* LaTeX: TeXcad compatible output */
#ifdef ATARI
{XX_CS, "cs"}, /* LaTeX using \special{...} for C. Strunk's TeX */
#endif
{XX_EM, "em"}, /* LaTeX using \special{em:...} */
{XX_EPIC, "epic"},/* LaTeX using epic.sty macros */
{XX_EPS, "eps"}, /* Encapulated PostScript */
#ifdef AMIGA
{XX_ILBM, "ilbm"},/* Special AMIGA format */
#endif
{XX_IMG, "img"}, /* Digital Research IMG raster format */
{XX_MF, "mf"}, /* Metafont source output */
{XX_PBM, "pbm"}, /* Portable Bitmap */
{XX_PCL, "pcl"}, /* HP-PCL Level 5 printer code */
{XX_PCX, "pcx"}, /* Painbtbrush's PCX raster format */
#ifdef PIC_PAC
{XX_PAC, "pac"}, /* for ATARI, e.g. used by StaD */
{XX_PIC, "pic"}, /* for ATARI. Try to replace by IMG */
#endif
{XX_PRE, "pre"}, /* DEFAULT: Preview on screen */
{XX_TERM, ""}, /* Dummy: List terminator */
};
static Logfile_flag = FALSE;
void SilentWait (void)
{
char dummy[80];
/**
** Get anything typed including '\n' if stderr does NOT go to a file
** or else the user may be invisibly prompted
**/
if (!Logfile_flag)
fgets (dummy,80,stdin);
}
void Wait (void)
{
#ifdef UNIX
if (getenv("TERM") == (char *) NULL)
return;
#endif
printf ("\nPress <Return> to continue ...\n");
SilentWait ();
}
void print_supported_modes(void)
{
int i;
fprintf(stderr, "(%s", ModeList[0].modestr);
for (i=1; ModeList[i].mode != XX_TERM; i++)
fprintf(stderr, ",%s", ModeList[i].modestr);
fprintf(stderr, ")\n");
}
void Send_ID(void)
{
fprintf(stderr,"\n%s\n%s\n%s\n%s\n%s\n",
"hp2xx is free software and you are welcome to distribute copies of it",
" under certain conditions. There is absolutely no warranty for hp2xx!",
"For full details, read file COPYING (shipped along with this package),",
" or write to:\t\tFree Software Foundation, Inc.",
"\t\t\t675 Mass Ave, Cambridge, MA 02139, USA");
fprintf(stderr,"\n%s%s\n",
"HP2xx:\tA HPGL converter (xx = mf, eps, pcl, pcx, img ...)\n",
"\tV 3.12 (93/04/13) (c) 1991 - 1993 Heinz W. Werntges\n"
#ifdef AMIGA
"\tAmiga additions (V 2.00) by Claus Langhans (92/12/16)\n"
#endif /* AMIGA */
#ifdef ATARI
"\tAtari additions (V 2.10) by N. Meyer / J. Eggers / A. Schwab (93/01/xx)\n"
#endif /* ATARI */
);
}
void usage_msg (PAR *p)
{
if (p->quiet)
return;
Send_ID();
#ifdef ATARI
fprintf (stderr,"Usage:\tdouble-click on HP2XX.TTP, type parameters into\n");
fprintf (stderr,"\tcommand-line with following syntax:\n");
fprintf (stderr,"\t[options] [hpglfile]\n");
fprintf (stderr,"\n\t(if command-line offers not enough space for all parameters\n");
fprintf (stderr,"\tuse a command-line interpreter for starting HP2xx)\n");
#else
fprintf (stderr,"Usage:\thp2xx [options] [file1 [file2 ...]]\n");
#endif /* ATARI */
fprintf (stderr,"\tUnix: Filter usage (.. | hp2xx -q -f- [options] | ..) ok\n");
Wait();
fprintf (stderr,"\nOpt fmt defaults\tComment:\n");
fprintf (stderr,
"---------------------------------------------------------------------------\n");
fprintf (stderr,"-m strg %s\t\tMode ", p->mode); print_supported_modes();
fprintf (stderr,"-f strg (auto gen.)\tName of output file ('-' = to stdout)\n");
fprintf (stderr,"-l strg (stderr)\tName of log file\n");
fprintf (stderr,"-p strg %1d%1d%1d%1d%1d%1d%1d%1d\tPensize(s) (in 1/10 mm (mf,ps) or dots (rest)).\n",
p->pensize[1], p->pensize[2], p->pensize[3], p->pensize[4],
p->pensize[5], p->pensize[6], p->pensize[7], p->pensize[8]);
fprintf (stderr,"\t\t\t\"strg\" must consist of 1 to 8 digits '0'-'9'\n");
fprintf (stderr,"-c strg %1d%1d%1d%1d%1d%1d%1d%1d\tPen color(s) (see manual for details).\n",
p->pencolor[1], p->pencolor[2], p->pencolor[3], p->pencolor[4],
p->pencolor[5], p->pencolor[6], p->pencolor[7], p->pencolor[8]);
fprintf (stderr,"-P n:n %d:%d\t\tPage range (0:0 = all pages).\n",
p->first_page, p->last_page);
fprintf (stderr,"-q %s\t\tQuiet mode (no diagnostics)\n",
FLAGSTATE(p->quiet));
fprintf (stderr,"-r float%5.1f\t\tRotation angle [deg]. -r90 = landscape\n",
p->rotation);
fprintf (stderr,"-s strg %s\tName of swap file\n",
p->swapfile);
fprintf (stderr,"\nBitmap controls:\n");
fprintf (stderr,"-d int %d\t\tDPI value for x or x&y, if -D unused.\n",
p->dpi_x);
fprintf (stderr,"-D int %d\t\tDPI value for y ONLY\n", p->dpi_x);
/* x, not y! */
Wait();
fprintf (stderr,"\nPCL-exclusive options:\n");
fprintf (stderr,"-i %s\tPre-initialize printer\n",
FLAGSTATE (p->init_p));
fprintf (stderr,"-F %s\tSend a FormFeed at end\n",
FLAGSTATE(p->formfeed));
fprintf (stderr,"-S int %d\tUse Deskjet special commands (0=off, 1=B/W, 3=CMY, 4=CMYK)\n",
p->specials);
fprintf (stderr,"NOTE: \tOnly valid for -d: 300/150/100/75; -D invalid!\n");
fprintf (stderr,"\nPCL / PostScript / Preview options:\n");
fprintf (stderr,"-o float %5.1f\tX offset [mm] of picture\n", p->xoff);
fprintf (stderr,"-O float %5.1f\tY offset [mm] of picture\n", p->yoff);
fprintf (stderr,"\nSize controls:\n");
fprintf (stderr,"-a float %5.1f\tAspect factor (x/y correction). Valid: > 0.0\n",
p->aspectfactor);
fprintf (stderr,"-h float %5.1f\tHeight [mm] of picture\n",p->height);
fprintf (stderr,"-w float %5.1f\tWidth [mm] of picture\n",p->width );
fprintf (stderr,"-t %s\tShow true HPGL size. Disables -a -h -w !\n",
FLAGSTATE (p->truesize));
fprintf (stderr,"-x float -\tManual HPGL-coord range presetting: x0\n");
fprintf (stderr,"-X float -\tManual HPGL-coord range presetting: x1\n");
fprintf (stderr,"-y float -\tManual HPGL-coord range presetting: y0\n");
fprintf (stderr,"-Y float -\tManual HPGL-coord range presetting: y1\n");
#ifdef DOS
fprintf (stderr,"\n-V int %d\tVGA mode byte (decimal). Change at own risk!\n",
p->vga_mode);
#endif
Wait();
fprintf (stderr,"Corresponding long options:\n\n");
fprintf (stderr,
"hp2xx [--mode] [--colors] [--pensizes] [--pages] [--quiet]\n");
fprintf (stderr,"\t[--width] [--height] [--aspectfactor] [--truesize]\n");
fprintf (stderr,"\t[--x0] [--x1] [--y0] [--y1] [--xoffset] [--yoffset]\n");
fprintf (stderr,"\t[--DPI] [--DPI_x] [--DPI_y]\n");
fprintf (stderr,"\t[--outfile] [--logfile] [--swapfile]\n");
fprintf (stderr,"\t[--PCL_formfeed] [--PCL_init] [--PCL_Deskjet]\n");
#ifdef DOS
fprintf (stderr,"\t[--VGAmodebyte]");
#endif
fprintf (stderr,"\t[--help]\n");
#ifdef PURE_C
fprintf(stderr,"\nPress RETURN key\n");
getchar();
#endif
}
void reset_par (PAR *pp)
/**
** Reset some parameter struct elements which may have been changed
** by action() to their defaults
**/
{
pp->x0 = 1e10; /* HP7550A's range is about */
pp->x1 = -1e10; /* [-2^24, 2^24], so we're safe */
pp->y0 = 1e10;
pp->y1 = -1e10;
pp->pen = 1;
}
void preset_par (PAR *pp)
/**
** Pre-set constant parameter struct elements with reasonable defaults
**/
{
int i;
pp->logfile = "";
pp->outfile = "";
pp->swapfile = "hp2xx.swp";
pp->mode = "pre";
pp->aspectfactor = 1.0;
pp->xoff = 0.0;
pp->yoff = 0.0;
pp->height = 200.0;
pp->width = 200.0;
pp->truesize = FALSE;
pp->rotation = 0.0;
pp->first_page= 0;
pp->last_page = 0;
pp->init_p = FALSE;
pp->formfeed = FALSE;
pp->quiet = FALSE;
pp->specials = 0;
pp->dpi_x = 75;
pp->dpi_y = 0;
pp->vga_mode = 18; /* 0x12: VGA 640x480, 16 colors */
pp->maxpensize= 1; /* in pixel or 1/10 mm */
pp->maxcolor = 1; /* max. color index */
pp->pensize[0]= 0; /* in pixel or 1/10 mm */
pp->pencolor[0]= xxBackground;
for (i=1; i<=8; i++)
{
pp->pensize [i] = 1; /* in pixel or 1/10 mm */
pp->pencolor[i] = xxForeground;
}
pp->is_color = FALSE;
pp->Clut[xxBackground][0]= 255; pp->Clut[xxBackground][1] = 255;
pp->Clut[xxBackground][2]= 255;
pp->Clut[xxForeground][0]= 0; pp->Clut[xxForeground][1] = 0;
pp->Clut[xxForeground][2]= 0;
pp->Clut[xxRed][0] = 255; pp->Clut[xxRed][1] = 0;
pp->Clut[xxRed][2] = 0;
pp->Clut[xxGreen][0] = 0; pp->Clut[xxGreen][1] = 255;
pp->Clut[xxGreen][2] = 0;
pp->Clut[xxBlue][0] = 0; pp->Clut[xxBlue][1] = 0;
pp->Clut[xxBlue][2] = 255;
pp->Clut[xxCyan][0] = 0; pp->Clut[xxCyan][1] = 255;
pp->Clut[xxCyan][2] = 255;
pp->Clut[xxMagenta][0]= 255; pp->Clut[xxMagenta][1] = 0;
pp->Clut[xxMagenta][2]= 255;
pp->Clut[xxYellow][0] = 255; pp->Clut[xxYellow][1] = 255;
pp->Clut[xxYellow][2] = 0;
reset_par (pp);
}
void Send_Copyright(void)
/**
** Remnant of older (non-GNU) releases. Leave here if you like
**/
{
static unsigned char msg[] =
{0xaf,0xa8,0xcd,0xd5,0x97,0xdd,0xdd,0x9f,
0x85,0x8d,0xc6,0x8c,0x85,0xed,0x8b,0x85,
0xf2,0xc0,0xd7,0xcb,0xd1,0xc2,0xc0,0xd6,
0xaf,0xa8,0xa5};
unsigned char *p;
p = msg;
while (*p!=0xa5)
putc ((*p++ ^ 0xa5), stderr);
exit (100);
}
void autoset_outfile_name(PAR *pp, char *inp_name)
{
int len, i;
if (*pp->outfile=='-')/* If output explicitly to stdout: */
return; /* then nothing's to do here */
if (isalpha(*pp->outfile))/* If this lookks like an output file name: */
return; /* Just accept it! Add validity check later? */
len = strlen(inp_name);
if (!len) /* If input from stdin: */
{ /* then supply a default file name */
pp->outfile="hp2xx.out";
return;
}
if (strcmp(pp->mode,"pre") == 0)
return; /* If preview mode: */
/* then output file name is unused */
for (i=len-1; i; i--) /* Search for (last) '.' char in path */
if (inp_name[i] == '.')
break;
i++;
/**
** We can assume a valid inp_name file name here.
** If not, the following fopen() in main() will fail
** and no harm will be done by an incorrect output file name.
**/
if ((pp->outfile = malloc(len+2+strlen(pp->mode))) == NULL)
{
fprintf(stderr,"Error: No mem for output file name!\n");
perror ("autoset_outfile_name");
exit (ERROR);
}
strcpy(pp->outfile, inp_name);
if (i==1 || len-i > 3) /* No or non-DOS extension: Add mode string */
{
strcat(pp->outfile, ".");
strcat(pp->outfile, pp->mode); /* Mode string is extension! */
}
else
strcpy(pp->outfile+i, pp->mode); /* Replace extension */
}
void action (PAR *p, FILE *hd)
{
FILE *td;
PicBuf *picbuf;
DevPt Maxdotcoord;
hp2xx_mode xx_mode=XX_TERM;
int i;
if (!p->quiet)
Send_ID();
for (i=0; ModeList[i].mode != XX_TERM; i++)
if (strncmp(p->mode, ModeList[i].modestr,
strlen(ModeList[i].modestr)) == 0)
{
xx_mode = ModeList[i].mode;
break;
}
/**
** Read HPGL data, put them into compact temporary binary file, and obtain
** scaling data (xmin/xmax/ymin/ymax in plotter coordinates)
**/
#if defined(DOS) && defined (GNU)
/**
** GNU libc.a (DJ's DOS port) bug fix (part 1 of 2):
** tmpfile() does not seem to work!
** See code below for part 2/2 (removing hp2xx.$$$).
** NOTE:
** If program terminates abnormally,
** delete hp2xx.$$$ manually!!
**/
if ((td = fopen("hp2xx.$$$","w+b")) == NULL)
#elif defined(AMIGA)
if ((td = fopen("t:hp2xx.tmp","w+b")) == NULL)
#else
if ((td = tmpfile()) == NULL)
#endif
{
perror("hp2xx -- opening temporary file");
exit (1);
}
read_HPGL (p, hd, td, &Maxdotcoord);
if (hd != stdin)
fclose (hd);
/**********************************************************
** Vector modes:
**/
switch (xx_mode)
{
case XX_MF:
rewind (td); /* Rewind temp file after filling it*/
to_mftex(p, td, 0); /* Output conversion/generation */
fclose (td); /* Close & unlink temp file */
return;
case XX_EM:
rewind (td);
to_mftex(p, td, 1);
fclose (td);
return;
case XX_EPIC:
rewind (td);
to_mftex(p, td, 2);
fclose (td);
return;
case XX_CAD:
rewind (td);
to_mftex(p, td, 3);
fclose (td);
return;
#ifdef ATARI
case XX_CS:
rewind (td);
to_mftex(p, td, 4);
fclose (td);
return;
#endif
case XX_EPS:
rewind (td);
to_eps (p, td);
fclose (td);
return;
/* default: drop through */
default:
break;
}
/**********************************************************
** Common part for all pixel-oriented formats:
** Buffer allocation / vector-to-raster conversion
**/
/**
** 1) Allocate virtual plotter area
**/
Maxdotcoord.x += (p->maxpensize - 1);
Maxdotcoord.y += (p->maxpensize - 1);
if ((picbuf = allocate_PicBuf (&Maxdotcoord, p)) == NULL)
{
fprintf(stderr,"Fatal error: cannot allocate %d*%d picture buffer\n",
Maxdotcoord.x, Maxdotcoord.y);
exit(ERROR);
}
/**
** 2) Read vectors from temporary file and plot them in memory buffer
**/
tmpfile_to_PicBuf (picbuf, p, td);
fclose (td); /* Close & unlink tmpfile */
#if defined(DOS) && defined (GNU)
/**
** GNU libc.a (DJ's DOS port) bug fix (part 2 of 2):
**/
unlink ("hp2xx.$$$");
#endif
/**********************************************************
** Raster modes:
**/
switch (xx_mode)
{
case XX_PCL: PicBuf_to_PCL (picbuf,p); break; /* HP PCL Level 3 */
case XX_PCX: PicBuf_to_PCX (picbuf,p); break; /* Paintbrush PCX */
#ifdef PIC_PAC
case XX_PIC: PicBuf_to_PIC (picbuf,p); break; /* ATARI 32K format */
case XX_PAC: PicBuf_to_PAC (picbuf,p); break; /* ATARI STaD format */
#endif /* To be phased out! */
#ifdef AMIGA
case XX_ILBM: PicBuf_to_ILBM(picbuf,p); break; /* AMIGA IFF-ILBM fmt */
#endif
case XX_IMG: PicBuf_to_IMG (picbuf,p); break; /* GEM's IMG format */
case XX_PBM: PicBuf_to_PBM (picbuf,p); break; /* Portable BitMap fmt */
case XX_PRE:
/**********************************************************
** Previewers (depending on hardware platform):
**/
#if defined(HAS_DOS_DJGR)
PicBuf_to_DJ_GR (picbuf,p); break;
#elif defined(HAS_DOS_VGA)
PicBuf_to_VGA (picbuf,p); break;
#elif defined(HAS_OS2_EMX)
PicBuf_to_OS2 (picbuf,p); break;
#elif defined(HAS_OS2_PM)
PicBuf_to_PM (picbuf,p); break;
#elif defined(HAS_UNIX_X11)
PicBuf_to_X11 (picbuf,p); break;
#elif defined(HAS_UNIX_SUNVIEW)
PicBuf_to_Sunview(picbuf,p);break;
#elif defined(ATARI)
PicBuf_to_ATARI (picbuf,p); break;
#elif defined(AMIGA)
PicBuf_to_AMIGA (picbuf,p); break;
#elif defined(VAX)
PicBuf_to_UIS (picbuf,p); break;
#else
PicBuf_to_Dummy (); break;
#endif /* defined(...) */
/**********************************************************
** Done -- clean up
**/
default: fprintf(stderr,"%s: Not implemented!\n", p->mode); break;
}
free_PicBuf (picbuf, p->swapfile);
}
/**
** main(): Process command line & call action routine
**/
void main (int argc, char *argv[])
{
PAR par;
double width, height;
int c, i,j, longind;
char *p;
FILE *hd;
char *shortopts = "a:c:d:D:f:h:l:m:o:O:p:P:r:s:S:V:w:x:X:y:Y:FHiqt";
struct option longopts[] = {
{"mode", 1, NULL, 'm'},
{"pencolors", 1, NULL, 'c'},
{"pensizes", 1, NULL, 'p'},
{"pages", 1, NULL, 'P'},
{"quiet", 0, NULL, 'q'},
{"DPI", 1, NULL, 'd'},
{"DPI_x", 1, NULL, 'd'},
{"DPI_y", 1, NULL, 'D'},
{"PCL_formfeed",0, NULL, 'F'},
{"PCL_init", 0, NULL, 'i'},
{"PCL_Deskjet", 1, NULL, 'S'},
{"outfile", 1, NULL, 'f'},
{"logfile", 1, NULL, 'l'},
{"swapfile", 1, NULL, 's'},
{"aspectfactor",1, NULL, 'a'},
{"height", 1, NULL, 'h'},
{"width", 1, NULL, 'w'},
{"truesize", 0, NULL, 't'},
{"x0", 1, NULL, 'x'},
{"x1", 1, NULL, 'X'},
{"y0", 1, NULL, 'y'},
{"y1", 1, NULL, 'Y'},
{"xoffset", 1, NULL, 'o'},
{"yoffset", 1, NULL, 'O'},
#ifdef DOS
{"VGAmodebyte",1, NULL, 'V'},
#endif
{"help", 0, NULL, 'H'}
};
preset_par (&par);
width = par.width; /* Copy defaults */
height= par.height;
if (argc == 1)
{
usage_msg (&par);
exit (0);
}
while ((c=getopt_long(argc,argv, shortopts, longopts, &longind)) != EOF)
switch (c) /* Easy addition of options ... */
{
case 'a':
par.aspectfactor = atof (optarg);
if (par.aspectfactor <= 0.0)
{
fprintf(stderr,"Aspect factor: %g illegal\n",
par.aspectfactor);
exit(ERROR);
}
break;
case 'c':
i = strlen(optarg);
if ((i<1) || (i>8))
{
fprintf(stderr,"Invalid pencolor string: %s\n", optarg);
exit(ERROR);
}
for (j=1, p = optarg; j <= i; j++, p++)
{
switch (*p-'0')
{
case xxBackground:par.pencolor[j] = xxBackground; break;
case xxForeground:par.pencolor[j] = xxForeground; break;
case xxRed: par.pencolor[j] = xxRed; break;
case xxGreen: par.pencolor[j] = xxGreen; break;
case xxBlue: par.pencolor[j] = xxBlue; break;
case xxCyan: par.pencolor[j] = xxCyan; break;
case xxMagenta: par.pencolor[j] = xxMagenta; break;
case xxYellow: par.pencolor[j] = xxYellow; break;
default :
fprintf(stderr,
"Invalid color of pen %d: %c\n", j, *p);
exit(ERROR);
}
if (par.pencolor[j] != xxBackground &&
par.pencolor[j] != xxForeground)
par.is_color = TRUE;
}
break;
case 'd':
switch (par.dpi_x = atoi (optarg))
{
case 75:
break;
case 100:
case 150:
case 300:
if ((!par.quiet) && (strcmp(par.mode,"pcl")==0))
fprintf(stderr,
"Warning: DPI setting is no PCL level 3 feature!\n");
break;
default:
if ((!par.quiet) && (strcmp(par.mode,"pcl")==0))
fprintf(stderr,
"Warning: DPI value %d is invalid for PCL mode\n",
par.dpi_x);
break;
}
break;
case 'D':
par.dpi_y = atoi (optarg);
if ((!par.quiet) && (strcmp(par.mode,"pcl")==0))
fprintf(stderr,"Warning: %s\n",
"Different DPI for x & y is invalid for PCL mode");
break;
case 'F':
par.formfeed = TRUE;
break;
case 'f':
par.outfile = optarg;
break;
case 'h':
par.height = height = atof (optarg);
if (height < 0.1)
fprintf(stderr,
"Warning: Small height: %g mm\n", height);
if (height > 300.0)
fprintf(stderr,
"Warning: Huge height: %g mm\n", height);
break;
case 'i':
par.init_p = TRUE;
break;
case 'l':
par.logfile = optarg;
if (freopen(par.logfile, "w", stderr) == NULL)
{
perror ("Cannot open log file");
fprintf(stderr, "Error redirecting stderr\n");
fprintf(stderr, "Continuing with output to stderr\n");
}
else
Logfile_flag = TRUE;
break;
case 'm':
par.mode = optarg;
for (i=0; ModeList[i].mode != XX_TERM; i++)
if (strcmp(ModeList[i].modestr, par.mode) == 0)
break;
if (ModeList[i].mode == XX_TERM)
{
fprintf(stderr,
"'%s': unknown mode!\n", par.mode);
fprintf(stderr,"Supported are: ");
print_supported_modes();
Send_Copyright();
}
break;
case 'o':
par.xoff = atof (optarg);
if (par.xoff < 0.0)
{
fprintf(stderr,"Illegal X offset: %g < 0\n",
par.xoff);
exit(ERROR);
}
if (par.xoff > 210.0) /* About DIN A4 width */
{
fprintf(stderr,"Illegal X offset: %g > 210\n",
par.xoff);
exit(ERROR);
}
break;
case 'O':
par.yoff = atof (optarg);
if (par.yoff < 0.0)
{
fprintf(stderr,"Illegal Y offset: %g < 0\n",
par.yoff);
exit(ERROR);
}
if (par.yoff > 300.0) /* About DIN A4 height */
{
fprintf(stderr,"Illegal Y offset: %g > 300\n",
par.yoff);
exit(ERROR);
}
break;
case 'p':
i = strlen(optarg);
if ((i<1) || (i>8))
{
fprintf(stderr,"Invalid pensize string: %s\n", optarg);
exit(ERROR);
}
for (j=1, p = optarg; j <= i; j++, p++)
{
if ((*p < '0') || (*p > '9'))
{
fprintf(stderr,"Invalid size of pen %d: %c\n",
j, *p);
exit(ERROR);
}
par.pensize[j] = *p - '0';
if (par.maxpensize < par.pensize[j])
par.maxpensize = par.pensize[j];
}
break;
case 'P':
if (*optarg == ':')
{
par.first_page = 0;
optarg++;
if (sscanf(optarg,"%d", &par.last_page) != 1)
par.last_page = 0;
}
else
switch (sscanf(optarg,"%d%*c%d",
&par.first_page, &par.last_page))
{
case 1:
par.last_page = 0;
break;
case 2:
break;
default:
fprintf(stderr,"Illegal page range.\n");
usage_msg (&par);
exit(ERROR);
}
break;
case 'q':
par.quiet = TRUE;
break;
case 'r':
par.rotation = atof(optarg);
break;
case 'S':
par.specials = atoi (optarg);
break;
case 's':
par.swapfile = optarg;
break;
case 't':
par.truesize = TRUE;
break;
case 'V':
par.vga_mode = atoi (optarg);
break;
case 'w':
par.width = width = atof (optarg);
if (width < 0.1)
fprintf(stderr,
"Warning: Small width: %g mm\n", width);
if (width > 300.0)
fprintf(stderr,
"Warning: Huge width: %g mm\n", width);
break;
case 'x':
par.x0 = atof (optarg);
break;
case 'X':
par.x1 = atof (optarg);
break;
case 'y':
par.y0 = atof (optarg);
break;
case 'Y':
par.y1 = atof (optarg);
break;
case 'H':
case '?':
default:
usage_msg (&par);
exit (ERROR);
}
/**
** Place consistency checks here
** - I'm just not in the mood for writing them myself ...
**/
if (par.dpi_y == 0)
par.dpi_y = par.dpi_x;
if (optind == argc) /* No filename: use stdin */
{
autoset_outfile_name (&par, argv[optind]);
action (&par, stdin);
}
else for ( ; optind < argc; optind++)
{ /* Multiple-input file handling: */
autoset_outfile_name (&par, argv[optind]);
if ((hd=fopen (argv[optind], READ_BIN)) == NULL)
{
perror("hp2xx");
exit (ERROR);
}
action (&par, hd); /* action() closes file */
reset_par (&par);
par.width = width; /* Restore width/height */
par.height= height; /* Changed in hpgl.c ! */
}
if (*par.logfile)
fclose (stderr);
exit (0);
}