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
|
include <imhdr.h>
include <error.h>
# Maximum number of correction function coefficients.
define MAXCOEF 3
# Maximum number of ADU....
define MAXADU 32767.0
# T_ARLINCOR -- Corrects IR imager frames for non linearity. This task
# only corrects a section of the total image and copies the rest of
# the image intact to the output image.
procedure t_irlincor ()
pointer inlist, outlist # input and output image lists
char section[SZ_LINE] # image section
pointer coeff # coeficients of correction function
bool sflag
pointer imin, imout
pointer input, output, orig, temp
pointer sp
int strlen()
int imtgetim(), imtlen()
real clgetr()
pointer immap(), imtopenp()
begin
# Get parameters
inlist = imtopenp ("input")
outlist = imtopenp ("output")
call clgstr ("section", section, SZ_LINE)
# Check that the input and output image lists have the
# same number of images. Abort if that's not the case.
if (imtlen (inlist) != imtlen (outlist)) {
call imtclose (inlist)
call imtclose (outlist)
call error (1, "Input and output image lists don't match")
}
# Set section flag
sflag = (strlen (section) > 0)
# Allocate string space
call smark (sp)
call salloc (input, SZ_FNAME, TY_CHAR)
call salloc (output, SZ_FNAME, TY_CHAR)
call salloc (orig, SZ_FNAME, TY_CHAR)
call salloc (temp, SZ_FNAME, TY_CHAR)
# Allocate memory for the correction coefficients and
# read them from the parameter file.
call malloc (coeff, MAXCOEF, TY_REAL)
Memr[coeff] = clgetr ("coeff1")
Memr[coeff+1] = clgetr ("coeff2")
Memr[coeff+2] = clgetr ("coeff3")
# Loop over all images in the input and output lists
while ((imtgetim (inlist, Memc[input], SZ_FNAME) != EOF) &&
(imtgetim (outlist, Memc[output], SZ_FNAME) != EOF)) {
# Generate temporary output image name to allow for
# input and output images having the same name
call xt_mkimtemp (Memc[input], Memc[output], Memc[orig], SZ_FNAME)
# Take different actions depending on whether the image section
# is specified or not, in order to optimize speed. When the image
# section is specified the input image is copied to the output
# image and then the output image opened to work on the section.
# Otherwise the output image is created only once.
if (sflag) {
# Copy input image into output image using fast copy
iferr (call irl_imcopy (Memc[input], Memc[output])) {
call erract (EA_WARN)
next
}
# Append section to image names. The output name should
# be preserved without the section for later use.
call strcat (section, Memc[input], SZ_FNAME)
call sprintf (Memc[temp], SZ_FNAME, "%s%s")
call pargstr (Memc[output])
call pargstr (section)
# Open input and output images. The output image already
# exists, since it was created by the copy operation, so
# it is opened as read/write.
iferr (imin = immap (Memc[input], READ_ONLY, 0)) {
call erract (EA_WARN)
next
}
iferr (imout = immap (Memc[temp], READ_WRITE, 0)) {
call imunmap (imin)
call erract (EA_WARN)
next
}
} else {
# Open input and output images. The output image does not
# exist already so it is opened as a new copy of the input
# image.
iferr (imin = immap (Memc[input], READ_ONLY, 0)) {
call erract (EA_WARN)
next
}
iferr (imout = immap (Memc[output], NEW_COPY, imin)) {
call imunmap (imin)
call erract (EA_WARN)
next
}
}
# Perform the linear correction.
call irl_correct (imin, imout, Memr[coeff], MAXCOEF)
# Close images
call imunmap (imin)
call imunmap (imout)
# Replace output image with the temporary image. This is a
# noop if the input and output images have different names
call xt_delimtemp (Memc[output], Memc[orig])
}
# Free memory and close image lists
call mfree (coeff, TY_REAL)
call imtclose (inlist)
call imtclose (outlist)
end
# IRL_CORRECT -- Corrects an IR imager frame for non-linearity using a
# simple power series polynomial correction function:
#
# ADU' = ADU * [ a + b * (ADU / MAXADU) + c * (ADU / MAXADU) **2 ]
#
procedure irl_correct (imin, imout, coeff, ncoef)
pointer imin # input image pointer
pointer imout # output image pointer
real coeff[ncoef] # coefficients of polynomial function
int ncoef # number of polynomial coeficients
int col, ncols
long v1[IM_MAXDIM], v2[IM_MAXDIM]
pointer inbuf, outbuf
int imgeti()
int imgnlr(), impnlr()
real apolr()
begin
# Initiliaze counters for line i/o
call amovkl (long(1), v1, IM_MAXDIM)
call amovkl (long(1), v2, IM_MAXDIM)
# Number of pixels per line
ncols = imgeti (imin, "i_naxis1")
# Loop over image lines
while ((imgnlr (imin, inbuf, v1) != EOF) &&
(impnlr (imout, outbuf, v2) != EOF)) {
call adivkr (Memr[inbuf], MAXADU, Memr[outbuf], ncols)
do col = 1, ncols {
Memr[outbuf+col-1] = apolr (Memr[outbuf+col-1], coeff, ncoef)
}
call amulr (Memr[inbuf], Memr[outbuf], Memr[outbuf], ncols)
}
end
# IRL_IMCOPY -- Copy input image into the output image. Avoid data type
# conversion in order to opetimize speed.
procedure irl_imcopy (input, output)
char input[ARB] # input image name
char output[ARB] # output image name
int npix
long vin[IM_MAXDIM], vout[IM_MAXDIM]
pointer imin, imout
pointer inline, outline
int imgeti()
int imgnls(), impnls()
int imgnli(), impnli()
int imgnll(), impnll()
int imgnlr(), impnlr()
int imgnld(), impnld()
int imgnlx(), impnlx()
pointer immap()
begin
# Open input and output images
iferr (imin = immap (input, READ_ONLY, 0))
call erract (EA_ERROR)
iferr (imout = immap (output, NEW_COPY, imin)) {
call imunmap (imin)
call erract (EA_ERROR)
}
# Initiliaze counters
call amovkl (long(1), vin, IM_MAXDIM)
call amovkl (long(1), vout, IM_MAXDIM)
# Copy image lines
switch (imgeti (imin, "i_pixtype")) {
case TY_SHORT, TY_USHORT:
while (imgnls (imin, inline, vin) != EOF) {
npix = impnls (imout, outline, vout)
call amovs (Mems[inline], Mems[outline], npix)
}
case TY_INT:
while (imgnli (imin, inline, vin) != EOF) {
npix = impnli (imout, outline, vout)
call amovi (Memi[inline], Memi[outline], npix)
}
case TY_LONG:
while (imgnll (imin, inline, vin) != EOF) {
npix = impnll (imout, outline, vout)
call amovl (Meml[inline], Meml[outline], npix)
}
case TY_REAL:
while (imgnlr (imin, inline, vin) != EOF) {
npix = impnlr (imout, outline, vout)
call amovr (Memr[inline], Memr[outline], npix)
}
case TY_DOUBLE:
while (imgnld (imin, inline, vin) != EOF) {
npix = impnld (imout, outline, vout)
call amovd (Memd[inline], Memd[outline], npix)
}
case TY_COMPLEX:
while (imgnlx (imin, inline, vin) != EOF) {
npix = impnlx (imout, outline, vout)
call amovx (Memx[inline], Memx[outline], npix)
}
default:
call error (0, "Unsupported pixel type")
}
# Close images
call imunmap (imin)
call imunmap (imout)
end
|