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
382
383
|
Image Kernel Interface (IKI)
Doug Tody
08 May 1986
1. INTRODUCTION
The IKI is the interface between IMIO and some particular image storage
format. IMIO itself has no knowledge of the storage format. The primary
function of the IKI is to access image headers, mapping the host header
storage format into the IMIO image header descriptor and vice versa.
The IKI is responsible for all image management operations, including
opening/creating/updating headers, opening/creating pixfiles (pixel storage
files), deleting, renaming, and copying images, checking for the existence
of images, and so on.
The IKI can support an arbitrary number of different storage formats.
Each format requires a set of format dependent driver subroutines implementing
the standard IKI functions. The IKI will dynamically select the driver to be
used to access a particular format at runtime. New drivers may be dynamically
loaded at runtime, in a way similar to that used for FIO. While IMIO directly
accesses the pixel storage file via binary FIO for efficiency reasons, the
pixfile is opened by the IKI driver, hence a special driver may be used if
desired. For example, this feature may be used to access image display frame
as a pixfile, or an image stored in archival format on an optical disk.
2. STRUCTURE
The role played by the IKI and format specific IKI drivers in the image
i/o subsystem is illustrated in the figure below.
IMIO Format independent; primarily does i/o to
| the pixel file. The image header is read
| into a dynamically allocated descriptor at
| open time.
|
IKI Selects driver to be used. Maintains table
| of open images, handles cleanup during error
| recovery.
|
(drivers) Physically accesses/creates/deletes etc. an
image stored in a particular format. Maps
the header stored in some particular external
format into the standardized IMIO descriptor.
Responsible for opening/creating the pixfile,
returning a FIO file descriptor to IMIO, which
directly accesses the pixel data.
The format specific driver packages are written in SPP using only standard
VOS i/o facilities, e.g., FIO and MEMIO. This is necessary due to the use
of an SPP descriptor structure to maintain the incore version of the image
header, due to the need to return an FIO file descriptor to IMIO, and so on.
To add support for a new format, one need only add a new driver to the IKI
and relink the system.
3. LOGICAL SCHEMA
The logical schema of the current IKI is highly constrained by the fact
that the IKI is an add-on to the existing IMIO interface. It is not worthwhile
in this revision to try to address the limitations/design flaws of the initial
IMIO interface, hence our intention is to add the IKI in such a way that few
changes are required to IMIO, and no changes are required to programs which
use IMIO. One or two further major revisions are planned before the final
interface is realized. The concept of the IKI is here to stay, but the current
interface attempts only to address the immediate need to support multiple
image formats with the least impact on current software.
An image consists of a header and a pixel array stored in a random access
binary file. Images may be grouped together into an array or "cluster" of
images, with the individual images being accessed by a one indexed subscript
appended to the cluster name, e.g., "pix[3]" refers to image 3 of the cluster
"pix". To create a cluster containing more than one image a / followed by
the cluster size may be included in the cluster index, e.g., "pix[3/10]" to
create a cluster of 10 images and write into image 3. An image section may
optionally be appended to access some subset of the pixels in the image, e.g.,
"pix[3][*,5]". Lastly, if the image is stored as a disk file, the filename
extension of the header file may be given to explicitly indicate the image
format (IKI driver) to be used to access the image.
A full specification (referencing an existing image) might therefore be
"pix.hhh[3][*,5]", where the ".hhh" extension indicates that the cluster is
physically stored in an SDAS GEIS (group format) data structure, the "[3]"
indicates image 3, and the "[*,5]" is a conventional IMIO image section.
If the minimal specification "pix" were given, the IKI would determine that
"pix" was a GEIS format image, accessing the entire contents of image [1].
As an aside, note that image sections are handled entirely by IMIO and are
not seen at the IKI level. Likewise, the cluster subscript is parsed by
IMIO and passed to the IKI as an integer argument.
IM_PIXTYPE int pixel type (usilrdx)
IM_NDIM int number of axes (0:7)
IM_LEN long[7] logical length of each axis (>=1)
IM_PHYSLEN long[7] physical length of each axis (>=1)
IM_CLINDEX int index of image in cluster
IM_CLSIZE int number of images in cluster
IM_PIXOFF long char file offset to the pixels
IM_CTIME long image creation time
IM_MTIME long most recent image modification time
IM_LIMTIME long time when max/min last updated
IM_MAX real maximum pixel value
IM_MIN real minimum pixel value
IM_PIXFILE char*80 pathname of pixel file (optional)
IM_TITLE char*80 image title string
The important fields of the IMIO image descriptor are summarized above, along
with their datatype and length in the case of arrays. This is from the original
IMIO design and has not been modified in any way, except for the addition of the
cluster fields to the runtime descriptor. The IKI drivers directly read and
write these fields in the image descriptor.
In addition to these standard fields (for which the IKI driver must supply
reasonable values at open time) the image descriptor contains a "user area"
containing an arbitrary sequence of keyword=value parameters encoded in
FITS character format. The FITS cards are trimmed at the right and
concatenated into an EOS delimited string with newline characters delimiting
each card. All host format specific header parameters should be passed to
IMIO in the user area. In the case of group format images, the user area
will contain both the group parameters (parameters shared by the entire group
of images) and the group header parameters (parameters for the individual
image in the group specified at open time). IMIO makes no distinction
between the two types of parameters. All header parameters are available
to the high level applications code via the IMIO/IDBI interface.
4. IKI INTERFACE PROCEDURES
The IMIO code calls only the IKI procedures and has no knowledge of the
IKI drivers, or of which driver has been connected to a particular image
descriptor. The high level IKI procedures are summarized below. The interface
is fairly small due to the use of the descriptor to maintain all information
describing the image, and due to the fact that IMIO directly accesses the
pixel data via FIO.
iki_open (im, image, group, gcount, acmode, o_im)
iki_close (im)
iki_opix (im) # open/create pixfile
iki_updhdr (im) # update image header
iki_copy (oldname, newname) # fast copy of entire group
iki_delete (group) # delete entire group
iki_rename (oldname, newname) # rename entire group
k = iki_access (image, acmode) # test existence, legal extn
iki_lddriver (open,close, # install new driver
opix,updhdr, access,copy,delete,rename)
The OPEN procedure opens or creates the indicated image in the named cluster.
In the case of a new image or new copy image, only the header is created by
the open call; the pixfile is not created until the OPIX routine is called,
allowing the high level code time to set the image dimensions, datatype,
number of groups, etc., in the image descriptor. Once OPIX has been called
to create a new group, the number of axes, size of each axis, pixel type,
etc. is fixed.
In the case of image stored in the SDAS/GEIS group format, all of the images
in a cluster (group) must be of the same size, must have the same header
parameters, and the header parameters must be defined when the group is
created (new parameters or images cannot be added to the group later).
The first open call for a image will allocate space for all images in the
cluster, but only the indicated image will be initialized in the first call.
Multiple images may be simultaneously open in the same cluster, and the same
image may be multiply opened on independent logical FIO file descriptors.
The high level IRAF software has little or no knowledge of the physical
association of images into clusters. In particular, the high level software
is ignorant about the SDAS/GEIS image storage format, but this need not
prevent processing of these images. The main limitations of the group
format derive from the fact that new images can neither be added to nor
deleted from to a group format cluster, and new parameters cannot be added
to a group header. To create a group format image via IMIO, one will normally
make a NEW_COPY copy of an existing group format image (to define the fields
of the group headers), specifing the number of images in the new group in
the cluster size field of the image name specification. For example, writing
to the new image "pix[3/10]" will cause a cluster of 10 images to be created
and image 3 to be initialized. Subsequent calls to write to either "pix[I]"
or "pix[I/10]" will be necessary to initialize the remaining images in the
cluster.
5. KERNEL PROCEDURES
Each supported image format requires a dedicated set of kernel procedures
to be called by the IKI to access images stored in that format. The calling
sequences for these procedures are shown below.
xxx_open (im, root, extn, cl_index, cl_size, acmode, status)
xxx_close (im, status)
xxx_opix (im, status)
xxx_updhdr (im, status)
xxx_access (root, extn, acmode, status)
xxx_copy (old_root, old_extn, new_root, new_extn, status)
xxx_delete (root, extn, status)
xxx_rename (old_root, old_extn, new_root, new_extn, status)
Here, the package prefix "xxx" is OIF for the old IRAF image format, and STF
for the STScI/SDAS GEIS format. Note that the OPEN procedure fills in selected
fields in a preallocated image descriptor rather than allocating the descriptor
itself. Image names are parsed into root, extension, cl_index, etc. fields by
the IKI or higher level code, to further simplify the kernel code. The IKI
verifies the existence or nonexistence of all operand images before calling
a kernel procedure, hence the kernel procedures need not perform these
functions. The kernel procedures should return an ERR status if they cannot
perform their function for some reason (rather than take an error action).
The locpr() entry point addresses of the kernel procedures are saved in a
runtime table maintained by the IKI.
The syntax and semantics of the kernel procedures are discussed in detail below.
Since the interface routines have full access to the IMIO descriptors, it is
important to realize what does and does not have to be set.
5.1 IMAGE OPEN PRIMITIVE
include <imhdr.h>
include <imio.h>
include "xxx.h"
# XXX_OPEN -- Open/create an image.
procedure oif_open (im, root, extn, cl_index, cl_size, acmode, status)
pointer im # image descriptor (allocated by IMIO)
char root[ARB] # root image name
char extn[ARB] # extension, if any
int cl_index # index of image to be opened
int cl_size # number of images in cluster
int acmode # access mode
int status # return status (OK|ERR)
begin
1. Construct the filename of the header file and open or create the
image header file.
2. If opening an existing image, read the image header and fill in
the following fields of the IMIO image header descriptor. If
creating a new image set only the field IM_HDRFILE.
IM_PIXTYPE # datatype of the pixels **
IM_NDIM # number of dimensions **
IM_LEN # length of the dimensions **
IM_CTIME # time of image creation
IM_MTIME # time of last modify
IM_LIMTIME # time min,max computed
IM_MAX # max pixel value
IM_MIN # min pixel value
IM_PIXFILE # name of pixel storage file
IM_HDRFILE # name of header storage file
IM_TITLE # image name string
IM_HISTORY # history comment string
The really essential fields are marked with a ** at the right.
CTIME, PIXFILE, HDRFILE, TITLE, and HISTORY are for information
only. MTIME and LIMTIME are used to determine if the min/max
pixel values are up to date, and the actual values do not matter
provided the conclusion about the min/max values is correct.
3. If opening an existing image, call IMIO to set those fields of the
image header/descriptor describing the format in which the pixels
are stored in the pixel storage file.
[] call imioff (im, pixoff, COMPRESS, blklen)
where
pixoff FIO file offset of first pixel.
compress Set to NO to enable alignment of image
lines on block boundaries, to YES for
compressed byte stream image.
blklen Device block size, chars. Set to 1 to
defeat all block alignment.
If opening a new image, this step may be left until the OPIX
primitive is called.
3. If the kernel procedures use their own internal descriptor,
allocate and initialize the descriptor and save a pointer to
it in IM_KDES(im).
4. Set return status.
end
5.2 OPEN PIXEL FILE PRIMITIVE
include <imhdr.h>
include <imio.h>
include "xxx.h"
# XXX_OPIX -- Open (or create) the pixel storage file. Call IMIO to set the
# file offsets and buffer sizes.
procedure xxx_opix (im, status)
pointer im # image descriptor
int status # return status
begin
1. Opening existing image:
1.1 Open pixel file read only or read write.
2. Opening (creating) new image:
2.1 Call IMIO to set the offset parameters, assuming this was not
already done in the OPEN primitive:
[] call imioff (im, pixoff, COMPRESS, blklen)
2.2 Using the file size computed by imioff or determined by more
format specific means, open (falloc) the pixel storage file.
The IM_HGMOFF field of the image header is set by imioff
to the file offset of the end of the image.
3. Call IMIO to set the i/o buffer parameters:
[] call imsetbuf (pfd, im)
This sets the FIO buffer size and the IM_FAST parameter.
The buffer size should be set before doing any i/o on the
pixel file. If in doubt, skip the call and simply set
IM_FAST(im) = NO (i/o will be suboptimal but not too bad).
4. Save the pixfile FIO file descriptor (required for pixel i/o)
in the image descriptor:
[] IM_PFD(im) = pfd
end
5.3 UPDATE HEADER PRIMITIVE
include <imhdr.h>
include <imio.h>
# XXX_UPDHDR -- Update the image header.
procedure xxx_updhdr (im, status)
pointer im # image descriptor
int status # return status
begin
1. Update the values of the standard logical image header fields
in the physical image header, e.g., PIXTYPE, NDIM, LEN, and CTIME
(for new images), MTIME, LIMTIME, MIN, MAX (any image).
2. Save the "user fields" in the physical image header. Some of
these may have been inserted in the user area by the kernel open
procedure, others may have been added by IRAF programs or by
the user since the image was opened.
end
5.4 CLOSE IMAGE PRIMITIVE
include <imio.h>
# XXX_CLOSE -- Close an image.
procedure xxx_close (im, status)
pointer im # image descriptor
int status
begin
1. If the pixel file has been opened, close it. Note that if no
pixel i/o was done to the image, the pixel file will never have
been opened.
2. If the header file is still open, close it.
3. If a special kernel descriptor was allocated at image open time
by the kernel, deallocate it.
end
|