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
|
include <imhdr.h>
include <imset.h>
include <mach.h>
include "ccdcache.h"
.help ccdcache Jun87
.nf ---------------------------------------------------------------------
The purpose of the CCD image caching package is to minimize image mapping
time, to prevent multiple mapping of the same image, and to keep entire
calibration images in memory for extended periods to minimize disk
I/O. It is selected by specifying a maximum caching size based on the
available memory. When there is not enough memory for caching (or by
setting the size to 0) then standard IMIO is used. When there is
enough memory then as many images as will fit into the specified cache
size are kept in memory. Images are also kept mapped until explicitly
flushed or the entire package is closed.
This is a special purpose interface intended only for the CCDRED package.
It has the following restrictions.
1. Images must be processed to be cached.
2. Images must be 2 dimensional to be cached
3. Images must be real or short to be cached.
4. Images must be read_only to be cached.
5. Cached images remain in memory until they are displaced,
flushed, or the package is closed.
The package consists of the following procedures.
ccd_open ()
im = ccd_cache (image)
ptr = ccd_glr (im, col1, col2, line)
ptr = ccd_gls (im, col1, col2, line)
ccd_unmap (im)
ccd_flush (im)
ccd_close ()
CCD_OPEN: Initialize the image cache. Called at the beginning.
CCD_CLOSE: Flush the image cache and restore memory. Called at the end.
CCD_CACHE: Open an image and save the IMIO pointer. If the image has been
opened previously it need not be opened again. If image data caching
is specified the image data may be read it into memory. In order for
image data caching to occur the the image has to have been processed,
be two dimensional, be real or short, and the total cache memory not
be exceeded. If an error occurs in reading the image into memory
the data is not cached.
CCD_UNMAP: The image access number is decremented but the image
is not closed against the event it will be used again.
CCD_FLUSH: The image is closed and flushed from the cache.
CCD_GLR, CCD_GLS: Get a real or short image line. If the image data is cached
then a pointer to the line is quickly returned. If the data is not cached then
IMIO is used to get the pointer.
.endhelp ---------------------------------------------------------------------
# CCD_CACHE -- Open an image and possibly cache it in memory.
pointer procedure ccd_cache (image, ccdtype)
char image[ARB] # Image to be opened
int ccdtype # Image type
int i, nc, nl, nbytes
pointer sp, str, pcache, pcache1, im
int sizeof()
pointer immap(), imgs2r(), imgs2s()
bool streq(), ccdcheck()
errchk immap, imgs2r, imgs2s
include "ccdcache.com"
define done_ 99
begin
call smark (sp)
call salloc (str, SZ_LINE, TY_CHAR)
# Check if the image is cached.
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
im = CCD_IM(pcache)
call imstats (im, IM_IMAGENAME, Memc[str], SZ_LINE)
if (streq (image, Memc[str]))
break
}
# If the image is not cached open it and allocate memory.
if (i > ccd_ncache) {
im = immap (image, READ_ONLY, 0)
ccd_ncache = i
call realloc (ccd_pcache, ccd_ncache, TY_INT)
call malloc (pcache, CCD_LENCACHE, TY_STRUCT)
Memi[ccd_pcache+i-1] = pcache
CCD_IM(pcache) = im
CCD_NACCESS(pcache) = 0
CCD_SZDATA(pcache) = 0
CCD_DATA(pcache) = NULL
CCD_BUFR(pcache) = NULL
CCD_BUFS(pcache) = NULL
}
# If not caching the image data or if the image data has already
# been cached we are done.
if ((ccd_maxcache == 0) || (CCD_SZDATA(pcache) > 0))
goto done_
# Don't cache unprocessed calibration image data.
# This is the only really CCDRED specific code.
if (ccdcheck (im, ccdtype))
goto done_
# Check image is 2D and a supported pixel type.
if (IM_NDIM(im) != 2)
goto done_
if ((IM_PIXTYPE(im) != TY_REAL) && (IM_PIXTYPE(im) !=TY_SHORT))
goto done_
# Compute the size of the image data.
nc = IM_LEN(im,1)
nl = IM_LEN(im,2)
nbytes = nc * nl * sizeof (IM_PIXTYPE(im)) * SZB_CHAR
# Free memory not in use.
if (ccd_szcache + nbytes > ccd_maxcache) {
for (i=1; i<=ccd_ncache; i=i+1) {
pcache1 = Memi[ccd_pcache+i-1]
if (CCD_NACCESS(pcache1) == 0) {
if (CCD_SZDATA(pcache1) > 0) {
ccd_szcache = ccd_szcache - CCD_SZDATA(pcache1)
CCD_SZDATA(pcache1) = 0
CCD_DATA(pcache1) = NULL
call mfree (CCD_BUFR(pcache1), TY_REAL)
call mfree (CCD_BUFS(pcache1), TY_SHORT)
call imseti (CCD_IM(pcache1), IM_CANCEL, YES)
if (ccd_szcache + nbytes > ccd_maxcache)
break
}
}
}
}
if (ccd_szcache + nbytes > ccd_maxcache)
goto done_
# Cache the image data
iferr {
switch (IM_PIXTYPE (im)) {
case TY_SHORT:
CCD_DATA(pcache) = imgs2s (im, 1, nc, 1, nl)
case TY_REAL:
CCD_DATA(pcache) = imgs2r (im, 1, nc, 1, nl)
}
ccd_szcache = ccd_szcache + nbytes
CCD_SZDATA(pcache) = nbytes
} then {
call imunmap (im)
im = immap (image, READ_ONLY, 0)
CCD_IM(pcache) = im
CCD_SZDATA(pcache) = 0
}
done_
CCD_NACCESS(pcache) = CCD_NACCESS(pcache) + 1
call sfree (sp)
return (im)
end
# CCD_OPEN -- Initialize the CCD image cache.
procedure ccd_open (max_cache)
int max_cache # Maximum cache size in bytes
int max_size, begmem()
include "ccdcache.com"
begin
ccd_ncache = 0
ccd_maxcache = max_cache
ccd_szcache = 0
call malloc (ccd_pcache, 1, TY_INT)
# Ask for the maximum physical memory.
if (ccd_maxcache > 0) {
ccd_oldsize = begmem (0, ccd_oldsize, max_size)
call fixmem (max_size)
}
end
# CCD_UNMAP -- Unmap an image.
# Don't actually unmap the image since it may be opened again.
procedure ccd_unmap (im)
pointer im # IMIO pointer
int i
pointer pcache
include "ccdcache.com"
begin
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
if (CCD_IM(pcache) == im) {
CCD_NACCESS(pcache) = CCD_NACCESS(pcache) - 1
return
}
}
call imunmap (im)
end
# CCD_FLUSH -- Close image and flush from cache.
procedure ccd_flush (im)
pointer im # IMIO pointer
int i
pointer pcache
include "ccdcache.com"
begin
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
if (CCD_IM(pcache) == im) {
ccd_ncache = ccd_ncache - 1
ccd_szcache = ccd_szcache - CCD_SZDATA(pcache)
call mfree (CCD_BUFR(pcache), TY_REAL)
call mfree (CCD_BUFS(pcache), TY_SHORT)
call mfree (pcache, TY_STRUCT)
for (; i<=ccd_ncache; i=i+1)
Memi[ccd_pcache+i-1] = Memi[ccd_pcache+i]
break
}
}
call imunmap (im)
end
# CCD_CLOSE -- Close the image cache.
procedure ccd_close ()
int i
pointer pcache
include "ccdcache.com"
begin
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
call imunmap (CCD_IM(pcache))
call mfree (CCD_BUFR(pcache), TY_REAL)
call mfree (CCD_BUFS(pcache), TY_SHORT)
call mfree (pcache, TY_STRUCT)
}
call mfree (ccd_pcache, TY_INT)
# Restore memory.
call fixmem (ccd_oldsize)
end
# CCD_GLR -- Get a line of real data from the image.
# If the image data is cached this is fast (particularly if the datatype
# matches). If the image data is not cached then use IMIO.
pointer procedure ccd_glr (im, col1, col2, line)
pointer im # IMIO pointer
int col1, col2 # Columns
int line # Line
int i
pointer pcache, data, bufr, imgs2r()
errchk malloc
include "ccdcache.com"
begin
# Quick test for cached data.
if (ccd_maxcache == 0)
return (imgs2r (im, col1, col2, line, line))
# Return cached data.
if (IM_PIXTYPE(im) == TY_REAL) {
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
if (CCD_IM(pcache) == im) {
if (CCD_SZDATA(pcache) > 0)
return (CCD_DATA(pcache)+(line-1)*IM_LEN(im,1)+col1-1)
else
break
}
}
} else {
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
if (CCD_IM(pcache) == im) {
if (CCD_SZDATA(pcache) > 0) {
data = CCD_DATA(pcache)+(line-1)*IM_LEN(im,1)+col1-1
bufr = CCD_BUFR(pcache)
if (bufr == NULL) {
call malloc (bufr, IM_LEN(im,1), TY_REAL)
CCD_BUFR(pcache) = bufr
}
call achtsr (Mems[data], Memr[bufr], IM_LEN(im,1))
return (bufr)
} else
break
}
}
}
# Return uncached data.
return (imgs2r (im, col1, col2, line, line))
end
# CCD_GLS -- Get a line of short data from the image.
# If the image data is cached this is fast (particularly if the datatype
# matches). If the image data is not cached then use IMIO.
pointer procedure ccd_gls (im, col1, col2, line)
pointer im # IMIO pointer
int col1, col2 # Columns
int line # Line
int i
pointer pcache, data, bufs, imgs2s()
errchk malloc
include "ccdcache.com"
begin
# Quick test for cached data.
if (ccd_maxcache == 0)
return (imgs2s (im, col1, col2, line, line))
# Return cached data.
if (IM_PIXTYPE(im) == TY_SHORT) {
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
if (CCD_IM(pcache) == im) {
if (CCD_SZDATA(pcache) > 0)
return (CCD_DATA(pcache)+(line-1)*IM_LEN(im,1)+col1-1)
else
break
}
}
} else {
for (i=1; i<=ccd_ncache; i=i+1) {
pcache = Memi[ccd_pcache+i-1]
if (CCD_IM(pcache) == im) {
if (CCD_SZDATA(pcache) > 0) {
data = CCD_DATA(pcache)+(line-1)*IM_LEN(im,1)+col1-1
bufs = CCD_BUFS(pcache)
if (bufs == NULL) {
call malloc (bufs, IM_LEN(im,1), TY_SHORT)
CCD_BUFS(pcache) = bufs
}
call achtrs (Memr[data], Mems[bufs], IM_LEN(im,1))
return (bufs)
} else
break
}
}
}
# Return uncached data.
return (imgs2s (im, col1, col2, line, line))
end
|