1 /*============================================================================
2 WCSLIB 7.7 - an implementation of the FITS WCS standard.
3 Copyright (C) 1995-2021, Mark Calabretta
4
5 This file is part of WCSLIB.
6
7 WCSLIB is free software: you can redistribute it and/or modify it under the
8 terms of the GNU Lesser General Public License as published by the Free
9 Software Foundation, either version 3 of the License, or (at your option)
10 any later version.
11
12 WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with WCSLIB. If not, see http://www.gnu.org/licenses.
19
20 Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
21 http://www.atnf.csiro.au/people/Mark.Calabretta
22 $Id: spc_f.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $
23 *===========================================================================*/
24
25 #include <stdio.h>
26 #include <string.h>
27
28 #include <wcserr.h>
29 #include <wcsutil.h>
30 #include <spc.h>
31
32 // Fortran name mangling.
33 #include <wcsconfig_f77.h>
34 #define spcput_ F77_FUNC(spcput, SPCPUT)
35 #define spcptc_ F77_FUNC(spcptc, SPCPTC)
36 #define spcptd_ F77_FUNC(spcptd, SPCPTD)
37 #define spcpti_ F77_FUNC(spcpti, SPCPTI)
38 #define spcget_ F77_FUNC(spcget, SPCGET)
39 #define spcgtc_ F77_FUNC(spcgtc, SPCGTC)
40 #define spcgtd_ F77_FUNC(spcgtd, SPCGTD)
41 #define spcgti_ F77_FUNC(spcgti, SPCGTI)
42
43 #define spcini_ F77_FUNC(spcini, SPCINI)
44 #define spcfree_ F77_FUNC(spcfree, SPCFREE)
45 #define spcsize_ F77_FUNC(spcsize, SPCSIZE)
46 #define spcprt_ F77_FUNC(spcprt, SPCPRT)
47 #define spcperr_ F77_FUNC(spcperr, SPCPERR)
48 #define spcset_ F77_FUNC(spcset, SPCSET)
49 #define spcx2s_ F77_FUNC(spcx2s, SPCX2S)
50 #define spcs2x_ F77_FUNC(spcs2x, SPCS2X)
51 #define spctype_ F77_FUNC(spctype, SPCTYPE)
52 #define spcspxe_ F77_FUNC(spcspxe, SPCSPXE)
53 #define spcxpse_ F77_FUNC(spcxpse, SPCXPSE)
54 #define spctrne_ F77_FUNC(spctrne, SPCTRNE)
55 #define spcaips_ F77_FUNC(spcaips, SPCAIPS)
56
57 // Deprecated.
58 #define spctyp_ F77_FUNC(spctyp, SPCTYP)
59 #define spcspx_ F77_FUNC(spcspx, SPCSPX)
60 #define spcxps_ F77_FUNC(spcxps, SPCXPS)
61 #define spctrn_ F77_FUNC(spctrn, SPCTRN)
62
63 // Must match the values set in spc.inc.
64 #define SPC_FLAG 100
65 #define SPC_TYPE 101
66 #define SPC_CODE 102
67 #define SPC_CRVAL 103
68 #define SPC_RESTFRQ 104
69 #define SPC_RESTWAV 105
70 #define SPC_PV 106
71
72 #define SPC_W 200
73 #define SPC_ISGRISM 201
74 #define SPC_ERR 202
75
76 //----------------------------------------------------------------------------
77
spcput_(int * spc,const int * what,const void * value,const int * m)78 int spcput_(int *spc, const int *what, const void *value, const int *m)
79
80 {
81 const char *cvalp;
82 const int *ivalp;
83 const double *dvalp;
84 struct spcprm *spcp;
85
86 // Cast pointers.
87 spcp = (struct spcprm *)spc;
88 cvalp = (const char *)value;
89 ivalp = (const int *)value;
90 dvalp = (const double *)value;
91
92 spcp->flag = 0;
93
94 switch (*what) {
95 case SPC_FLAG:
96 spcp->flag = *ivalp;
97 break;
98 case SPC_TYPE:
99 // Only four characters need be given.
100 wcsutil_strcvt(4, ' ', 1, cvalp, spcp->type);
101 wcsutil_null_fill(8, spcp->type);
102 break;
103 case SPC_CODE:
104 // Only three characters need be given.
105 wcsutil_strcvt(3, ' ', 1, cvalp, spcp->code);
106 wcsutil_null_fill(4, spcp->code);
107 break;
108 case SPC_CRVAL:
109 spcp->crval = *dvalp;
110 break;
111 case SPC_RESTFRQ:
112 spcp->restfrq = *dvalp;
113 break;
114 case SPC_RESTWAV:
115 spcp->restwav = *dvalp;
116 break;
117 case SPC_PV:
118 spcp->pv[*m] = *dvalp;
119 break;
120 default:
121 return 1;
122 }
123
124 return 0;
125 }
126
spcptc_(int * spc,const int * what,const char * value,const int * m)127 int spcptc_(int *spc, const int *what, const char *value, const int *m)
128 {
129 return spcput_(spc, what, value, m);
130 }
131
spcptd_(int * spc,const int * what,const double * value,const int * m)132 int spcptd_(int *spc, const int *what, const double *value, const int *m)
133 {
134 return spcput_(spc, what, value, m);
135 }
136
spcpti_(int * spc,const int * what,const int * value,const int * m)137 int spcpti_(int *spc, const int *what, const int *value, const int *m)
138 {
139 return spcput_(spc, what, value, m);
140 }
141
142 //----------------------------------------------------------------------------
143
spcget_(const int * spc,const int * what,void * value)144 int spcget_(const int *spc, const int *what, void *value)
145
146 {
147 unsigned int l;
148 int m;
149 char *cvalp;
150 int *ivalp;
151 double *dvalp;
152 const int *ispcp;
153 const struct spcprm *spcp;
154
155 // Cast pointers.
156 spcp = (const struct spcprm *)spc;
157 cvalp = (char *)value;
158 ivalp = (int *)value;
159 dvalp = (double *)value;
160
161 switch (*what) {
162 case SPC_FLAG:
163 *ivalp = spcp->flag;
164 break;
165 case SPC_TYPE:
166 wcsutil_strcvt(8, ' ', 0, spcp->type, cvalp);
167 break;
168 case SPC_CODE:
169 wcsutil_strcvt(4, ' ', 0, spcp->code, cvalp);
170 break;
171 case SPC_CRVAL:
172 *dvalp = spcp->crval;
173 break;
174 case SPC_RESTFRQ:
175 *dvalp = spcp->restfrq;
176 break;
177 case SPC_RESTWAV:
178 *dvalp = spcp->restwav;
179 break;
180 case SPC_PV:
181 for (m = 0; m < 7; m++) {
182 *(dvalp++) = spcp->pv[m];
183 }
184 break;
185 case SPC_W:
186 for (m = 0; m < 6; m++) {
187 *(dvalp++) = spcp->w[m];
188 }
189 break;
190 case SPC_ISGRISM:
191 *ivalp = spcp->isGrism;
192 break;
193 case SPC_ERR:
194 // Copy the contents of the wcserr struct.
195 if (spcp->err) {
196 ispcp = (int *)(spcp->err);
197 for (l = 0; l < ERRLEN; l++) {
198 *(ivalp++) = *(ispcp++);
199 }
200 } else {
201 for (l = 0; l < ERRLEN; l++) {
202 *(ivalp++) = 0;
203 }
204 }
205 break;
206 default:
207 return 1;
208 }
209
210 return 0;
211 }
212
spcgtc_(const int * spc,const int * what,char * value)213 int spcgtc_(const int *spc, const int *what, char *value)
214 {
215 return spcget_(spc, what, value);
216 }
217
spcgtd_(const int * spc,const int * what,double * value)218 int spcgtd_(const int *spc, const int *what, double *value)
219 {
220 return spcget_(spc, what, value);
221 }
222
spcgti_(const int * spc,const int * what,int * value)223 int spcgti_(const int *spc, const int *what, int *value)
224 {
225 return spcget_(spc, what, value);
226 }
227
228 //----------------------------------------------------------------------------
229
spcini_(int * spc)230 int spcini_(int *spc)
231
232 {
233 return spcini((struct spcprm *)spc);
234 }
235
236 //----------------------------------------------------------------------------
237
spcfree_(int * spc)238 int spcfree_(int *spc)
239
240 {
241 return spcfree((struct spcprm *)spc);
242 }
243
244 //----------------------------------------------------------------------------
245
spcsize_(const int * spc,int sizes[2])246 int spcsize_(const int *spc, int sizes[2])
247
248 {
249 return spcsize((const struct spcprm *)spc, sizes);
250 }
251
252 //----------------------------------------------------------------------------
253
spcprt_(const int * spc)254 int spcprt_(const int *spc)
255
256 {
257 // This may or may not force the Fortran I/O buffers to be flushed. If
258 // not, try CALL FLUSH(6) before calling SPCPRT in the Fortran code.
259 fflush(NULL);
260
261 return spcprt((const struct spcprm *)spc);
262 }
263
264 //----------------------------------------------------------------------------
265
266 // If null-terminated (using the Fortran CHAR(0) intrinsic), prefix may be of
267 // length less than but not exceeding 72 and trailing blanks are preserved.
268 // Otherwise, it must be of length 72 and trailing blanks are stripped off.
269
spcperr_(int * spc,const char prefix[72])270 int spcperr_(int *spc, const char prefix[72])
271
272 {
273 char prefix_[73];
274 wcsutil_strcvt(72, '\0', 1, prefix, prefix_);
275
276 // This may or may not force the Fortran I/O buffers to be flushed.
277 // If not, try CALL FLUSH(6) before calling SPCPERR in the Fortran code.
278 fflush(NULL);
279
280 return wcserr_prt(((struct spcprm *)spc)->err, prefix_);
281 }
282
283 //----------------------------------------------------------------------------
284
spcset_(int * spc)285 int spcset_(int *spc)
286
287 {
288 return spcset((struct spcprm *)spc);
289 }
290
291 //----------------------------------------------------------------------------
292
spcx2s_(int * spc,const int * nx,const int * sspec,const int * sx,const double x[],double spec[],int stat[])293 int spcx2s_(
294 int *spc,
295 const int *nx,
296 const int *sspec,
297 const int *sx,
298 const double x[],
299 double spec[],
300 int stat[])
301
302 {
303 return spcx2s((struct spcprm *)spc, *nx, *sx, *sspec, x, spec, stat);
304 }
305
306 //----------------------------------------------------------------------------
307
spcs2x_(int * spc,const int * nspec,const int * sspec,const int * sx,const double spec[],double x[],int stat[])308 int spcs2x_(
309 int *spc,
310 const int *nspec,
311 const int *sspec,
312 const int *sx,
313 const double spec[],
314 double x[],
315 int stat[])
316
317 {
318 return spcs2x((struct spcprm *)spc, *nspec, *sspec, *sx, spec, x, stat);
319 }
320
321 //----------------------------------------------------------------------------
322
spctype_(const char ctypei[8],char stype[4],char scode[3],char sname[21],char units[7],char ptype[1],char xtype[1],int * restreq,iptr err)323 int spctype_(
324 const char ctypei[8],
325 char stype[4],
326 char scode[3],
327 char sname[21],
328 char units[7],
329 char ptype[1],
330 char xtype[1],
331 int *restreq,
332 iptr err)
333
334 {
335 char ctypei_[9];
336 wcsutil_strcvt(8, ' ', 1, ctypei, ctypei_);
337
338 char stype_[5], scode_[4], sname_[22], units_[8];
339 int status = spctype(ctypei_, stype_, scode_, sname_, units_, ptype, xtype,
340 restreq, (struct wcserr **)err);
341
342 wcsutil_strcvt( 4, ' ', 0, stype_, stype);
343 wcsutil_strcvt( 3, ' ', 0, scode_, scode);
344 wcsutil_strcvt(21, ' ', 0, sname_, sname);
345 wcsutil_strcvt( 7, ' ', 0, units_, units);
346
347 return status;
348 }
349
350 // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
351
spctyp_(const char ctypei[8],char stype[4],char scode[3],char sname[21],char units[7],char ptype[1],char xtype[1],int * restreq)352 int spctyp_(
353 const char ctypei[8],
354 char stype[4],
355 char scode[3],
356 char sname[21],
357 char units[7],
358 char ptype[1],
359 char xtype[1],
360 int *restreq)
361
362 {
363 return spctype_(ctypei, stype, scode, sname, units, ptype, xtype, restreq,
364 0x0);
365 }
366
367 //----------------------------------------------------------------------------
368
spcspxe_(const char ctypeS[8],const double * crvalS,const double * restfrq,const double * restwav,char ptype[1],char xtype[1],int * restreq,double * crvalX,double * dXdS,iptr err)369 int spcspxe_(
370 const char ctypeS[8],
371 const double *crvalS,
372 const double *restfrq,
373 const double *restwav,
374 char ptype[1],
375 char xtype[1],
376 int *restreq,
377 double *crvalX,
378 double *dXdS,
379 iptr err)
380
381 {
382 char ctypeS_[9];
383 wcsutil_strcvt(8, ' ', 1, ctypeS, ctypeS_);
384
385 return spcspxe(ctypeS_, *crvalS, *restfrq, *restwav, ptype, xtype, restreq,
386 crvalX, dXdS, (struct wcserr **)err);
387 }
388
389 // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
390
spcspx_(const char ctypeS[8],const double * crvalS,const double * restfrq,const double * restwav,char ptype[1],char xtype[1],int * restreq,double * crvalX,double * dXdS)391 int spcspx_(
392 const char ctypeS[8],
393 const double *crvalS,
394 const double *restfrq,
395 const double *restwav,
396 char ptype[1],
397 char xtype[1],
398 int *restreq,
399 double *crvalX,
400 double *dXdS)
401
402 {
403 return spcspxe_(ctypeS, crvalS, restfrq, restwav, ptype, xtype, restreq,
404 crvalX, dXdS, 0x0);
405 }
406
407 //----------------------------------------------------------------------------
408
spcxpse_(const char ctypeS[8],const double * crvalX,const double * restfrq,const double * restwav,char ptype[1],char xtype[1],int * restreq,double * crvalS,double * dSdX,iptr err)409 int spcxpse_(
410 const char ctypeS[8],
411 const double *crvalX,
412 const double *restfrq,
413 const double *restwav,
414 char ptype[1],
415 char xtype[1],
416 int *restreq,
417 double *crvalS,
418 double *dSdX,
419 iptr err)
420
421 {
422 char ctypeS_[9];
423 wcsutil_strcvt(8, ' ', 1, ctypeS, ctypeS_);
424
425 return spcxpse(ctypeS_, *crvalX, *restfrq, *restwav, ptype, xtype, restreq,
426 crvalS, dSdX, (struct wcserr **)err);
427 }
428
429 // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
430
spcxps_(const char ctypeS[8],const double * crvalX,const double * restfrq,const double * restwav,char ptype[1],char xtype[1],int * restreq,double * crvalS,double * dSdX)431 int spcxps_(
432 const char ctypeS[8],
433 const double *crvalX,
434 const double *restfrq,
435 const double *restwav,
436 char ptype[1],
437 char xtype[1],
438 int *restreq,
439 double *crvalS,
440 double *dSdX)
441
442 {
443 return spcxpse_(ctypeS, crvalX, restfrq, restwav, ptype, xtype, restreq,
444 crvalS, dSdX, 0x0);
445 }
446
447 //----------------------------------------------------------------------------
448
spctrne_(const char ctypeS1[8],const double * crvalS1,const double * cdeltS1,const double * restfrq,const double * restwav,char ctypeS2[8],double * crvalS2,double * cdeltS2,iptr err)449 int spctrne_(
450 const char ctypeS1[8],
451 const double *crvalS1,
452 const double *cdeltS1,
453 const double *restfrq,
454 const double *restwav,
455 char ctypeS2[8],
456 double *crvalS2,
457 double *cdeltS2,
458 iptr err)
459
460 {
461 char ctypeS1_[9], ctypeS2_[9];
462 wcsutil_strcvt(8, ' ', 1, ctypeS1, ctypeS1_);
463 wcsutil_strcvt(8, ' ', 1, ctypeS2, ctypeS2_);
464
465 int status = spctrne(ctypeS1_, *crvalS1, *cdeltS1, *restfrq, *restwav,
466 ctypeS2_, crvalS2, cdeltS2, (struct wcserr **)err);
467
468 wcsutil_strcvt(8, ' ', 0, ctypeS2_, ctypeS2);
469
470 return status;
471 }
472
473 // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
474
spctrn_(const char ctypeS1[8],const double * crvalS1,const double * cdeltS1,const double * restfrq,const double * restwav,char ctypeS2[8],double * crvalS2,double * cdeltS2)475 int spctrn_(
476 const char ctypeS1[8],
477 const double *crvalS1,
478 const double *cdeltS1,
479 const double *restfrq,
480 const double *restwav,
481 char ctypeS2[8],
482 double *crvalS2,
483 double *cdeltS2)
484
485 {
486 return spctrne_(ctypeS1, crvalS1, cdeltS1, restfrq, restwav, ctypeS2,
487 crvalS2, cdeltS2, 0x0);
488 }
489
490 //----------------------------------------------------------------------------
491
spcaips_(const char ctypeA[8],int * velref,char ctype[8],char specsys[8])492 int spcaips_(
493 const char ctypeA[8],
494 int *velref,
495 char ctype[8],
496 char specsys[8])
497
498 {
499 char ctypeA_[9];
500 wcsutil_strcvt(8, ' ', 1, ctypeA, ctypeA_);
501
502 char ctype_[9], specsys_[9];
503 int status = spcaips(ctypeA_, *velref, ctype_, specsys_);
504
505 wcsutil_strcvt(8, ' ', 0, ctype_, ctype);
506 wcsutil_strcvt(8, ' ', 0, specsys_, specsys);
507
508 return status;
509 }
510