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