1
/* @(#)bdf2ps.c 19.1 (ES0-DMD) 02/25/03 14:35:14 */
2
/*===========================================================================
3
Copyright (C) 1995 European Southern Observatory (ESO)
5
This program is free software; you can redistribute it and/or
6
modify it under the terms of the GNU General Public License as
7
published by the Free Software Foundation; either version 2 of
8
the License, or (at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public
16
License along with this program; if not, write to the Free
17
Software Foundation, Inc., 675 Massachusetss Ave, Cambridge,
20
Correspondence concerning ESO-MIDAS should be addressed as follows:
21
Internet e-mail: midas@eso.org
22
Postal address: European Southern Observatory
23
Data Management Division
24
Karl-Schwarzschild-Strasse 2
25
D 85748 Garching bei Muenchen
27
===========================================================================*/
29
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
30
.COPYRIGHT (c) 1997 European Southern Observatory
33
.AUTHOR Preben J. Grosbol [ESO/IPG]
34
.KEYWORDS MIDAS bdf format, PostScript, conversion
35
.PURPOSE Convert MIDAS bdf files to PostScript format
37
.VERSION 1.0 1992-Jun-23 : Creation, PJG
38
.VERSION 1.1 1992-Oct-05 : Better LUT's, PJG
39
.VERSION 1.2 1993-Apr-14 : LUT tables and true color, PJG
40
.VERSION 1.3 1993-Jul-01 : add frame size and origin, PJG
41
.VERSION 1.4 1993-Nov-12 : Correct error + add options, PJG
42
.VERSION 1.5 1993-Nov-25 : Separate X/Y scales, PJG
43
.VERSION 1.6 1994-Mar-18 : Correct error in scaling, PJG
44
.VERSION 1.7 1994-May-03 : Add option for frame box, PJG
45
.VERSION 1.8 1994-May-19 : Explicit check of SC error returns, PJG
46
.VERSION 1.9 1994-Oct-09 : Write usage on wrong option, PJG
47
.VERSION 1.91 1997-Feb-18 : Explicit cast in SCFMAP/GET, PJG
48
.VERSION 1.95 1997-May-15 : Initiate pointers to NULL, PJG
49
.VERSION 2.00 1998-Feb-27 : Use 'strtok' and add line/arc draw, PJG
50
.VERSION 2.10 1998-Mar-03 : Correct algorithm for neg. step size, PJG
51
------------------------------------------------------------------------*/
52
#include <stdlib.h> /* Standard Library definitions */
53
#include <stdio.h> /* Standard I/O definitions */
54
#include <math.h> /* Standard Mathmatical library */
55
#include <string.h> /* Standard string definitions */
56
#include <time.h> /* Time library */
57
#include <osparms.h> /* MIDAS OS-definitions */
58
#include <midas_def.h> /* MIDAS definitions */
59
#include <fitsfmt.h> /* Data formats */
60
#include <fitsdef.h> /* FITS definitions */
61
#include <fitskwt.h> /* FITS Table definitions */
63
#define MXPARM 32 /* Max. no. of parameters */
64
#define MXNAME 64 /* Max size of name string */
65
#define MXLINE 128 /* Max. size of print line */
66
#define MXITF 256 /* Max size of LUT/ITT tables */
67
#define PSPAGE "A4P" /* Default page format */
68
#define PSFONT "Helvetica" /* Standard PS font used */
69
#define PSNAME "psimage.ps" /* Default name for output file */
72
char *name; /* Name of page format */
73
double xsize; /* Total size of page in X (cm) */
74
double ysize; /* Total size of page in Y (cm) */
75
double xmar; /* Page margin in X (cm) */
76
double ymar; /* Page margin in Y (cm) */
77
double angle; /* Angle of page ref. Portait */
80
static PAGE page[] = { {"A4P", 21.00, 29.73, 1.0, 1.0, 0.0},
81
{"A4L", 21.00, 29.73, 1.0, 1.0, 90.0},
82
{"A3P", 29.73, 42.00, 1.0, 1.0, 0.0},
83
{"A3L", 29.73, 42.00, 1.0, 1.0, 90.0},
84
{"S4P", 21.00, 29.73, 2.0, 3.0, 0.0},
85
{"S4L", 21.00, 29.73, 2.0, 3.0, 90.0},
86
{(char *) 0, 0.0, 0.0, 0.0, 0.0, 0.0} };
88
/* Definition of parameter list */
89
static char *plist[] = {"i+:Input file",
93
"r+:Resolution per cm",
96
"z+:Z-cut levels (low,high)",
98
"b-:Background color",
100
"e-:Exponential scale",
103
"E-:Encapsulated PostScript",
105
"v-:Verbose", (char *) 0};
106
static char usage[] =
107
"Usage: bdf2ps [-i bdf-file] [-o ps-file] [-l list-file] [-p page-format]\n\t\
108
[-r resolution] [-c LUT] [-s xscale,yscale] [-z lcut,hcut] [-wbneafENv]";
111
int argc; /* parameter count */
112
char **argv; /* pointers to parameters */
114
unsigned char *data, *px[3];
115
char c, *pc, *pl, *pfmt, *pfl, *pin, *pon, *text;
116
char pg[4], iname[MXNAME];
117
char *pval[MXPARM], line[MXLINE], ident[MXLINE];
118
char *gvparm(), *getenv();
119
int vmode, amode, bmode, wmode, nmode, fmode;
120
int nx, ny, mx, my, na, np, nxs, nys, nxe, nye;
121
int n, i, ip, iva, err, n1, n2, cmode, image, lok;
122
int msize, idf, ioff, idt, nr, ng, nb, gcmode;
123
int inull, lfsize, ipl, ixcen, iycen, ilc, ihc;
124
int *pbl, *pgl, *prl, npix[3], kunit[4];
125
int itt[MXITF], blut[MXITF], glut[MXITF], rlut[MXITF];
126
int dcparm(), pscolor(), psdraw();
127
float *buf, *pf, val, cuts[4];
128
double cl, ch, gcl, gch, gxscale, gyscale, xscale, yscale;
129
double ww, res[2], fac, xw, yw, pi, lcut, hcut;
130
double xorg, yorg, xsize, ysize, xend, yend, xcen, ycen;
131
double start[3], step[3], xstr, ystr, xo, xs, yo, ys;
132
double red, blue, green;
137
SCSPRO("-1"); /* initiate MIDAS environment */
140
SCECNT("PUT", &na, &iva, &iva); /* disable SC errors */
142
if (dcparm(argc,argv,plist,pval)) { /* decode parameter list */
143
fprintf(stdout,"%s\n",usage); SCSEPI();
146
pin = gvparm('i',plist,pval);
147
pfl = gvparm('l',plist,pval);
148
if ((pin && pfl) || !(pin || pfl)) { /* If no file list/name */
149
fprintf(stderr,"Error: either file name OR list MUST be given!\n");
154
pfd = fopen(pfl,"r");
156
fprintf(stderr,"Error: cannot open list file >%s<\n",pfl);
163
pfmt = (pc=gvparm('p',plist,pval)) ? pc : PSPAGE; /* Page format */
164
for (n=0; n<4; n++) {
165
c = (*pfmt) ? *pfmt : PSPAGE[n];
166
pg[n] = ('a'<=c && c<='z') ? c+'A'-'a' : c;
169
for (pp=page; pp->name && strcmp(pp->name,pg); pp++);
171
fprintf(stderr,"Error: Unknown page format!\n");
175
if (gvparm('e',plist,pval) != (char *) 0) { /* ramp or log ITT */
176
fac = 255.0/log(256.0);
177
for (n=0; n<MXITF; n++) itt[n] = fac*log(1.0+n);
180
for (n=0; n<MXITF; n++) itt[n] = n;
182
if (gvparm('n',plist,pval) != (char *) 0) /* negative ITT */
183
for (n=0; n<MXITF/2; n++) {
184
i = itt[n]; itt[n] = itt[MXITF-n-1]; itt[MXITF-n-1] = i;
187
amode = (gvparm('a',plist,pval) != (char *) 0);
188
vmode = (gvparm('v',plist,pval) != (char *) 0);
189
bmode = (gvparm('b',plist,pval) != (char *) 0);
190
wmode = (gvparm('w',plist,pval) != (char *) 0);
191
nmode = (gvparm('N',plist,pval) != (char *) 0);
192
fmode = (gvparm('f',plist,pval) != (char *) 0) ? -1 : 0;
196
px[0] = px[1] = px[2] = (unsigned char *) 0;
199
if ((pc=gvparm('c',plist,pval))) { /* define LUTs */
201
if (vmode) printf("Color table: >%s<\n",pc);
204
case '0' : /* default LUT no. 0 */
206
for (n=n1; n<n2; n++) {
207
blut[n] = 8*n; glut[n] = 0; rlut[n] = 0;
210
for (n=n1; n<n2; n++) {
211
blut[n] = 255; glut[n] = (255*(n-n1))/48; rlut[n] = 0;
214
for (n=n1; n<n2; n++) {
215
blut[n] = 255 - (255*(n-n1))/48; glut[n] = 255; rlut[n] = 0;
218
for (n=n1; n<n2; n++) {
219
blut[n] = 0; glut[n] = 255; rlut[n] = (255*(n-n1))/48;
222
for (n=n1; n<n2; n++) {
223
blut[n] = 0; glut[n] = 252 - (255*(n-n1))/48; rlut[n] = 255;
225
n1 = n2 ; n2 = MXITF;
226
for (n=n1; n<n2; n++) {
227
blut[n] = 8*(n-n1); glut[n] = 8*(n-n1); rlut[n] = 255;
230
case '1' : /* default LUT no. 1 */
231
for (n=0; n<MXITF; n++) blut[n] = (n<MXITF/2) ? i-2*n : 0;
232
for (n=0; n<MXITF; n++) rlut[n] = (n<=MXITF/2) ? 0 : 2*n-MXITF;
233
for (n=0; n<MXITF; n++) glut[n] = i - blut[n] - rlut[n];
235
case '2' : /* default LUT no. 2 */
236
for (n=0; n<MXITF; n++) blut[n] = i - n;
237
for (n=0; n<MXITF; n++) rlut[n] = n;
238
for (n=0; n<MXITF; n++) glut[n] = 128;
240
case '3' : /* default LUT no. 3 */
243
for (n=0; n<MXITF; n++)
244
blut[n] = 0.5*i*(1.0+cos(fac*n));
245
for (n=0; n<MXITF; n++)
246
rlut[n] = 0.5*i*(1.0+cos(5.0*fac*n-pi));
247
for (n=0; n<MXITF; n++)
248
glut[n] = 0.5*i*(1.0+sin(9.0*fac*n));
250
default : /* read LUT table */
251
err = TCTOPN(pc, F_I_MODE, &idt);
252
if (err != ERR_NORMAL) {
253
fprintf(stderr,"Error: Cannot open LUT table >%s<!\n",pc);
256
err = TCCSER(idt, "RED", &nr);
257
err = TCCSER(idt, "GREEN", &ng);
258
err = TCCSER(idt, "BLUE", &nb);
259
for (n=0; n<MXITF; n++) {
260
err = TCERDR(idt, n, nr, &val, &inull);
261
rlut[n] = (inull) ? 0 : i*val;
262
err = TCERDR(idt, n, ng, &val, &inull);
263
glut[n] = (inull) ? 0 : i*val;
264
err = TCERDR(idt, n, nb, &val, &inull);
265
blut[n] = (inull) ? 0 : i*val;
269
prl = rlut; pgl = glut; pbl = blut;
271
else pbl = pgl = prl = (int *) 0;
273
res[0] = (pc=gvparm('r',plist,pval)) ? atof(pc) : 0.0; /* resolution */
276
gxscale = gyscale = 0.0; /* Global X/Y scale */
277
if ((pc=gvparm('s',plist,pval))) {
279
while (*pc && *pc!=',') pc++;
280
gyscale = (*pc++ == ',') ? atof(pc) : gxscale;
283
gcl = gch = 0.0; /* Global z-cuts */
284
if ((pc=gvparm('z',plist,pval))) {
286
while (*pc && *pc!=',') pc++;
287
gch = (*pc++ == ',') ? atof(pc) : gcl;
290
pon = (pc=gvparm('o',plist,pval)) ? pc : PSNAME; /* get PS-file name */
291
if(psopen(pon,iname,pp->xsize,pp->ysize, /* open PS output file */
292
pp->xmar,pp->ymar,pp->angle,res)) {
293
fprintf(stderr,"Error: cannot open PostScript output file\n");
296
psmode(bmode, 0.0, 0.0, 1.0); /* set background color */
299
if (!(gvparm('E',plist,pval))) {
300
if (oshdate(ident,&tms)) ident[0] = '\0';
301
sprintf(line,"ESO-MIDAS; %s",ident);
302
pslabel(0.0,0.0,PSFONT,5,line);
305
while (pin || (pfd && fgets(line,MXLINE,pfd))) { /* go through files */
307
xscale = gxscale; yscale = gyscale;
308
xorg = 0.0; yorg = 1.0;
309
if (pp->angle == 0.0) {
310
xsize = pp->xsize - 2*(pp->xmar) - xorg - 2.0*ww;
311
ysize = pp->ysize - 2*(pp->ymar) - yorg;
314
xsize = pp->ysize - 2*(pp->ymar) - xorg - 2.0*ww;
315
ysize = pp->xsize - 2*(pp->xmar) - yorg;
318
ixcen = iycen = 0; /* no x/y-center given */
321
lcut = 0.0; hcut = 1.0;
323
if (!pin) { /* decode file list */
324
if (vmode) fprintf(stdout,"File line >%s",line);
327
pl = strtok(line, " \t:\n");
328
if (!pl || *pl=='#' || *pl=='!') continue; /* comment line */
332
if (!(pl=strtok(NULL, " \t:"))) break;
333
pc = strcpy(iname,pl); /* get file name */
335
if (!(pl=strtok(NULL, " \n\t,"))) break;
337
if (!(pl=strtok(NULL, " \n\t,"))) break;
339
if (!(pl=strtok(NULL, " \n\t,"))) break;
341
if (!(pl=strtok(NULL, " \n\t,"))) break;
343
if (!(pl=strtok(NULL, " \n\t,"))) break;
345
if (!(pl=strtok(NULL, " \n\t,"))) break;
347
ixcen = ((pl=strtok(NULL, " \n\t,")) != 0);
348
if (ixcen) xcen = atof(pl);
349
iycen = ((pl=strtok(NULL, " \n\t,")) != 0);
350
if (iycen) ycen = atof(pl);
351
ilc = ((pl=strtok(NULL, " \n\t,")) != 0);
352
if (ilc) lcut = atof(pl);
353
ihc = ((pl=strtok(NULL, " \n\t,")) != 0);
354
if (ihc) hcut = atof(pl);
356
fprintf(stdout,"File >%s< %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f\n"
357
,pin,xorg,yorg,xscale,yscale,xsize,ysize);
358
fprintf(stdout," %7.1f %7.1f %7.1f %7.1f\n"
359
,xcen,ycen,lcut,hcut);
364
case 'T' : /* write text */
366
if (!(pl=strtok(NULL, "\n"))) break;
367
while (*pl && (*pl==' ' || *pl=='\t')) pl++;
368
if (*pl=='"') c = '"', pl++; else c = ' ';
370
while (*pl && *pl!=c) pl++;
372
if (!(pl=strtok(pl, " \n\t,"))) break;
374
if (!(pl=strtok(NULL, " \n\t,"))) break;
376
i = (pl=strtok(NULL, " \n\t,")) ? atol(pl) : 5;
377
red = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
378
green = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
379
gcmode = (pl==0) ? 0 : 1;
380
blue = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
381
pscolor(gcmode,red,green,blue);
383
fprintf(stdout,"Text >%s< %7.1f %7.1f, %d\n",text,xorg,yorg,i);
385
pslabel(xorg,yorg,PSFONT,i,text);
388
case 'L' : /* draw line */
390
if (!(pl=strtok(NULL, " \n\t,"))) break;
392
if (!(pl=strtok(NULL, " \n\t,"))) break;
394
if (!(pl=strtok(NULL, " \n\t,"))) break;
396
ysize = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
397
xscale = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.1;
398
red = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
399
green = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
400
gcmode = (pl==0) ? 0 : 1;
401
blue = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
402
pscolor(gcmode,red,green,blue);
404
fprintf(stdout,"Line %7.1f %7.1f,%7.1f %7.1f, %7.2f\n",
405
xorg,yorg,xsize,ysize,xscale);
407
psdraw(0,xorg,yorg,xscale,xsize,ysize,0.0,0.0);
410
case 'C' : /* draw circle */
412
if (!(pl=strtok(NULL, " \n\t,"))) break;
414
if (!(pl=strtok(NULL, " \n\t,"))) break;
416
if (!(pl=strtok(NULL, " \n\t,"))) break;
418
xscale = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
419
yscale = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 360.0;
420
ysize = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.1;
421
red = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
422
green = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
423
gcmode = (pl==0) ? 0 : 1;
424
blue = (pl=strtok(NULL, " \n\t,")) ? atof(pl) : 0.0;
425
pscolor(gcmode,red,green,blue);
427
fprintf(stdout,"Circle %7.1f %7.1f,%7.1f %7.1f, %7.2f %7.2f\n",
428
xorg,yorg,ysize,xsize,xscale,yscale);
430
psdraw(1,xorg,yorg,ysize,xsize,xscale,yscale,0.0);
434
fprintf(stderr,"Warning: Unknown line type in input list file\n");
435
fprintf(stderr," >%32.32s<\n",line);
438
fprintf(stderr,"Error: wrong parameters in line\n");
442
if (!image) continue;
445
if (vmode) fprintf(stdout,"Open image frame >%s<\n",pin);
446
err = SCFOPN(pin, D_R4_FORMAT, 0, F_IMA_TYPE, &idf);
447
if (err != ERR_NORMAL) { /* check if frame exists */
448
fprintf(stderr,"Warning: Image file >%s< not found\n", pin);
452
err = SCDRDI(idf, "NAXIS", 1, 1, &iva, &na, kunit, &inull);
453
if (na<2 || 3<na || err) { /* check dimension of frame */
454
fprintf(stderr,"Error: Bad dimensions (%d) of image\n",na);
459
err = SCDRDI(idf, "NPIX", 1, na, &iva, npix, kunit, &inull);
460
mx = npix[0]; my = npix[1];
461
msize = (na==3) ? mx*my : 0;
462
np = (na==3) ? npix[2] : 1;
463
if (na==3 && np!=3) {
464
fprintf(stderr,"Error: 3-dimensional frame does NOT have 3 planes\n");
469
err = SCDRDD(idf, "START",1, na, &iva, start, kunit, &inull);
470
err = SCDRDD(idf, "STEP", 1, na, &iva, step, kunit, &inull);
471
if (!ixcen) xcen = 0.5*(mx-1)*step[0] + start[0];
472
if (!iycen) ycen = 0.5*(my-1)*step[1] + start[1];
473
xw = fabs(step[0]*npix[0]);
474
yw = fabs(step[1]*npix[1]);
476
err = SCDGETC(idf, "IDENT", 1,MXLINE-1, &iva, ident);
477
if (cl==ch) { /* read cuts from frame */
478
err = SCDRDR(idf, "LHCUTS", 1, 4, &iva, cuts, kunit, &inull);
479
if (cuts[1]==cuts[0]) { ch = cuts[3]; cl = cuts[2]; }
480
else { ch = cuts[1]; cl = cuts[0]; }
485
/* define image size and location */
487
if (xscale<=0.0 && yscale<=0.0) {
488
xscale = xw/xsize; yscale = yw/ysize;
489
if (yscale<xscale) yscale = xscale;
490
else xscale = yscale;
492
else if (xscale<=0.0) xscale = yscale;
493
else if (yscale<=0.0) yscale = xscale;
495
/* range in X and Y */
497
nxs = (xcen-start[0])/step[0] - 0.5*xsize*xscale/fabs(step[0]) + 1;
499
nxe = (xcen-start[0])/step[0] + 0.5*xsize*xscale/fabs(step[0]) + 1;
500
if (mx<nxe) nxe = mx;
503
nys = (ycen-start[1])/step[1] - 0.5*ysize*yscale/fabs(step[1]) + 1;
505
nye = (ycen-start[1])/step[1] + 0.5*ysize*yscale/fabs(step[1]) + 1;
506
if (my<nye) nye = my;
509
if (mx<nxs || nxe<1 || nx<2 || my<nys || nye<1 || ny<2) {
510
fprintf(stderr,"Warning: frame not in display window!\n");
511
SCFCLO(idf); pin = (char *) 0;
515
xstr = start[0] + (nxs-1)*step[0];
516
ystr = start[1] + (nys-1)*step[1];
517
xend = start[0] + (nxe-1)*step[0];
518
yend = start[1] + (nye-1)*step[1];
520
xo = xorg + 0.5*xsize - fabs(xcen-xstr)/xscale;
521
xs = fabs(xend-xstr)/xscale;
522
yo = yorg + 0.5*ysize - fabs(ycen-ystr)/yscale;
523
ys = fabs(yend-ystr)/yscale;
525
if (na==3) /* define ITT and LUT */
526
psitf(2,MXITF,itt,itt,itt,itt);
528
psitf(cmode,MXITF,itt,prl,pgl,pbl);
530
psframe(fmode, xo, yo, xs, ys, PSFONT, lfsize, xstr, ystr, xend, yend);
531
psimage(nx, ny, 0, 8);
534
fprintf(stdout,"Origin,size : %6.1f %6.1f, %6.1f %6.1f\n",
536
fprintf(stdout," Scale,cuts: %6.1f %6.1f, %6.1f %6.1f\n",
537
xscale,yscale,lcut,hcut);
538
fprintf(stdout," Range: %d %d %d %d; %d %d %d %d\n",
539
nxs,nxe,nx,mx,nys,nye,ny,my);
542
/* create internal buffer */
544
buf = (float *) calloc(2*nx, sizeof(float));
546
fprintf(stderr,"Error: Cannot open internal buffer!\n");
549
fac = (MXITF-1) / (hcut - lcut);
550
ioff = nxs + mx*(nys-1);
552
for (n=0; n<ny; n++) {
554
data = (unsigned char *) &buf[nx];
555
for (ip=0; ip<np; ip++) {
556
err = SCFGET(idf, ioff+ipl, nx, &iva, (char *) buf);
557
pf = buf; px[ip] = data;
564
*data = fac * (*pf-lcut);
569
psline(px[0], px[1], px[2]);
573
psline(data, data, data); /* flush internal buffer */
575
if (wmode) pswedge(1, xorg+xsize+0.05, yorg, ww, ysize, cl, ch);
576
if (!nmode) pslabel(xorg,yorg-0.4,PSFONT,lfsize,ident);
578
SCFCLO(idf); /* close bdf-file */