aboutsummaryrefslogtreecommitdiff
path: root/sys/mwcs/iwrfits.x
blob: b70208a504b50b6844751d9571760f5e949ff519 (plain) (blame)
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
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<syserr.h>
include	<imhdr.h>
include <ctype.h>
include	<imio.h>
include	"mwcs.h"
include	"imwcs.h"

# IW_RFITS -- Read a FITS image header into an IMWCS (FITS oriented) world
# coordinate system descriptor.  For reasons of efficiency (especially due
# to the possibly of large sampled WCS arrays) this is done with a single
# pass through the header to get all the WCS data, with interpretation of
# the data being a separate independent step.  A pointer to an IMWCS descriptor
# is returned as the function value.  When no longer needed, this should be
# freed with IW_CLOSE.  The dimensionality of the WCS is determined first
# from the image dimensionality (which may be zero) and then overridden
# if there is a WCSDIM card.  If the final dimensionality is zero then
# the maximum axis of the WCS cards sets the dimensionality.


pointer procedure iw_rfits (mw, im, mode)

pointer	mw			#I pointer to MWCS descriptor
pointer	im			#I pointer to image header
int	mode			#I RF_REFERENCE or RF_COPY

double	dval
bool	omit, copy
pointer	iw, idb, rp, cp, fp
int	ndim, recno, ualen, type, axis, index, ip, temp, i

pointer	idb_open()
int	idb_nextcard(), iw_cardtype(), ctod(), ctoi()
errchk	calloc, realloc, syserrs

begin
	ndim = max (IM_NDIM(im), IM_NPHYSDIM(im))
	copy = (mode == RF_COPY)

	# Allocate and initialize the FITS-WCS descriptor.
	call calloc (iw, LEN_IMWCS, TY_STRUCT)
	call calloc (IW_CBUF(iw), LEN_CDES * DEF_MAXCARDS, TY_STRUCT)

	# Allocate string buffer if we must keep a local copy of the data.
	if (copy) {
	    call calloc (IW_SBUF(iw), SZ_SBUF, TY_CHAR)
	    IW_SBUFLEN(iw) = SZ_SBUF
	    IW_SBUFOP(iw) = 0
	}

	IW_MAXCARDS(iw) = DEF_MAXCARDS
	IW_NDIM(iw) = ndim
	IW_IM(iw) = im

	# Scan the image header, examining successive cards to see if they
	# are WCS specification cards, making an entry for each such card
	# in the IMWCS descriptor.  The values of simple scalar valued cards
	# are interpreted immediately and used to modify the default WCS
	# data values established above.  For the array valued parameters we
	# merely record the particulars for each card, leaving reconstruction
	# of the array until all the cards have been located.

	idb = idb_open (im, ualen)
	recno = 0
	while (idb_nextcard (idb, rp) != EOF) {
	    recno = recno + 1
	    if (iw_cardtype (Memc[rp], type, axis, index) <= 0)
		next


	    # Has this card already been seen?
	    omit = false
	    do i = 1, IW_NCARDS(iw) {
		cp = IW_CARD(iw,i)
		if (C_TYPE(cp) != type)
		    next
		if (C_AXIS(cp) != axis)
		    next
		if (C_INDEX(cp) != index)
		    next
		omit = true
		break
	    }

	    # Ignore duplicate cards.
	    if (omit)
		next

	    # Get another card descriptor.
	    IW_NCARDS(iw) = IW_NCARDS(iw) + 1
	    if (IW_NCARDS(iw) > IW_MAXCARDS(iw)) {
		IW_MAXCARDS(iw) = IW_MAXCARDS(iw) + INC_MAXCARDS
		call realloc (IW_CBUF(iw),
		    IW_MAXCARDS(iw) * LEN_CDES, TY_STRUCT)
		cp = IW_CARD(iw,IW_NCARDS(iw))
		call aclri (Memi[cp],
		    (IW_MAXCARDS(iw) - IW_NCARDS(iw) + 1) * LEN_CDES)
	    }
	    cp = IW_CARD(iw,IW_NCARDS(iw))

	    C_TYPE(cp) = type
	    C_AXIS(cp) = axis
	    C_INDEX(cp) = index
	    C_CARDNO(cp) = recno

	    ndim = max (ndim, axis)

	    # The FITS data must be copied into local storage if the header
	    # will be edited, since otherwise the cards may move, invalidating
	    # the pointer.  Always save whole cards; don't bother with an EOS
	    # or newline between cards.

	    if (copy) {
		if (IW_SBUFOP(iw) + SZ_CARD > IW_SBUFLEN(iw))
		    call syserrs (SYS_MWFITSOVFL, IM_NAME(im))
		C_RP(cp) = IW_SBUF(iw) + IW_SBUFOP(iw)
		call strcpy (Memc[rp], Memc[C_RP(cp)], SZ_CARD)
		IW_SBUFOP(iw) = IW_SBUFOP(iw) + SZ_CARD
	    } else
		C_RP(cp) = rp

	    # Decode the card value. 
	    ip = IDB_STARTVALUE
	    switch (type) {
	    case TY_CTYPE:
		fp = C_RP(cp) + ip
		while (IS_WHITE(Memc[fp]) || Memc[fp] == '\'')
		    fp = fp + 1
		IW_CTYPE(iw,axis) =  fp
	    case TY_CDELT:
		if (ctod (Memc[rp], ip, IW_CDELT(iw,axis)) <= 0)
		    IW_CDELT(iw,axis) = 0.0
	    case TY_CROTA:
		if (ctod (Memc[rp], ip, dval) > 0)
		    IW_CROTA(iw) = dval
	    case TY_CRPIX:
		if (ctod (Memc[rp], ip, IW_CRPIX(iw,axis)) <= 0)
		    IW_CRPIX(iw,axis) = 0.0
	    case TY_CRVAL:
		if (ctod (Memc[rp], ip, IW_CRVAL(iw,axis)) <= 0)
		    IW_CRVAL(iw,axis) = 0.0
	    case TY_CD:
		if (ctod (Memc[rp], ip, IW_CD(iw,axis,index)) <= 0)
		    IW_CD(iw,axis,index) = 0.0
	    case TY_LTV:
		if (ctod (Memc[rp], ip, IW_LTV(iw,axis)) <= 0)
		    IW_LTV(iw,axis) = 0.0
	    case TY_LTM:
		if (ctod (Memc[rp], ip, IW_LTM(iw,axis,index)) <= 0)
		    IW_LTM(iw,axis,index) = 0.0
	    case TY_WSVLEN:
		if (ctoi (Memc[rp], ip, IW_WSVLEN(iw,axis)) <= 0)
		    IW_WSVLEN(iw,axis) = 0
	    case TY_WCSDIM:
		if (ctoi (Memc[rp], ip, temp) > 0)
		    IW_NDIM(iw) = temp
	    }
	}

	# Set dimension to the maximum axis seen.
	if (IW_NDIM(iw) == 0)
	    IW_NDIM(iw) = ndim

	call idb_close (idb)
	return (iw)
end