aboutsummaryrefslogtreecommitdiff
path: root/pkg/proto/maskexpr/t_mskexpr.x
blob: 9a1aa91272688054bbcdc821db4ab9ef8adcc36f (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
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
include <fset.h>
include <ctype.h>
include <imhdr.h>

# T_MSKEXPR -- Create a list of pixel masks using an expression and a list of
# reference images.
#
# The input expression may be any legal EVVEXPR expression which can be
# converted to a valid integer mask pixel value. The input operands must be one
# of, i for the reference image, i.keyword for a reference image header
# keyword, m for the input mask image, m.keyword for the input mask image
# header keyword a numeric constant, a builtin function, or the pixel operands
# I, J, K, etc. May be desirable to replace the reference image operand
# i with $I. This is a detail however.
#
# This task uses the get tokens library in images to expand the macros.
# This library should probably be removed from images and put in xtools
# for the applications programmers or in the core system as a useful
# library maybe in fmtio like imexpr. There is a similar if not identical(?)
# library in qpoe.

procedure t_mskexpr()

pointer	expr, st, xexpr, refim, pmim, refmsk
pointer	sp, exprdb, dims, uaxlen, mskname, imname, refname
int	i, ip, op, msklist, imlist, rmsklist, len_exprbuf, fd, nchars, ch
int	undim, npix, depth
bool	verbose

pointer	me_getexprdb(), me_expandtext(), immap(), yt_mappm(), me_mkmask()
long	fstatl()
int	imtopenp(), imtlen(), open(), getci(), imtgetim(), ctoi()
int	clgeti(), strmatch(), imaccess()
bool	clgetb(), strne()
errchk	immap(), yt_pmmap()

begin
	# Get the expression parameter.
	call malloc (expr, SZ_COMMAND, TY_CHAR)
	call clgstr ("expr", Memc[expr], SZ_COMMAND)

	# Get the output mask list.
	msklist = imtopenp ("masks")
	if (imtlen (msklist) <= 0) {
	    call eprintf ("The output mask list is empty\n")
	    call imtclose (msklist)
	    call mfree (expr, TY_CHAR)
	    return
	}

	# Get the input reference image list.
	imlist = imtopenp ("refimages")
	if (imtlen (imlist) > 0 && imtlen (imlist) != imtlen (msklist)) {
	    call eprintf (
	    "The reference image and output mask lists are not the same size\n")
	    call imtclose (imlist) 
	    call imtclose (msklist)
	    call mfree (expr, TY_CHAR)
	    return
	}

	# Get the input reference mask list.
	rmsklist = imtopenp ("refmasks")
	if (imtlen (rmsklist) > 0 && imtlen (rmsklist) != imtlen (msklist)) {
	    call eprintf (
	    "The reference image and output mask lists are not the same size\n")
	    call imtclose (rmsklist)
	    call imtclose (msklist)
	    call imtclose (imlist) 
	    call mfree (expr, TY_CHAR)
	    return
	}

	# Get some working space.
	call smark (sp)
	call salloc (exprdb, SZ_FNAME, TY_CHAR)
	call salloc (dims, SZ_FNAME, TY_CHAR)
	call salloc (uaxlen, IM_MAXDIM, TY_LONG)
	call salloc (mskname, SZ_FNAME, TY_CHAR)
	call salloc (imname, SZ_FNAME, TY_CHAR)
	call salloc (refname, SZ_FNAME, TY_CHAR)

	# Get remaining parameters,
	call clgstr ("exprdb", Memc[exprdb], SZ_PATHNAME)
	call clgstr ("dims", Memc[dims], SZ_FNAME)
	depth = clgeti ("depth")
	verbose = clgetb ("verbose")

	# Load the expression database if any.
	if (strne (Memc[exprdb], "none"))
	    st = me_getexprdb (Memc[exprdb])
	else
	    st = NULL

	# Get the expression to be evaluated and expand any file inclusions
	# or macro references.
	len_exprbuf = SZ_COMMAND
	if (Memc[expr] == '@') {
	    fd = open (Memc[expr+1], READ_ONLY, TEXT_FILE)
	    nchars = fstatl (fd, F_FILESIZE)
	    if (nchars > len_exprbuf) {
		len_exprbuf = nchars
		call realloc (expr, len_exprbuf, TY_CHAR)
	    }
	    for (op = expr;  getci(fd, ch) != EOF;  op = op + 1) {
		if (ch == '\n')
		    Memc[op] = ' '
		else
		    Memc[op] = ch
	    }
	    Memc[op] = EOS
	    call close (fd)
	}
	if (st != NULL) {
	    xexpr = me_expandtext (st, Memc[expr])
	    call mfree (expr, TY_CHAR)
	    expr = xexpr
	}
	if (verbose) {
	    call printf ("Expr: %s\n")
	        call pargstr (Memc[expr])
	    call flush (STDOUT)
	}

	# Determine the default dimension and size of the output image.  If the 
	# reference image is defined then the dimensions of the reference
	# image determine the dimensions of the output mask. Otherwise the
	# default dimensions are used.

	undim = 0
	call aclrl (Meml[uaxlen], IM_MAXDIM)
	for (ip = 1;  ctoi (Memc[dims], ip, npix) > 0;  ) {
	    Meml[uaxlen+undim] = npix
	    undim = undim + 1
	    for (ch = Memc[dims+ip-1];  IS_WHITE(ch) || ch == ',';
	        ch = Memc[dims+ip-1])
	        ip = ip + 1
	}

	# Loop over the output mask names.
	while (imtgetim (msklist, Memc[mskname], SZ_FNAME) != EOF) {

	    # Add .pl to output mask name.
	    if (strmatch (Memc[mskname], ".pl$") == 0)
		call strcat (".pl", Memc[mskname], SZ_FNAME)

	    # Check whether the output mask already exists.
	    if (imaccess (Memc[mskname], 0) == YES) {
		if (verbose) {
		    call printf ("Mask %s already exists\n")
			call pargstr (Memc[mskname])
		}
		next
	    }

	    # Open the reference image.
	    if (imtlen (imlist) > 0) {
		if (imtgetim (imlist, Memc[imname], SZ_FNAME) != EOF) {
		    iferr (refim = immap (Memc[imname], READ_ONLY, 0)) {
			refim = NULL
		        call printf (
			    "Cannot open reference image %s for mask %s\n")
			    call pargstr (Memc[imname])
			    call pargstr (Memc[mskname])
		        next
		    }
		} else {
		    refim = NULL
		    call printf ("Cannot open reference image for mask %s\n")
			call pargstr (Memc[mskname])
		    next
		}
	    } else
		refim = NULL

	    # Open the reference mask.
	    if (imtlen (rmsklist) > 0) {
		if (imtgetim (rmsklist, Memc[refname], SZ_FNAME) != EOF) {
		    if (refim != NULL) {
		        iferr (refmsk = yt_mappm (Memc[refname], refim,
			    "logical", Memc[refname], SZ_FNAME))
			    refmsk = NULL
		    } else {
			iferr (refmsk = immap (Memc[refname], READ_ONLY, 0))
			    refmsk = NULL
		    }
		    if (refmsk == NULL) {
		        call printf (
			    "Cannot open reference mask %s for mask %s\n")
			    call pargstr (Memc[refname])
			    call pargstr (Memc[mskname])
		        if (refim != NULL)
		            call imunmap (refim)
		        next
		    } else if (refim != NULL) {
			if (IM_NDIM(refim) != IM_NDIM(refmsk)) {
		            call printf (
			    "Reference image and mask for %s don't match\n")
			        call pargstr (Memc[mskname])
			    call imunmap (refmsk)
			    if (refim != NULL)
			        call imunmap (refim)
			    next
			} else {
			    do i = 1, IM_NDIM(refim) {
				if (IM_LEN(refim,i) == IM_LEN(refmsk,i))
				    next
				else
				    break
			    }
			    if (i <= IM_NDIM(refim)) {
		                call printf (
			        "Reference image and mask for %s don't match\n")
			            call pargstr (Memc[mskname])
			        call imunmap (refmsk)
			        if (refim != NULL)
			            call imunmap (refim)
				next
			    }
			}
		    }
		} else {
		    refmsk = NULL
		    call printf ("Cannot open reference mask for mask %s\n")
			call pargstr (Memc[refname])
		    if (refim != NULL)
		        call imunmap (refim)
		    next
		}
	    } else
		refmsk = NULL

	    if (verbose) {
		if (refim != NULL && refmsk != NULL) {
		    call printf ("Creating mask %s\n")
			call pargstr (Memc[mskname])
		    call printf ("    Using reference image %s and mask %s\n")
			call pargstr (Memc[imname])
			call pargstr (Memc[refname])
		} else if (refim != NULL) {
		    call printf ("Creating mask %s using reference image %s\n")
			call pargstr (Memc[mskname])
			call pargstr (Memc[imname])
		} else if (refmsk != NULL) {
		    call printf ("Creating mask %s using reference image %s\n")
			call pargstr (Memc[mskname])
			call pargstr (Memc[refname])
		} else {
		    call printf ("Creating mask %s\n")
			call pargstr (Memc[mskname])
		}
	    }

	    # Evalute the expression return a mask image pointer.
	    if (refim != NULL)
	        pmim = me_mkmask (Memc[expr], Memc[mskname], refim, refmsk,
	            IM_NDIM(refim), IM_LEN(refim,1), depth)
	    else if (refmsk != NULL)
	        pmim = me_mkmask (Memc[expr], Memc[mskname], refim, refmsk,
	            IM_NDIM(refmsk), IM_LEN(refmsk,1), depth)
	    else
	        pmim = me_mkmask (Memc[expr], Memc[mskname], refim, refmsk,
	            undim, Meml[uaxlen], depth)

	    # Save the mask.
	    call imunmap (pmim)

	    # Close the reference image.
	    if (refim != NULL)
	        call imunmap (refim)

	    # Close the reference mask.
	    if (refmsk != NULL)
	        call imunmap (refmsk)
	}

	# Cleanup.
	call mfree (expr, TY_CHAR) 
	if (st != NULL)
	    call stclose (st)
	call imtclose (rmsklist)
	call imtclose (msklist)
	call imtclose (imlist)
	call sfree (sp)
end