This file is indexed.

/usr/include/wcslib-4.8.3/spc.h is in wcslib-dev 4.8.3-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
/*============================================================================

  WCSLIB 4.8 - an implementation of the FITS WCS standard.
  Copyright (C) 1995-2011, Mark Calabretta

  This file is part of WCSLIB.

  WCSLIB is free software: you can redistribute it and/or modify it under the
  terms of the GNU Lesser General Public License as published by the Free
  Software Foundation, either version 3 of the License, or (at your option)
  any later version.

  WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
  more details.

  You should have received a copy of the GNU Lesser General Public License
  along with WCSLIB.  If not, see <http://www.gnu.org/licenses/>.

  Correspondence concerning WCSLIB may be directed to:
    Internet email: mcalabre@atnf.csiro.au
    Postal address: Dr. Mark Calabretta
                    Australia Telescope National Facility, CSIRO
                    PO Box 76
                    Epping NSW 1710
                    AUSTRALIA

  Author: Mark Calabretta, Australia Telescope National Facility
  http://www.atnf.csiro.au/~mcalabre/index.html
  $Id: spc.h,v 4.8.1.1 2011/08/15 08:07:06 cal103 Exp cal103 $
*=============================================================================
*
* WCSLIB 4.8 - C routines that implement the spectral coordinate systems
* recognized by the FITS World Coordinate System (WCS) standard.  Refer to
*
*   "Representations of world coordinates in FITS",
*   Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (Paper I)
*
*   "Representations of spectral coordinates in FITS",
*   Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L.
*   2006, A&A, 446, 747 (Paper III)
*
* Refer to the README file provided with WCSLIB for an overview of the
* library.
*
*
* Summary of the spc routines
* ---------------------------
* These routines implement the part of the FITS WCS standard that deals with
* spectral coordinates.  They define methods to be used for computing spectral
* world coordinates from intermediate world coordinates (a linear
* transformation of image pixel coordinates), and vice versa.  They are based
* on the spcprm struct which contains all information needed for the
* computations.  The struct contains some members that must be set by the
* user, and others that are maintained by these routines, somewhat like a
* C++ class but with no encapsulation.
*
* Routine spcini() is provided to initialize the spcprm struct with default
* values, spcfree() reclaims any memory that may have been allocated to store
* an error message, and spcprt() prints its contents.
*
* A setup routine, spcset(), computes intermediate values in the spcprm struct
* from parameters in it that were supplied by the user.  The struct always
* needs to be set up by spcset() but it need not be called explicitly - refer
* to the explanation of spcprm::flag.
*
* spcx2s() and spcs2x() implement the WCS spectral coordinate transformations.
* In fact, they are high level driver routines for the lower level spectral
* coordinate transformation routines described in spx.h.
*
* A number of routines are provided to aid in analysing or synthesising sets
* of FITS spectral axis keywords:
*
*   - spctype() checks a spectral CTYPEia keyword for validity and returns
*     information derived from it.
*
*   - Spectral keyword analysis routine spcspxe() computes the values of the
*     X-type spectral variables for the S-type variables supplied.
*
*   - Spectral keyword synthesis routine, spcxpse(), computes the S-type
*     variables for the X-types supplied.
*
*   - Given a set of spectral keywords, a translation routine, spctrne(),
*     produces the corresponding set for the specified spectral CTYPEia.
*
*   - spcaips() translates AIPS-convention spectral keywords, CTYPEn and
*     VELREF, into CTYPEia and SPECSYSa.
*
* Spectral variable types - S, P, and X:
* --------------------------------------
* A few words of explanation are necessary regarding spectral variable types
* in FITS.
*
* Every FITS spectral axis has three associated spectral variables:
*
*   S-type: the spectral variable in which coordinates are to be
*     expressed.  Each S-type is encoded as four characters and is
*     linearly related to one of four basic types as follows:
*
*     F: frequency
*       'FREQ':  frequency
*       'AFRQ':  angular frequency
*       'ENER':  photon energy
*       'WAVN':  wave number
*       'VRAD':  radio velocity
*
*     W: wavelength in vacuo
*       'WAVE':  wavelength
*       'VOPT':  optical velocity
*       'ZOPT':  redshift
*
*     A: wavelength in air
*       'AWAV':  wavelength in air
*
*     V: velocity
*       'VELO':  relativistic velocity
*       'BETA':  relativistic beta factor
*
*     The S-type forms the first four characters of the CTYPEia keyvalue,
*     and CRVALia and CDELTia are expressed as S-type quantities so that
*     they provide a first-order approximation to the S-type variable at
*     the reference point.
*
*     Note that 'AFRQ', angular frequency, is additional to the variables
*     defined in WCS Paper III.
*
*   P-type: the basic spectral variable (F, W, A, or V) with which the
*     S-type variable is associated (see list above).
*
*     For non-grism axes, the P-type is encoded as the eighth character of
*     CTYPEia.
*
*   X-type: the basic spectral variable (F, W, A, or V) for which the
*     spectral axis is linear, grisms excluded (see below).
*
*     For non-grism axes, the X-type is encoded as the sixth character of
*     CTYPEia.
*
*   Grisms: Grism axes have normal S-, and P-types but the axis is linear,
*     not in any spectral variable, but in a special "grism parameter".
*     The X-type spectral variable is either W or A for grisms in vacuo or
*     air respectively, but is encoded as 'w' or 'a' to indicate that an
*     additional transformation is required to convert to or from the
*     grism parameter.  The spectral algorithm code for grisms also has a
*     special encoding in CTYPEia, either 'GRI' (in vacuo) or 'GRA' (in air).
*
* In the algorithm chain, the non-linear transformation occurs between the
* X-type and the P-type variables; the transformation between P-type and
* S-type variables is always linear.
*
* When the P-type and X-type variables are the same, the spectral axis is
* linear in the S-type variable and the second four characters of CTYPEia
* are blank.  This can never happen for grism axes.
*
* As an example, correlating radio spectrometers always produce spectra that
* are regularly gridded in frequency; a redshift scale on such a spectrum is
* non-linear.  The required value of CTYPEia would be 'ZOPT-F2W', where the
* desired S-type is 'ZOPT' (redshift), the P-type is necessarily 'W'
* (wavelength), and the X-type is 'F' (frequency) by the nature of the
* instrument.
*
* Argument checking:
* ------------------
* The input spectral values are only checked for values that would result in
* floating point exceptions.  In particular, negative frequencies and
* wavelengths are allowed, as are velocities greater than the speed of
* light.  The same is true for the spectral parameters - rest frequency and
* wavelength.
*
* Accuracy:
* ---------
* No warranty is given for the accuracy of these routines (refer to the
* copyright notice); intending users must satisfy for themselves their
* adequacy for the intended purpose.  However, closure effectively to within
* double precision rounding error was demonstrated by test routine tspc.c
* which accompanies this software.
*
*
* spcini() - Default constructor for the spcprm struct
* ----------------------------------------------------
* spcini() sets all members of a spcprm struct to default values.  It should
* be used to initialize every spcprm struct.
*
* Given and returned:
*   spc       struct spcprm*
*                       Spectral transformation parameters.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         1: Null spcprm pointer passed.
*
*
* spcfree() - Destructor for the spcprm struct
* --------------------------------------------
* spcfree() frees any memory that may have been allocated to store an error
* message in the spcprm struct.
*
* Given:
*   spc       struct spcprm*
*                       Spectral transformation parameters.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         1: Null spcprm pointer passed.
*
*
* spcprt() - Print routine for the spcprm struct
* ----------------------------------------------
* spcprt() prints the contents of a spcprm struct using wcsprintf().  Mainly
* intended for diagnostic purposes.
*
* Given:
*   spc       const struct spcprm*
*                       Spectral transformation parameters.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         1: Null spcprm pointer passed.
*
*
* spcset() - Setup routine for the spcprm struct
* ----------------------------------------------
* spcset() sets up a spcprm struct according to information supplied within
* it.
*
* Note that this routine need not be called directly; it will be invoked by
* spcx2s() and spcs2x() if spcprm::flag is anything other than a predefined
* magic value.
*
* Given and returned:
*   spc       struct spcprm*
*                       Spectral transformation parameters.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         1: Null spcprm pointer passed.
*                         2: Invalid spectral parameters.
*
*                       For returns > 1, a detailed error message is set in
*                       spcprm::err if enabled, see wcserr_enable().
*
*
* spcx2s() - Transform to spectral coordinates
* --------------------------------------------
* spcx2s() transforms intermediate world coordinates to spectral coordinates.
*
* Given and returned:
*   spc       struct spcprm*
*                       Spectral transformation parameters.
*
* Given:
*   nx        int       Vector length.
*
*   sx        int       Vector stride.
*
*   sspec     int       Vector stride.
*
*   x         const double[]
*                       Intermediate world coordinates, in SI units.
*
* Returned:
*   spec      double[]  Spectral coordinates, in SI units.
*
*   stat      int[]     Status return value status for each vector element:
*                         0: Success.
*                         1: Invalid value of x.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         1: Null spcprm pointer passed.
*                         2: Invalid spectral parameters.
*                         3: One or more of the x coordinates were invalid,
*                            as indicated by the stat vector.
*
*                       For returns > 1, a detailed error message is set in
*                       spcprm::err if enabled, see wcserr_enable().
*
*
* spcs2x() - Transform spectral coordinates
* -----------------------------------------
* spcs2x() transforms spectral world coordinates to intermediate world
* coordinates.
*
* Given and returned:
*   spc       struct spcprm*
*                       Spectral transformation parameters.
*
* Given:
*   nspec     int       Vector length.
*
*   sspec     int       Vector stride.
*
*   sx        int       Vector stride.
*
*   spec      const double[]
*                       Spectral coordinates, in SI units.
*
* Returned:
*   x         double[]  Intermediate world coordinates, in SI units.
*
*   stat      int[]     Status return value status for each vector element:
*                         0: Success.
*                         1: Invalid value of spec.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         1: Null spcprm pointer passed.
*                         2: Invalid spectral parameters.
*                         4: One or more of the spec coordinates were
*                            invalid, as indicated by the stat vector.
*
*                       For returns > 1, a detailed error message is set in
*                       spcprm::err if enabled, see wcserr_enable().
*
*
* spctype() - Spectral CTYPEia keyword analysis
* ---------------------------------------------
* spctype() checks whether a CTYPEia keyvalue is a valid spectral axis type
* and if so returns information derived from it relating to the associated S-,
* P-, and X-type spectral variables (see explanation above).
*
* The return arguments are guaranteed not be modified if CTYPEia is not a
* valid spectral type; zero-pointers may be specified for any that are not of
* interest.
*
* A deprecated form of this function, spctyp(), lacks the wcserr** parameter.
*
* Given:
*   ctype     const char[9]
*                       The CTYPEia keyvalue, (eight characters with null
*                       termination).
*
* Returned:
*   stype     char[]    The four-letter name of the S-type spectral variable
*                       copied or translated from ctype.  If a non-zero
*                       pointer is given, the array must accomodate a null-
*                       terminated string of length 5.
*
*   scode     char[]    The three-letter spectral algorithm code copied or
*                       translated from ctype.  Logarithmic ('LOG') and
*                       tabular ('TAB') codes are also recognized.  If a
*                       non-zero pointer is given, the array must accomodate a
*                       null-terminated string of length 4.
*
*   sname     char[]    Descriptive name of the S-type spectral variable.
*                       If a non-zero pointer is given, the array must
*                       accomodate a null-terminated string of length 22.
*
*   units     char[]    SI units of the S-type spectral variable.  If a
*                       non-zero pointer is given, the array must accomodate a
*                       null-terminated string of length 8.
*
*   ptype     char*     Character code for the P-type spectral variable
*                       derived from ctype, one of 'F', 'W', 'A', or 'V'.
*
*   xtype     char*     Character code for the X-type spectral variable
*                       derived from ctype, one of 'F', 'W', 'A', or 'V'.
*                       Also, 'w' and 'a' are synonymous to 'W' and 'A' for
*                       grisms in vacuo and air respectively.  Set to 'L' or
*                       'T' for logarithmic ('LOG') and tabular ('TAB') axes.
*
*   restreq   int*      Multivalued flag that indicates whether rest
*                       frequency or wavelength is required to compute
*                       spectral variables for this CTYPEia:
*                         0: Not required.
*                         1: Required for the conversion between S- and
*                            P-types (e.g. 'ZOPT-F2W').
*                         2: Required for the conversion between P- and
*                            X-types (e.g. 'BETA-W2V').
*                         3: Required for the conversion between S- and
*                            P-types, and between P- and X-types, but not
*                            between S- and X-types (this applies only for
*                            'VRAD-V2F', 'VOPT-V2W', and 'ZOPT-V2W').
*                        Thus the rest frequency or wavelength is required for
*                        spectral coordinate computations (i.e. between S- and
*                        X-types) only if restreq%3 != 0.
*
*   err       struct wcserr **
*                       For function return values > 1, this struct will
*                       contain a detailed error message.  May be NULL if an
*                       error message is not desired.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         2: Invalid spectral parameters (not a spectral
*                            CTYPEia).
*
*
* spcspxe() - Spectral keyword analysis
* ------------------------------------
* spcspxe() analyses the CTYPEia and CRVALia FITS spectral axis keyword values
* and returns information about the associated X-type spectral variable.
*
* A deprecated form of this function, spcspx(), lacks the wcserr** parameter.
*
* Given:
*   ctypeS    const char[9]
*                       Spectral axis type, i.e. the CTYPEia keyvalue, (eight
*                       characters with null termination).  For non-grism
*                       axes, the character code for the P-type spectral
*                       variable in the algorithm code (i.e. the eighth
*                       character of CTYPEia) may be set to '?' (it will not
*                       be reset).
*
*   crvalS    double    Value of the S-type spectral variable at the reference
*                       point, i.e. the CRVALia keyvalue, SI units.
*
*   restfrq,
*   restwav   double    Rest frequency [Hz] and rest wavelength in vacuo [m],
*                       only one of which need be given, the other should be
*                       set to zero.  Neither are required if the translation
*                       is between wave-characteristic types, or between
*                       velocity-characteristic types.  E.g., required for
*                       'FREQ'     -> 'ZOPT-F2W', but not required for
*                       'VELO-F2V' -> 'ZOPT-F2W'.
*
* Returned:
*   ptype     char*     Character code for the P-type spectral variable
*                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
*
*   xtype     char*     Character code for the X-type spectral variable
*                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
*                       Also, 'w' and 'a' are synonymous to 'W' and 'A' for
*                       grisms in vacuo and air respectively; crvalX and dXdS
*                       (see below) will conform to these.
*
*   restreq   int*      Multivalued flag that indicates whether rest frequency
*                       or wavelength is required to compute spectral
*                       variables for this CTYPEia, as for spctype().
*
*   crvalX    double*   Value of the X-type spectral variable at the reference
*                       point, SI units.
*
*   dXdS      double*   The derivative, dX/dS, evaluated at the reference
*                       point, SI units.  Multiply the CDELTia keyvalue by
*                       this to get the pixel spacing in the X-type spectral
*                       coordinate.
*
*   err       struct wcserr **
*                       For function return values > 1, this struct will
*                       contain a detailed error message.  May be NULL if an
*                       error message is not desired.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         2: Invalid spectral parameters.
*
*
* spcxpse() - Spectral keyword synthesis
* -------------------------------------
* spcxpse(), for the spectral axis type specified and the value provided for
* the X-type spectral variable at the reference point, deduces the value of
* the FITS spectral axis keyword CRVALia and also the derivative dS/dX which
* may be used to compute CDELTia.  See above for an explanation of the S-,
* P-, and X-type spectral variables.
*
* A deprecated form of this function, spcxps(), lacks the wcserr** parameter.
*
* Given:
*   ctypeS    const char[9]
*                       The required spectral axis type, i.e. the CTYPEia
*                       keyvalue, (eight characters with null termination).
*                       For non-grism axes, the character code for the P-type
*                       spectral variable in the algorithm code (i.e. the
*                       eighth character of CTYPEia) may be set to '?' (it
*                       will not be reset).
*
*   crvalX    double    Value of the X-type spectral variable at the reference
*                       point (N.B. NOT the CRVALia keyvalue), SI units.
*
*   restfrq,
*   restwav   double    Rest frequency [Hz] and rest wavelength in vacuo [m],
*                       only one of which need be given, the other should be
*                       set to zero.  Neither are required if the translation
*                       is between wave-characteristic types, or between
*                       velocity-characteristic types.  E.g., required for
*                       'FREQ'     -> 'ZOPT-F2W', but not required for
*                       'VELO-F2V' -> 'ZOPT-F2W'.
*
* Returned:
*   ptype     char*     Character code for the P-type spectral variable
*                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
*
*   xtype     char*     Character code for the X-type spectral variable
*                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
*                       Also, 'w' and 'a' are synonymous to 'W' and 'A' for
*                       grisms; crvalX and cdeltX must conform to these.
*
*   restreq   int*      Multivalued flag that indicates whether rest frequency
*                       or wavelength is required to compute spectral
*                       variables for this CTYPEia, as for spctype().
*
*   crvalS    double*   Value of the S-type spectral variable at the reference
*                       point (i.e. the appropriate CRVALia keyvalue), SI
*                       units.
*
*   dSdX      double*   The derivative, dS/dX, evaluated at the reference
*                       point, SI units.  Multiply this by the pixel spacing
*                       in the X-type spectral coordinate to get the CDELTia
*                       keyvalue.
*
*   err       struct wcserr **
*                       For function return values > 1, this struct will
*                       contain a detailed error message.  May be NULL if an
*                       error message is not desired.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         2: Invalid spectral parameters.
*
*
* spctrne() - Spectral keyword translation
* ---------------------------------------
* spctrne() translates a set of FITS spectral axis keywords into the
* corresponding set for the specified spectral axis type.  For example, a
* 'FREQ' axis may be translated into 'ZOPT-F2W' and vice versa.
*
* A deprecated form of this function, spctrn(), lacks the wcserr** parameter.
*
* Given:
*   ctypeS1   const char[9]
*                       Spectral axis type, i.e. the CTYPEia keyvalue, (eight
*                       characters with null termination).  For non-grism
*                       axes, the character code for the P-type spectral
*                       variable in the algorithm code (i.e. the eighth
*                       character of CTYPEia) may be set to '?' (it will not
*                       be reset).
*
*   crvalS1   double    Value of the S-type spectral variable at the reference
*                       point, i.e. the CRVALia keyvalue, SI units.
*
*   cdeltS1   double    Increment of the S-type spectral variable at the
*                       reference point, SI units.
*
*   restfrq,
*   restwav   double    Rest frequency [Hz] and rest wavelength in vacuo [m],
*                       only one of which need be given, the other should be
*                       set to zero.  Neither are required if the translation
*                       is between wave-characteristic types, or between
*                       velocity-characteristic types.  E.g., required for
*                       'FREQ'     -> 'ZOPT-F2W', but not required for
*                       'VELO-F2V' -> 'ZOPT-F2W'.
*
* Given and returned:
*   ctypeS2   char[9]   Required spectral axis type (eight characters with
*                       null termination).  The first four characters are
*                       required to be given and are never modified.  The
*                       remaining four, the algorithm code, are completely
*                       determined by, and must be consistent with, ctypeS1
*                       and the first four characters of ctypeS2.  A non-zero
*                       status value will be returned if they are inconsistent
*                       (see below).  However, if the final three characters
*                       are specified as "???", or if just the eighth
*                       character is specified as '?', the correct algorithm
*                       code will be substituted (applies for grism axes as
*                       well as non-grism).
*
* Returned:
*   crvalS2   double*   Value of the new S-type spectral variable at the
*                       reference point, i.e. the new CRVALia keyvalue, SI
*                       units.
*
*   cdeltS2   double*   Increment of the new S-type spectral variable at the
*                       reference point, i.e. the new CDELTia keyvalue, SI
*                       units.
*
*   err       struct wcserr **
*                       For function return values > 1, this struct will
*                       contain a detailed error message.  May be NULL if an
*                       error message is not desired.
*
* Function return value:
*             int       Status return value:
*                         0: Success.
*                         2: Invalid spectral parameters.
*
*                       A status value of 2 will be returned if restfrq or
*                       restwav are not specified when required, or if ctypeS1
*                       or ctypeS2 are self-inconsistent, or have different
*                       spectral X-type variables.
*
*
* spcaips() - Translate AIPS-convention spectral keywords
* -------------------------------------------------------
* spcaips() translates AIPS-convention spectral keywords, CTYPEn and VELREF,
* into CTYPEia and SPECSYSa.
*
* Given:
*   ctypeA    const char[9]
*                       CTYPEia keyvalue (eight characters, need not be null-
*                       terminated).
*
*   velref    int       AIPS-convention VELREF code.  It has the following
*                       integer values:
*                         1: LSR kinematic, originally described simply as
*                            "LSR" without distinction between the kinematic
*                            and dynamic definitions.
*                         2: Barycentric, originally described as "HEL"
*                            meaning heliocentric.
*                         3: Topocentric, originally described as "OBS"
*                            meaning geocentric but widely interpreted as
*                            topocentric.
*                       AIPS++ extensions to VELREF are also recognized:
*                         4: LSR dynamic.
*                         5: Geocentric.
*                         6: Source rest frame.
*                         7: Galactocentric.
*                       For an AIPS 'VELO' axis, a radio convention velocity
*                       is denoted by adding 256 to VELREF, otherwise an
*                       optical velocity is indicated (not applicable to
*                       'FELO' axes).  Unrecognized values of VELREF are
*                       simply ignored.
*
*                       VELREF takes precedence over CTYPEia in defining the
*                       Doppler frame, e.g. if
*
=                         CTYPEn = 'VELO-HEL'
=                         VELREF = 1
*
*                       the Doppler frame is set to LSRK.
*
* Returned:
*   ctype     char[9]   Translated CTYPEia keyvalue, or a copy of ctypeA if no
*                       translation was performed (null-filled).
*
*   specsys   char[9]   Doppler reference frame indicated by VELREF or else by
*                       CTYPEn.
*
* Function return value:
*             int       Status return value:
*                        -1: No translation required (not an error).
*                         0: Success.
*
*
* spcprm struct - Spectral transformation parameters
* --------------------------------------------------
* The spcprm struct contains information required to transform spectral
* coordinates.  It consists of certain members that must be set by the user
* ("given") and others that are set by the WCSLIB routines ("returned").  Some
* of the latter are supplied for informational purposes while others are for
* internal use only.
*
*   int flag
*     (Given and returned) This flag must be set to zero whenever any of the
*     following spcprm structure members are set or changed:
*
*       - spcprm::type,
*       - spcprm::code,
*       - spcprm::crval,
*       - spcprm::restfrq,
*       - spcprm::restwav,
*       - spcprm::pv[].
*
*     This signals the initialization routine, spcset(), to recompute the
*     returned members of the spcprm struct.  spcset() will reset flag to
*     indicate that this has been done.
*
*   char type[8]
*     (Given) Four-letter spectral variable type, e.g "ZOPT" for
*     CTYPEia = 'ZOPT-F2W'.  (Declared as char[8] for alignment reasons.)
*
*   char code[4]
*     (Given) Three-letter spectral algorithm code, e.g "F2W" for
*     CTYPEia = 'ZOPT-F2W'.
*
*   double crval
*     (Given) Reference value (CRVALia), SI units.
*
*   double restfrq
*     (Given) The rest frequency [Hz], and ...
*
*   double restwav
*     (Given) ... the rest wavelength in vacuo [m], only one of which need be
*     given, the other should be set to zero.  Neither are required if the
*     X and S spectral variables are both wave-characteristic, or both
*     velocity-characteristic, types.
*
*   double pv[7]
*     (Given) Grism parameters for 'GRI' and 'GRA' algorithm codes:
*       - 0: G, grating ruling density.
*       - 1: m, interference order.
*       - 2: alpha, angle of incidence [deg].
*       - 3: n_r, refractive index at the reference wavelength, lambda_r.
*       - 4: n'_r, dn/dlambda at the reference wavelength, lambda_r (/m).
*       - 5: epsilon, grating tilt angle [deg].
*       - 6: theta, detector tilt angle [deg].
*
* The remaining members of the spcprm struct are maintained by spcset() and
* must not be modified elsewhere:
*
*   double w[6]
*     (Returned) Intermediate values:
*       - 0: Rest frequency or wavelength (SI).
*       - 1: The value of the X-type spectral variable at the reference point
*           (SI units).
*       - 2: dX/dS at the reference point (SI units).
*      The remainder are grism intermediates.
*
*   int isGrism
*     (Returned) Grism coordinates?
*       - 0: no,
*       - 1: in vacuum,
*       - 2: in air.
*
*   int padding1
*     (An unused variable inserted for alignment purposes only.)
*
*   struct wcserr *err
*     (Returned) If enabled, when an error status is returned this structure
*     contains detailed information about the error, see wcserr_enable().
*
*   void *padding2
*     (An unused variable inserted for alignment purposes only.)
*   int (*spxX2P)(SPX_ARGS)
*     (Returned) The first and ...
*   int (*spxP2S)(SPX_ARGS)
*     (Returned) ... the second of the pointers to the transformation
*     functions in the two-step algorithm chain X -> P -> S in the
*     pixel-to-spectral direction where the non-linear transformation is from
*     X to P.  The argument list, SPX_ARGS, is defined in spx.h.
*
*   int (*spxS2P)(SPX_ARGS)
*     (Returned) The first and ...
*   int (*spxP2X)(SPX_ARGS)
*     (Returned) ... the second of the pointers to the transformation
*     functions in the two-step algorithm chain S -> P -> X in the
*     spectral-to-pixel direction where the non-linear transformation is from
*     P to X.  The argument list, SPX_ARGS, is defined in spx.h.
*
*
* Global variable: const char *spc_errmsg[] - Status return messages
* ------------------------------------------------------------------
* Error messages to match the status value returned from each function.
*
*===========================================================================*/

