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
|
include <error.h>
include <imhdr.h>
include "epix.h"
define HELP "imedit_help$"
define PROMPT "imedit options"
# T_IMEDIT -- Edit image pixels.
# This task provides selection of pixels to be edit via cursor or file
# input. The regions to be edited may be defined as a rectangle or a
# center and radius for a circular or square aperture. The replacement
# options include constant substitution, background substitution, column
# or line interpolation, and moving one region to another. In addition
# this task can be used to select and display regions in surface perspective
# and to print statistics. The image display interface temporarily
# used simple calls to a user specified display task (such as TV.DISPLAY).
# The editing is done in a temporary image buffer. The commands which
# alter the input image may be logged if a log file is given.
procedure t_imedit ()
int inlist # List of input images
int outlist # List of output images
int i, key, ap, xa, ya, xb, yb, x1, x2, y1, y2
int change, changes, newdisplay, newimage
bool erase
pointer sp, ep, cmd, temp
pointer im
bool streq()
pointer immap(), imgl2r(), impl2r()
int imtopenp(), imtlen(), imtgetim(), imaccess(), ep_gcur()
errchk immap, imdelete, ep_imcopy, ep_setpars, imgl2r, impl2r
define newim_ 99
begin
call smark (sp)
call salloc (cmd, SZ_LINE, TY_CHAR)
# Allocate and initialize imedit descriptor.
call salloc (ep, EP_LEN, TY_STRUCT)
call aclri (Memi[ep], EP_LEN)
# Check the input and output image lists have proper format.
inlist = imtopenp ("input")
outlist = imtopenp ("output")
if (imtlen (outlist) > 0 && imtlen (outlist) != imtlen (inlist))
call error (1, "Input and output lists are not the same length")
# Set the rest of the task parameters.
call ep_setpars (ep)
# Repeat on each input image.
while (imtgetim (inlist, EP_INPUT(ep), EP_SZFNAME) != EOF) {
if (imtgetim (outlist, EP_OUTPUT(ep), EP_SZFNAME) == EOF)
call strcpy (EP_INPUT(ep), EP_OUTPUT(ep), EP_SZFNAME)
else if (imaccess (EP_OUTPUT(ep), READ_ONLY) == YES) {
call eprintf ("%s: Output image %s exists\n")
call pargstr (EP_INPUT(ep))
call pargstr (EP_OUTPUT(ep))
next
}
# The editing takes place in a temporary editing image buffer.
newim_ call strcpy (EP_OUTPUT(ep), EP_WORK(ep), EP_SZFNAME)
call xt_mkimtemp (EP_OUTPUT(ep), EP_WORK(ep), EP_OUTPUT(ep),
EP_SZFNAME)
iferr (call ep_imcopy (EP_INPUT(ep), EP_WORK(ep))) {
call erract (EA_WARN)
next
}
EP_IM(ep) = immap (EP_WORK(ep), READ_WRITE, 0)
EP_INDATA(ep) = NULL
EP_OUTDATA(ep) = NULL
if (EP_LOGFD(ep) != NULL) {
call fprintf (EP_LOGFD(ep), "# Input image %s\n")
call pargstr (EP_INPUT(ep))
}
if (EP_DISPLAY(ep) == YES) {
key = '0'
call ep_zoom (ep, xa, ya, xb, yb, key, erase)
call ep_command (ep, EP_WORK(ep), erase)
}
# Enter the cursor loop. The apertures and commands are
# returned by the EP_GCUR procedure.
newimage = NO
changes = 0
while (ep_gcur (ep,ap,xa,ya,xb,yb,key,Memc[cmd],SZ_LINE) != EOF) {
newdisplay = NO
change = NO
iferr {
switch (key) {
case '?': # Print help
call pagefile (HELP, PROMPT)
case ':': # Process colon commands
call ep_colon (ep, Memc[cmd], newimage)
if (newimage == YES)
break
case 'a', 'b': # Background replacement
call ep_background (ep, ap, xa, ya, xb, yb)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case 'c': # Column interpolation
call ep_col (ep, ap, xa, ya, xb, yb)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case 'd', 'e', 'v': # Constant value
call ep_constant (ep, ap, xa, ya, xb, yb)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case 'f': # Diagonal aperture
if (ap == APCDIAG)
call ep_col (ep, ap, xa, ya, xb, yb)
else
call ep_line (ep, ap, xa, ya, xb, yb)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case '=', '<', '>': # Replace
if (IM_PIXTYPE(EP_IM(ep)) == TY_INT)
call ep_replacei (ep, xa, ya, key)
else
call ep_replacer (ep, xa, ya, key)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case 'i': # Initialize
call imunmap (EP_IM(ep))
goto newim_
case 'j', 'k': # Replace with input
call ep_input (ep, ap, xa, ya, xb, yb)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case 'l': # Line interpolation
call ep_line (ep, ap, xa, ya, xb, yb)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case 'm', 'n': # Move
i = ep_gcur (ep, ap, x1, y1, x2, y2, key,
Memc[cmd],SZ_LINE)
call ep_move (ep, ap, xa, ya, xb, yb, x1, y1, x2, y2,
key)
if (EP_OUTDATA(ep) != NULL) {
change = YES
changes = changes + 1
}
case 'g': # Surface graph
call ep_dosurface (ep)
case ' ': # Statistics
call ep_statistics (ep, ap, xa, ya, xb, yb, NO)
case 'p':
call ep_statistics (ep, ap, xa, ya, xb, yb, YES)
case 't':
EP_SEARCH(ep) = -EP_SEARCH(ep)
call ep_colon (ep, "search", newimage)
case '+':
EP_RADIUS(ep) = EP_RADIUS(ep) + 1.
call ep_colon (ep, "radius", newimage)
case '-':
EP_RADIUS(ep) = max (0., EP_RADIUS(ep) - 1.)
call ep_colon (ep, "radius", newimage)
case 's': # Surface plot
i = max (5.,
abs (EP_SEARCH(ep))+EP_BUFFER(ep)+EP_WIDTH(ep)+1)
x1 = min (xa, xb) - i
x2 = max (xa, xb) + i
y1 = min (ya, yb) - i
y2 = max (ya, yb) + i
call ep_gindata (ep, x1, x2, y1, y2)
EP_OUTDATA(ep) = NULL
call ep_dosurface (ep)
case 'q': # Quit and save
case 'u': # Undo
if (EP_OUTDATA(ep) != NULL && EP_INDATA(ep) != NULL) {
call malloc (temp, EP_NPTS(ep), TY_REAL)
call amovr (Memr[EP_OUTDATA(ep)], Memr[temp],
EP_NPTS(ep))
call amovr (Memr[EP_INDATA(ep)],
Memr[EP_OUTDATA(ep)], EP_NPTS(ep))
call amovr (Memr[temp], Memr[EP_INDATA(ep)],
EP_NPTS(ep))
call mfree (temp, TY_REAL)
change = YES
} else
call eprintf ("Can't undo last change\007\n")
case 'r', 'E', 'P', 'R', 'Z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9':
if (EP_DISPLAY(ep) == YES) {
call ep_zoom (ep, xa, ya, xb, yb, key, erase)
newdisplay = YES
}
case 'Q': # Quit and no save
changes = 0
case 'I': # Immediate interrupt
call imdelete (EP_WORK(ep))
call fatal (1, "Interrupt")
default:
call printf ("\007")
}
} then
call erract (EA_WARN)
if (key == 'q' || key == 'Q')
break
if (change == YES && EP_AUTOSURFACE(ep) == YES)
call ep_dosurface (ep)
if (change == YES && EP_AUTODISPLAY(ep) == YES)
newdisplay = YES
if (newdisplay == YES && EP_DISPLAY(ep) == YES)
call ep_display (ep, EP_WORK(ep), erase)
# Log certain commands. Note that this is done after
# centering.
if (EP_LOGFD(ep) != NULL) {
switch (key) {
case 'a', 'c', 'd', 'f', 'j', 'l', 'v':
call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n")
call pargi (xa)
call pargi (ya)
call pargi (key)
call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n")
call pargi (xb)
call pargi (yb)
call pargi (key)
case 'b', 'e', 'k':
call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n")
call pargi ((xa+xb)/2)
call pargi ((ya+yb)/2)
call pargi (key)
case 'u':
if (EP_OUTDATA(ep) != NULL) {
call fprintf (EP_LOGFD(ep), "%c\n")
call pargi (key)
}
case 'm', 'n':
call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n")
call pargi ((xa+xb)/2)
call pargi ((ya+yb)/2)
call pargi (key)
call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n")
call pargi ((x1+x2)/2)
call pargi ((y1+y2)/2)
call pargi (key)
}
}
}
call imunmap (EP_IM(ep))
# Only create the output if the input has been changed.
if (changes > 0) {
if (streq (EP_INPUT(ep), EP_OUTPUT(ep))) {
EP_IM(ep) = immap (EP_OUTPUT(ep), READ_WRITE, 0)
im = immap (EP_WORK(ep), READ_ONLY, 0)
do i = 1, IM_LEN(EP_IM(ep),2)
call amovr (Memr[imgl2r(im,i)],
Memr[impl2r(EP_IM(ep),i)], IM_LEN(im,1))
call imunmap (im)
call imunmap (EP_IM(ep))
call imdelete (EP_WORK(ep))
} else {
if (imaccess (EP_OUTPUT(ep), READ_ONLY) == YES)
call imdelete (EP_OUTPUT(ep))
call imrename (EP_WORK(ep), EP_OUTPUT(ep))
}
} else
call imdelete (EP_WORK(ep))
# Check for a new image based on a colon command. This case
# always uses the input image name as output.
if (newimage == YES) {
call strcpy (EP_INPUT(ep), EP_OUTPUT(ep), EP_SZFNAME)
goto newim_
}
}
# Finish up.
if (EP_LOGFD(ep) != NULL)
call close (EP_LOGFD(ep))
call imtclose (inlist)
call imtclose (outlist)
call sfree (sp)
end
|