#ifndef WCSLIB_SPC
#define WCSLIB_SPC

#include "spx.h"
#include "wcserr.h"

#ifdef __cplusplus
extern "C" {
#endif


extern const char *spc_errmsg[];

enum spc_errmsg_enum {
  SPCERR_SUCCESS         = 0,	/* Success. */
  SPCERR_NULL_POINTER    = 1,	/* Null spcprm pointer passed. */
  SPCERR_BAD_SPEC_PARAMS = 2,	/* Invalid spectral parameters. */
  SPCERR_BAD_X           = 3,	/* One or more of x coordinates were
				   invalid. */
  SPCERR_BAD_SPEC        = 4 	/* One or more of the spec coordinates were
				   invalid. */
};

struct spcprm {
  /* Initialization flag (see the prologue above).                          */
  /*------------------------------------------------------------------------*/
  int    flag;			/* Set to zero to force initialization.     */

  /* Parameters to be provided (see the prologue above).                    */
  /*------------------------------------------------------------------------*/
  char   type[8];		/* Four-letter spectral variable type.      */
  char   code[4];		/* Three-letter spectral algorithm code.    */

  double crval;			/* Reference value (CRVALia), SI units.     */
  double restfrq;		/* Rest frequency, Hz.                      */
  double restwav;		/* Rest wavelength, m.                      */

  double pv[7];			/* Grism parameters:                        */
				/*   0: G, grating ruling density.          */
				/*   1: m, interference order.              */
				/*   2: alpha, angle of incidence.          */
				/*   3: n_r, refractive index at lambda_r.  */
				/*   4: n'_r, dn/dlambda at lambda_r.       */
				/*   5: epsilon, grating tilt angle.        */
				/*   6: theta, detector tilt angle.         */

  /* Information derived from the parameters supplied.                      */
  /*------------------------------------------------------------------------*/
  double w[6];			/* Intermediate values.                     */
				/*   0: Rest frequency or wavelength (SI).  */
				/*   1: CRVALX (SI units).                  */
				/*   2: CDELTX/CDELTia = dX/dS (SI units).  */
				/* The remainder are grism intermediates.   */

  int    isGrism;		/* Grism coordinates?  1: vacuum, 2: air.   */
  int    padding1;		/* (Dummy inserted for alignment purposes.) */

  /* Error handling                                                         */
  /*------------------------------------------------------------------------*/
  struct wcserr *err;

  /* Private                                                                */
  /*------------------------------------------------------------------------*/
  void   *padding2;		/* (Dummy inserted for alignment purposes.) */
  int (*spxX2P)(SPX_ARGS);	/* Pointers to the transformation functions */
  int (*spxP2S)(SPX_ARGS);	/* in the two-step algorithm chain in the   */
				/* pixel-to-spectral direction.             */

  int (*spxS2P)(SPX_ARGS);	/* Pointers to the transformation functions */
  int (*spxP2X)(SPX_ARGS);	/* in the two-step algorithm chain in the   */
				/* spectral-to-pixel direction.             */
};

/* Size of the spcprm struct in int units, used by the Fortran wrappers. */
#define SPCLEN (sizeof(struct spcprm)/sizeof(int))


int spcini(struct spcprm *spc);

int spcfree(struct spcprm *spc);

int spcprt(const struct spcprm *spc);

int spcset(struct spcprm *spc);

int spcx2s(struct spcprm *spc, int nx, int sx, int sspec,
           const double x[], double spec[], int stat[]);

int spcs2x(struct spcprm *spc, int nspec, int sspec, int sx,
           const double spec[], double x[], int stat[]);

int spctype(const char ctype[], char stype[], char scode[], char sname[],
            char units[], char *ptype, char *xtype, int *restreq,
            struct wcserr **err);

int spcspxe(const char ctypeS[], double crvalS, double restfrq,
            double restwav, char *ptype, char *xtype, int *restreq,
            double *crvalX, double *dXdS, struct wcserr **err);

int spcxpse(const char ctypeS[], double crvalX, double restfrq,
            double restwav, char *ptype, char *xtype, int *restreq,
            double *crvalS, double *dSdX, struct wcserr **err);

int spctrne(const char ctypeS1[], double crvalS1, double cdeltS1,
            double restfrq, double restwav, char ctypeS2[], double *crvalS2,
            double *cdeltS2, struct wcserr **err);

int spcaips(const char ctypeA[], int velref, char ctype[], char specsys[]);


/* Deprecated. */
#define spcini_errmsg spc_errmsg
#define spcprt_errmsg spc_errmsg
#define spcset_errmsg spc_errmsg
#define spcx2s_errmsg spc_errmsg
#define spcs2x_errmsg spc_errmsg

int spctyp(const char ctype[], char stype[], char scode[], char sname[],
           char units[], char *ptype, char *xtype, int *restreq);
int spcspx(const char ctypeS[], double crvalS, double restfrq, double restwav,
           char *ptype, char *xtype, int *restreq, double *crvalX,
           double *dXdS);
int spcxps(const char ctypeS[], double crvalX, double restfrq, double restwav,
           char *ptype, char *xtype, int *restreq, double *crvalS,
           double *dSdX);
int spctrn(const char ctypeS1[], double crvalS1, double cdeltS1,
           double restfrq, double restwav, char ctypeS2[], double *crvalS2,
           double *cdeltS2);

#ifdef __cplusplus
}
#endif

#endif /* WCSLIB_SPC */