aboutsummaryrefslogtreecommitdiff
path: root/sys/imfort/doc
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /sys/imfort/doc
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'sys/imfort/doc')
-rw-r--r--sys/imfort/doc/TODO3
-rw-r--r--sys/imfort/doc/bfaloc.hlp32
-rw-r--r--sys/imfort/doc/bfbsiz.hlp22
-rw-r--r--sys/imfort/doc/bfchan.hlp27
-rw-r--r--sys/imfort/doc/bfclos.hlp27
-rw-r--r--sys/imfort/doc/bfflsh.hlp26
-rw-r--r--sys/imfort/doc/bffsiz.hlp24
-rw-r--r--sys/imfort/doc/bfopen.hlp32
-rw-r--r--sys/imfort/doc/bfread.hlp31
-rw-r--r--sys/imfort/doc/bfwrit.hlp38
-rw-r--r--sys/imfort/doc/clarg.hlp42
-rw-r--r--sys/imfort/doc/clnarg.hlp24
-rw-r--r--sys/imfort/doc/clrawc.hlp35
-rw-r--r--sys/imfort/doc/imacck.hlp27
-rw-r--r--sys/imfort/doc/imaddk.hlp55
-rw-r--r--sys/imfort/doc/imakw.hlp50
-rw-r--r--sys/imfort/doc/imclos.hlp39
-rw-r--r--sys/imfort/doc/imcrea.hlp55
-rw-r--r--sys/imfort/doc/imdele.hlp29
-rw-r--r--sys/imfort/doc/imdelk.hlp36
-rw-r--r--sys/imfort/doc/imemsg.hlp31
-rw-r--r--sys/imfort/doc/imflsh.hlp39
-rw-r--r--sys/imfort/doc/imfort.hd44
-rw-r--r--sys/imfort/doc/imfort.ms1711
-rw-r--r--sys/imfort/doc/imfort.toc54
-rw-r--r--sys/imfort/doc/imgkw.hlp41
-rw-r--r--sys/imfort/doc/imgl.hlp48
-rw-r--r--sys/imfort/doc/imgs.hlp54
-rw-r--r--sys/imfort/doc/imgsiz.hlp51
-rw-r--r--sys/imfort/doc/imhcpy.hlp30
-rw-r--r--sys/imfort/doc/imokwl.hlp65
-rw-r--r--sys/imfort/doc/imopen.hlp35
-rw-r--r--sys/imfort/doc/imopnc.hlp49
-rw-r--r--sys/imfort/doc/impixf.hlp53
-rw-r--r--sys/imfort/doc/impkw.hlp51
-rw-r--r--sys/imfort/doc/impl.hlp49
-rw-r--r--sys/imfort/doc/imps.hlp54
-rw-r--r--sys/imfort/doc/imrnam.hlp35
-rw-r--r--sys/imfort/doc/imtypk.hlp33
39 files changed, 3181 insertions, 0 deletions
diff --git a/sys/imfort/doc/TODO b/sys/imfort/doc/TODO
new file mode 100644
index 00000000..662fc249
--- /dev/null
+++ b/sys/imfort/doc/TODO
@@ -0,0 +1,3 @@
+IMFORT docs updates needed:
+
+ o Add description of IM[SG]DIR, 'imdir' semantics. (6/1/89)
diff --git a/sys/imfort/doc/bfaloc.hlp b/sys/imfort/doc/bfaloc.hlp
new file mode 100644
index 00000000..470042bc
--- /dev/null
+++ b/sys/imfort/doc/bfaloc.hlp
@@ -0,0 +1,32 @@
+.help bfaloc Sep86 imfort.bfio
+.ih
+NAME
+bfaloc -- create and preallocate storage for a binary file
+.ih
+SYNOPSIS
+.nf
+subroutine bfaloc (fname, nchars, status)
+
+character*(*) fname #I host name of new file
+integer nchars #I size of file in "chars"
+integer status #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIbfaloc\fR procedure creates a new file \fIfname\fR and preallocates
+space for at least \fInchars\fR SPP char units of storage. The contents of
+the file are unitialized.
+.ih
+RETURN VALUE
+A negative status value indicates either that the file could not be created
+(e.g., due to insufficient permission), or that the requested amount of space
+could not be allocated. A positive or zero status indicates that the operation
+succeeded.
+.ih
+NOTES
+On some systems, storage may not physically be allocated until the file is
+written into.
+.ih
+SEE ALSO
+bfopen
+.endhelp
diff --git a/sys/imfort/doc/bfbsiz.hlp b/sys/imfort/doc/bfbsiz.hlp
new file mode 100644
index 00000000..aeea7912
--- /dev/null
+++ b/sys/imfort/doc/bfbsiz.hlp
@@ -0,0 +1,22 @@
+.help bfbsiz Sep86 imfort.bfio
+.ih
+NAME
+bfbsiz -- get the buffer size in chars of a binary file
+.ih
+SYNOPSIS
+.nf
+integer function bfbsiz (fd)
+
+integer fd #I BFIO file descriptor of open file
+.fi
+.ih
+DESCRIPTION
+The \fIbfbsiz\fR function is used to query the size in SPP char units of
+storage of the internal BFIO file buffer.
+.ih
+RETURN VALUE
+The size of the BFIO file buffer in chars is returned as the function value.
+.ih
+SEE ALSO
+bffsiz, bfchan
+.endhelp
diff --git a/sys/imfort/doc/bfchan.hlp b/sys/imfort/doc/bfchan.hlp
new file mode 100644
index 00000000..9641b971
--- /dev/null
+++ b/sys/imfort/doc/bfchan.hlp
@@ -0,0 +1,27 @@
+.help bfchan Sep86 imfort.bfio
+.ih
+NAME
+bfchan -- return the kernel i/o channel of an open BFIO file
+.ih
+SYNOPSIS
+.nf
+integer function bfchan (fd)
+
+integer fd #I BFIO file descriptor of open file
+.fi
+.ih
+DESCRIPTION
+The \fIbfchan\fR procedure is used to get the i/o channel assigned to the
+file at open time by the binary file driver in the IRAF kernel.
+This may be used as input to the \fIzfiobf\fR binary file driver primitives
+if the lowest possible level of binary file i/o is desired (short of talking
+directly to the host system). The \fIzfiobf\fR procedures provide a direct
+(unbuffered), block oriented, asynchronous binary file i/o interface.
+.ih
+RETURN VALUE
+The i/o channel assigned to the file by the \fIzfiobf\fR binary file driver
+at open time is returned as the function value.
+.ih
+SEE ALSO
+The manual pages for the binary file driver.
+.endhelp
diff --git a/sys/imfort/doc/bfclos.hlp b/sys/imfort/doc/bfclos.hlp
new file mode 100644
index 00000000..83b8e856
--- /dev/null
+++ b/sys/imfort/doc/bfclos.hlp
@@ -0,0 +1,27 @@
+.help bfclos Sep86 imfort.bfio
+.ih
+NAME
+bfclos -- close a file opened for binary file i/o
+.ih
+SYNOPSIS
+.nf
+subroutine bfclos (fd, status)
+
+integer fd #I BFIO file descriptor of open file
+integer status #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIbfclos\fR procedure closes a file previously opened with \fIbfopen\fR,
+freeing the file descriptor and any other system resources associated with the
+file descriptor. The output buffer is automatically flushed before the file
+is closed.
+.ih
+RETURN VALUE
+A negative status indicates failure, e.g., either a write error occurred
+when the output buffer was flushed, or the file descriptor \fIfd\fR was
+invalid.
+.ih
+SEE ALSO
+bfopen
+.endhelp
diff --git a/sys/imfort/doc/bfflsh.hlp b/sys/imfort/doc/bfflsh.hlp
new file mode 100644
index 00000000..3dc676a0
--- /dev/null
+++ b/sys/imfort/doc/bfflsh.hlp
@@ -0,0 +1,26 @@
+.help bfflsh Sep86 imfort.bfio
+.ih
+NAME
+bfflsh -- flush any buffered output data to disk
+.ih
+SYNOPSIS
+.nf
+integer function bfflsh (fd)
+
+integer fd #I BFIO file descriptor of open file
+.fi
+.ih
+DESCRIPTION
+The \fIbfflsh\fR procedure flushes any buffered output data to a binary
+file opened for read-write access.
+.ih
+RETURN VALUE
+A negative status indicates failure, e.g., a write error on the file.
+.ih
+NOTES
+If the buffer has already been flushed or the file was opened for read-only
+access, \fIbfflsh\fR is a no-op.
+.ih
+SEE ALSO
+bfwrit
+.endhelp
diff --git a/sys/imfort/doc/bffsiz.hlp b/sys/imfort/doc/bffsiz.hlp
new file mode 100644
index 00000000..4385b270
--- /dev/null
+++ b/sys/imfort/doc/bffsiz.hlp
@@ -0,0 +1,24 @@
+.help bffsiz Sep86 imfort.bfio
+.ih
+NAME
+bffsiz -- get the size in chars of a binary file
+.ih
+SYNOPSIS
+.nf
+integer function bffsiz (fd)
+
+integer fd #I BFIO file descriptor of open file
+.fi
+.ih
+DESCRIPTION
+The \fIbffsiz\fR function is used to query the size in SPP char units of
+storage of a binary file previously opened with \fIbfopen\fR. This is useful,
+for example, when writing at the end of file, since the BFIO write function
+requires an absolute file offset as input.
+.ih
+RETURN VALUE
+The current size of the file in chars is returned as the function value.
+.ih
+SEE ALSO
+bfbsiz, bfchan
+.endhelp
diff --git a/sys/imfort/doc/bfopen.hlp b/sys/imfort/doc/bfopen.hlp
new file mode 100644
index 00000000..a345d4fa
--- /dev/null
+++ b/sys/imfort/doc/bfopen.hlp
@@ -0,0 +1,32 @@
+.help bfopen Sep86 imfort.bfio
+.ih
+NAME
+bfopen -- open a file for binary file i/o
+.ih
+SYNOPSIS
+.nf
+integer function bfopen (fname, acmode, advice)
+
+character*(*) fname #I host name of file to be opened
+integer acmode #I file access mode (1=RO,3=RW,5=NF)
+integer advice #I type of access (1=random,2=seq.)
+.fi
+.ih
+DESCRIPTION
+The \fIbfopen\fR procedure either opens an existing file for binary
+file i/o (\fIacmode\fR 1=read-only or 3=read-write), or creates a new,
+zero length file and opens it for binary file i/o with read-write
+access mode (\fIacmode\fR 5=new-file). The \fIadvice\fR parameter
+controls the size of the internal file buffer allocated at open time.
+The possible values are 1 (random access, small buffer), or 2 (sequential
+access, large buffer); anything larger is taken to be the actual size
+of the buffer. Note that the size of the buffer must be an integral
+multiple of the size of a disk block.
+.ih
+RETURN VALUE
+The BFIO file descriptor (\fIfd\fR) is returned as the function value if
+the file is successfully opened, otherwise a negative value is returned.
+.ih
+SEE ALSO
+bfaloc, bfclos
+.endhelp
diff --git a/sys/imfort/doc/bfread.hlp b/sys/imfort/doc/bfread.hlp
new file mode 100644
index 00000000..2345dfa3
--- /dev/null
+++ b/sys/imfort/doc/bfread.hlp
@@ -0,0 +1,31 @@
+.help bfread Sep86 imfort.bfio
+.ih
+NAME
+bfread -- read from a binary file at the specified offset
+.ih
+SYNOPSIS
+.nf
+integer function bfread (fd, buf, nchars, offset)
+
+integer fd #I BFIO file descriptor of open file
+typeless buf(*) #O buffer to receive file data
+integer nchars #I number of SPP chars to read
+integer offset #I 1-indexed char offset into file
+.fi
+.ih
+DESCRIPTION
+The \fIbfread\fR procedure reads \fInchars\fR char units of storage from
+the file opened on file descriptor \fIfd\fR starting at the one-indexed
+char file offset \fIoffset\fR. Any number of chars may be read starting
+at any char file offset.
+.ih
+RETURN VALUE
+The actual number of char units of storage read is returned as the function
+value; a read at end of file results in zero chars being read. A negative
+function value indicates that the read failed for some reason, e.g., the
+file descriptor was invalid, the file offset was out of range, or an actual
+physical read error occurred.
+.ih
+SEE ALSO
+bfwrit
+.endhelp
diff --git a/sys/imfort/doc/bfwrit.hlp b/sys/imfort/doc/bfwrit.hlp
new file mode 100644
index 00000000..510ad92f
--- /dev/null
+++ b/sys/imfort/doc/bfwrit.hlp
@@ -0,0 +1,38 @@
+.help bfwrit Sep86 imfort.bfio
+.ih
+NAME
+bfwrit -- write to a binary file at the specified offset
+.ih
+SYNOPSIS
+.nf
+integer function bfwrit (fd, buf, nchars, offset)
+
+integer fd #I BFIO file descriptor of open file
+typeless buf(*) #I buffer containing file data
+integer nchars #I number of SPP chars to be written
+integer offset #I 1-indexed char offset into file
+
+.fi
+.ih
+DESCRIPTION
+The \fIbfwrit\fR procedure writes \fInchars\fR char units of storage from
+the user supplied buffer to the file opened on file descriptor \fIfd\fR
+starting at the one-indexed char file offset \fIoffset\fR. Any number of
+chars may be written starting at any char file offset.
+.ih
+RETURN VALUE
+The actual number of char units of storage written is returned as the function
+value; it is probably an error if this is not equal to \fInchars\fR.
+A negative function value indicates that the write failed for some reason,
+e.g., the file descriptor was invalid, the file offset was out of range,
+or an actual physical write error occurred.
+.ih
+NOTES
+The entire contents of the internal BFIO file buffer are always written,
+even when writing at the end of file, hence it is not possible to write
+odd-sized files with the BFIO interface (partial blocks can however be
+read with \fIbfread\fR).
+.ih
+SEE ALSO
+bfread
+.endhelp
diff --git a/sys/imfort/doc/clarg.hlp b/sys/imfort/doc/clarg.hlp
new file mode 100644
index 00000000..c924ebc7
--- /dev/null
+++ b/sys/imfort/doc/clarg.hlp
@@ -0,0 +1,42 @@
+.help clarg Sep86 imfort
+.ih
+NAME
+clarg -- fetch and decode the value of a command line argument
+.ih
+SYNOPSIS
+.nf
+subroutine clargc (argno, cval, ier)
+subroutine clargi (argno, ival, ier)
+subroutine clargr (argno, rval, ier)
+subroutine clargd (argno, dval, ier)
+
+integer argno #I index of argument to be decoded
+integer ier #O status return
+
+character*(*) cval #O string value of argument
+integer ival #O integer value of argument
+real rval #O real value of argument
+doubleprecision dval #O double value of argument
+.fi
+.ih
+DESCRIPTION
+The four \fIclarg\fR procedures are used to fetch and decode the value of
+the indexed command line argument; the first argument is number one.
+Any argument may be returned as a string with \fIclargc\fR.
+Numeric arguments are decoded using the IRAF formatted i/o primitives,
+hence octal constants (`B' suffix), hex constants (`X' suffix),
+and sexagesimal numbers are all legal as input.
+.ih
+RETURN VALUE
+A status of zero indicates that the indexed argument was present on the
+command line and could be decoded in the manner specified.
+
+.nf
+IE_GCMDLN: cannot read command line string
+IE_NEXARG: nonexistent command line argument referenced
+IE_NONNUMARG: command line argument cannot be decoded as a number
+.fi
+.ih
+SEE ALSO
+clnarg, clrawc
+.endhelp
diff --git a/sys/imfort/doc/clnarg.hlp b/sys/imfort/doc/clnarg.hlp
new file mode 100644
index 00000000..c7321931
--- /dev/null
+++ b/sys/imfort/doc/clnarg.hlp
@@ -0,0 +1,24 @@
+.help clnarg Sep86 imfort
+.ih
+NAME
+clnarg -- get the number of arguments on the command line
+.ih
+SYNOPSIS
+.nf
+subroutine clnarg (nargs)
+
+integer nargs #O the number of arguments
+.fi
+.ih
+DESCRIPTION
+The \fIclnarg\fR subroutine returns the number of whitespace delimited
+(or quoted) arguments given on the command line when the calling program
+was invoked.
+.ih
+RETURN VALUE
+The number of arguments, or zero if there were no arguments or if the
+command line cannot be accessed for some reason (there is no error return).
+.ih
+SEE ALSO
+clarg, clrawc
+.endhelp
diff --git a/sys/imfort/doc/clrawc.hlp b/sys/imfort/doc/clrawc.hlp
new file mode 100644
index 00000000..09b2891d
--- /dev/null
+++ b/sys/imfort/doc/clrawc.hlp
@@ -0,0 +1,35 @@
+.help clrawc Sep86 imfort
+.ih
+NAME
+clrawc -- return the raw command line as a string
+.ih
+SYNOPSIS
+.nf
+subroutine clrawc (outstr, ier)
+
+character*(*) outstr #O receives the command line string
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIclrawc\fR procedure returns the raw command line as a string,
+i.e., all the argument strings are concatenated together with spaces
+between successive arguments.
+.ih
+RETURN VALUE
+A status of zero indicates that the task was called with a nonnull command
+string. An error status indicates that the program was called without any
+arguments.
+
+IE_GCMDLN: cannot read command line string
+.ih
+NOTES
+Normally it is preferable to use the \fIclarg\fR procedures to decode
+and return the values of the individual arguments. Note that decoding
+the argument list with a list-directed read against \fIoutstr\fR is in
+violation of the Fortran 77 standard, and probably would not work anyhow,
+since the string arguments are not quoted.
+.ih
+SEE ALSO
+clnarg, clarg
+.endhelp
diff --git a/sys/imfort/doc/imacck.hlp b/sys/imfort/doc/imacck.hlp
new file mode 100644
index 00000000..75e922c9
--- /dev/null
+++ b/sys/imfort/doc/imacck.hlp
@@ -0,0 +1,27 @@
+.help imacck Sep86 imfort
+.ih
+NAME
+imacck -- determine if the named header keyword exists
+.ih
+SYNOPSIS
+.nf
+subroutine imacck (im, keyw, ier)
+
+integer im #I image descriptor of open image
+character*(*) keyw #I name of keyword to be accessed
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimacck\fR procedure is used to test if the named header keyword
+can be accessed, i.e., if it exists.
+.ih
+RETURN VALUE
+A zero status return indicates that the header does indeed have such a
+keyword.
+
+IE_NEXKW: nonexistent header keyword referenced
+.ih
+SEE ALSO
+imtypek, imaddk, imokwl
+.endhelp
diff --git a/sys/imfort/doc/imaddk.hlp b/sys/imfort/doc/imaddk.hlp
new file mode 100644
index 00000000..e796d168
--- /dev/null
+++ b/sys/imfort/doc/imaddk.hlp
@@ -0,0 +1,55 @@
+.help imaddk Sep86 imfort
+.ih
+NAME
+imaddk -- add a new keyword to an image header
+.ih
+SYNOPSIS
+.nf
+subroutine imaddk (im, keyw, dtype, comm, ier)
+
+integer im #I image descriptor of open image
+character*(*) keyw #I name of the new keyword
+integer dtype #I keyword datatype code
+character*(*) comm #I comment string describing keyword
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimaddk\fR procedure is used to add a new keyword to the header of
+an existing, open image. The datatype of the new keyword must be specified
+at creation time; the possible datatype codes for header keywords are given
+in the following table.
+
+.nf
+ 1 boolean (logical)
+ 2 character string
+ 3,4,5 short integer, don't-care integer, long integer
+ 6,7 real or double precision floating
+.fi
+
+A comment string may optionally be given to describ the keyword, i.e.,
+its function or purpose. The comment string is printed in image header
+listings and is propagated onto FITS tapes.
+.ih
+RETURN VALUE
+A zero status is returned if there is space for the new keyword, and the
+keyword does not redefine an existing keyword.
+
+.nf
+SYS_IDBREDEF: attempt to redefine an image header keyword
+SYS_IDBOVFL: out of space in image header
+.fi
+.ih
+NOTES
+The precision of a keyword name is currently limited to eight characters
+(longer keyword names will be silently truncated), and all user defined
+keyword names are rendered into upper case. This is necessary to permit
+use of the FITS image format to transport images.
+An alternative to the relatively low level \fIimaddk\fR procedure is provided
+by the \fIimakw\fR procedures, which will not add a new keyword if the named
+keyword already exists, which also set the value of the new keyword, and which
+avoid the need to use a datatype code.
+.ih
+SEE ALSO
+imdelk, imacck, imakw
+.endhelp
diff --git a/sys/imfort/doc/imakw.hlp b/sys/imfort/doc/imakw.hlp
new file mode 100644
index 00000000..cd447806
--- /dev/null
+++ b/sys/imfort/doc/imakw.hlp
@@ -0,0 +1,50 @@
+.help imakw Sep86 imfort
+.ih
+NAME
+imakw -- add or set the value of an image header keyword
+.ih
+SYNOPSIS
+.nf
+subroutine imakwb (im, keyw, bval, comm, ier)
+subroutine imakwc (im, keyw, cval, comm, ier)
+subroutine imakwi (im, keyw, ival, comm, ier)
+subroutine imakwr (im, keyw, rval, comm, ier)
+subroutine imakwd (im, keyw, dval, comm, ier)
+
+integer im #I image descriptor of open image
+character*(*) keyw #I name of the keyword to be set
+character*(*) comm #I comment string describing keyword
+integer ier #O status return
+
+logical bval #I logical (boolean) keyword value
+character*(*) cval #I character string keyword value
+integer ival #I integer keyword value
+real rval #I real keyword value
+doubleprecision dval #I double precision keyword value
+.fi
+.ih
+DESCRIPTION
+The \fIimakw\fR procedures are used to set the values of image header keywords.
+If the named keyword does not already exist, a new keyword of the indicated
+datatype is first added and then the value of the new keyword is set,
+otherwise the value of the existing keyword is updated.
+The comment string is used only if a new keyword is created.
+Automatic datatype conversion is provided when updating the value of
+an existing keyword, i.e., if the keyword already exists there is some
+flexibility in the choice of the datatype of the \fIimakw\fR procedure
+to be used.
+.ih
+RETURN VALUE
+A zero status is returned if the named keyword exists, is writable, and if
+the datatype coercion implied is permissible, or if the named keyword is
+not found but can be added.
+
+.nf
+SYS_IDBOVFL: out of space in image header
+SYS_IDBREDEF: attempt to redefine an image header keyword
+SYS_IDBTYPE: illegal header parameter data type conversion
+.fi
+.ih
+SEE ALSO
+imaddk, imacck, impkw, imgkw
+.endhelp
diff --git a/sys/imfort/doc/imclos.hlp b/sys/imfort/doc/imclos.hlp
new file mode 100644
index 00000000..c771a961
--- /dev/null
+++ b/sys/imfort/doc/imclos.hlp
@@ -0,0 +1,39 @@
+.help imclos Sep86 imfort
+.ih
+NAME
+imclos -- close an image
+.ih
+SYNOPSIS
+.nf
+subroutine imclos (im, ier)
+
+integer im #I image descriptor of open image
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+An image opened with \fIimopen\fR or \fIimopnc\fR should be closed with
+\fIimclos\fR when the image operation is complete. The close operation
+flushes any buffered output pixel data, updates the header if necessary,
+closes the header and pixel files, and frees any system resources
+associated with the image descriptor.
+.ih
+RETURN VALUE
+A zero status is returned if the image descriptor is valid and the header
+and pixel files could be updated and closed without any errors.
+
+.nf
+IE_CLSHDR: error closing image header file
+IE_CLSPIX: error closing image pixel file
+IE_UPDHDR: error updating image header file
+IE_UPDRO: image header modified but image was opened read only
+.fi
+.ih
+NOTES
+If an image is erroneously opened read-only by a program which updates the
+image header, no error condition will occur until the image is closed,
+hence the \fIimclos\fR status return should always be checked.
+.ih
+SEE ALSO
+imopen, imopnc
+.endhelp
diff --git a/sys/imfort/doc/imcrea.hlp b/sys/imfort/doc/imcrea.hlp
new file mode 100644
index 00000000..9b7381f7
--- /dev/null
+++ b/sys/imfort/doc/imcrea.hlp
@@ -0,0 +1,55 @@
+.help imcrea Nov86 imfort
+.ih
+NAME
+imcrea -- create a new image
+.ih
+SYNOPSIS
+.nf
+subroutine imcrea (image, axlen, naxis, dtype, ier)
+
+character*(*) image #I host name of the new image
+integer axlen(7) #I length of each axis
+integer naxis #I number of axes
+integer dtype #I pixel datatype
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimcrea\fR procedure is used to create a new image from scratch,
+using only the information passed via the command line arguments.
+The image name \fIimname\fR is the host system filename of the new image,
+although the extension (".imh") may be omitted if desired. The dimensionality
+of the new image is given by \fInaxis\fR, and the length in pixels of each
+axis is given by the first few elements of the array \fIaxlen\fR.
+In the current implementation of IMFORT the dimensionality of an image
+should not exceed three. There are no restrictions on the size of an image.
+
+The datatype to be used to store the pixels in the new image is given by
+the integer code \fIdtype\fR. Only two pixel datatypes are currently
+supported, i.e., \fIdtype\fR=3 for short integer pixels, and \fIdtype\fR=6
+for type real pixels.
+
+Both the image header file and the pixel file are created, and storage is
+allocated for the pixel array in the pixel file. A subsequent call to
+\fIimopen\fR is required to access the new image. The size, dimensionality,
+and datatype of the new image cannot be changed once the image has been
+created.
+.ih
+RETURN VALUE
+A nonzero error code is returned if either the header file or the pixel
+file cannot be created for some reason, or if any of the input arguments
+are invalid.
+
+.nf
+IE_NAXIS: wrong number of axes on image
+IE_AXLEN: length of each image axis must be .ge. 1
+IE_PIXTYPE: image pixel type must be short or real
+IE_CREHDR: cannot create image
+IE_WRHDR: error writing to image header file
+IE_ALCPIX: cannot create or allocate space for pixel file
+IE_ACCPIX: error writing into pixel file during image create
+.fi
+.ih
+SEE ALSO
+imopen, imopnc, imdele, imrnam
+.endhelp
diff --git a/sys/imfort/doc/imdele.hlp b/sys/imfort/doc/imdele.hlp
new file mode 100644
index 00000000..b80e5692
--- /dev/null
+++ b/sys/imfort/doc/imdele.hlp
@@ -0,0 +1,29 @@
+.help imdele Sep86 imfort
+.ih
+NAME
+imdele -- delete an image
+.ih
+SYNOPSIS
+.nf
+subroutine imdele (image, ier)
+
+character*(*) image #I host name of image to be deleted
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimdele\fR procedure deletes an image, i.e., the both the header file
+and the pixel file (if any).
+.ih
+RETURN VALUE
+A zero status is returned if the image exists and was successfully deleted.
+It is not an error if there is no pixel file.
+
+.nf
+IE_IMDELNEXIM: attempt to delete a nonexistent image
+IE_IMDELETE: cannot delete image
+.fi
+.ih
+SEE ALSO
+imrnam, imcrea
+.endhelp
diff --git a/sys/imfort/doc/imdelk.hlp b/sys/imfort/doc/imdelk.hlp
new file mode 100644
index 00000000..d654447e
--- /dev/null
+++ b/sys/imfort/doc/imdelk.hlp
@@ -0,0 +1,36 @@
+.help imdelk Sep86 imfort
+.ih
+NAME
+imdelk -- delete a header keyword
+.ih
+SYNOPSIS
+.nf
+subroutine imdelk (im, keyw, ier)
+
+integer im #I image descriptor of open image
+character*(*) keyw #I name of keyword to be deleted
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimdelk\fR procedure is used to delete a user defined image header
+keyword, e.g., a keyword previously created with \fIimaddk\fR or with one
+of the \fIimakw\fR procedures.
+.ih
+RETURN VALUE
+A zero status is returned if the named keyword existed, was a user defined
+keyword (rather an a protected system keyword), and was successfully deleted.
+
+.nf
+SYS_IDBNODEL: cannot delete image header keyword
+SYS_IDBDELNXKW: attempt to delete a nonexistent image header keyword
+.fi
+.ih
+NOTES
+It is not an error to delete a keyword from the header of an image opened for
+read-only access, but an error status will be returned at \fIimclos\fR or
+\fIimflsh\fR time since the header cannot be updated on disk.
+.ih
+SEE ALSO
+imaddk, imakw, imacck
+.endhelp
diff --git a/sys/imfort/doc/imemsg.hlp b/sys/imfort/doc/imemsg.hlp
new file mode 100644
index 00000000..32b1677c
--- /dev/null
+++ b/sys/imfort/doc/imemsg.hlp
@@ -0,0 +1,31 @@
+.help imemsg Sep86 imfort
+.ih
+NAME
+imemsg -- convert an IMFORT error code into an error message
+.ih
+SYNOPSIS
+.nf
+subroutine imemsg (ier, errmsg)
+
+integer ier #I an IMFORT error code
+character*(*) errmsg #O the corresponding error message
+.fi
+.ih
+DESCRIPTION
+The \fIimemsg\fR procedure converts a positive integer error code,
+such as is returned by the IMFORT procedures in the event of an error,
+into the corresponding error message string. In cases where the error
+was associated with a named object, e.g., a file or image, the operand
+name will be enclosed in parenthesis and appended to the base error
+message string returned to the user.
+.ih
+RETURN VALUE
+The error message string, or "imfort error (unrecognized error code)" if
+called with an unknown error code.
+.ih
+SEE ALSO
+.nf
+The individual manual pages for the symbolic names of the error codes
+imfort$imfort.h and lib$syserr.h for the integer error codes.
+.fi
+.endhelp
diff --git a/sys/imfort/doc/imflsh.hlp b/sys/imfort/doc/imflsh.hlp
new file mode 100644
index 00000000..d1d184f3
--- /dev/null
+++ b/sys/imfort/doc/imflsh.hlp
@@ -0,0 +1,39 @@
+.help imflsh Sep86 imfort
+.ih
+NAME
+imflsh -- flush any buffered image data to disk
+.ih
+SYNOPSIS
+.nf
+subroutine imflsh (im, ier)
+
+integer im #I image descriptor of open image
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimflsh\fR procedure flushes any buffered image data to disk. Both the
+image header and pixel file are updated if either has been modified since
+the image was opened, or since the last call to \fIimflsh\fR. All buffered
+image data is automatically flushed when an image is closed with \fIimclos\fR.
+Explicit calls to \fIimflsh\fR are rarely needed since synchronization occurs
+automatically when the image is closed, but may be desirable in applications
+where the image will be open for a substantial period of time, increasing the
+possibility of a program abort or interrupt before the image is closed.
+Calling \fIimflsh\fR on an image opened for read-only access is harmless.
+.ih
+RETURN VALUE
+A zero status is returned if no image data has been modified and an update
+is not necessary, or if either the header or pixel data has been modified and
+the update was successful. The most likely cause of an update failure is lack
+of write permission on the image.
+
+.nf
+IE_FLUSH: error flushing buffered data to pixel file
+IE_UPDHDR: error updating image header file
+IE_UPDRO: image header modified but image was opened read only
+.fi
+.ih
+SEE ALSO
+imclos
+.endhelp
diff --git a/sys/imfort/doc/imfort.hd b/sys/imfort/doc/imfort.hd
new file mode 100644
index 00000000..c37b96cd
--- /dev/null
+++ b/sys/imfort/doc/imfort.hd
@@ -0,0 +1,44 @@
+# Helpdir for the IMFORT package.
+
+zawset hlp = doc$zawset.hlp, src = os$zawset.c
+
+$imfort = "sys$imfort/"
+$doc = "sys$imfort/doc/"
+
+bfaloc hlp = doc$bfaloc.hlp, src = imfort$bfaloc.x
+bfbsiz hlp = doc$bfbsiz.hlp, src = imfort$bfbsiz.x
+bfchan hlp = doc$bfchan.hlp, src = imfort$bfchan.x
+bfclos hlp = doc$bfclos.hlp, src = imfort$bfclos.x
+bfflsh hlp = doc$bfflsh.hlp, src = imfort$bfflsh.x
+bffsiz hlp = doc$bffsiz.hlp, src = imfort$bffsiz.x
+bfopen hlp = doc$bfopen.hlp, src = imfort$bfopen.x
+bfread hlp = doc$bfread.hlp, src = imfort$bfread.x
+bfwrit hlp = doc$bfwrit.hlp, src = imfort$bfwrit.x
+clarg hlp = doc$clarg.hlp, src = imfort$clarg.x
+clnarg hlp = doc$clnarg.hlp, src = imfort$clnarg.x
+clrawc hlp = doc$clrawc.hlp, src = imfort$clrawc.x
+imacck hlp = doc$imacck.hlp, src = imfort$imacck.x
+imaddk hlp = doc$imaddk.hlp, src = imfort$imaddk.x
+imakw hlp = doc$imakw.hlp, src = imfort$imakw.x
+imclos hlp = doc$imclos.hlp, src = imfort$imclos.x
+imcrea hlp = doc$imcrea.hlp, src = imfort$imcrea.x
+imdele hlp = doc$imdele.hlp, src = imfort$imdele.x
+imdelk hlp = doc$imdelk.hlp, src = imfort$imdelk.x
+imemsg hlp = doc$imemsg.hlp, src = imfort$imemsg.x
+imflsh hlp = doc$imflsh.hlp, src = imfort$imflsh.x
+imgkw hlp = doc$imgkw.hlp, src = imfort$imgkw.x
+imgl hlp = doc$imgl.hlp, src = imfort$imgl.x
+imgs hlp = doc$imgs.hlp, src = imfort$imgs.x
+imgsiz hlp = doc$imgsiz.hlp, src = imfort$imgsiz.x
+imhcpy hlp = doc$imhcpy.hlp, src = imfort$imhcpy.x
+imokwl hlp = doc$imokwl.hlp, src = imfort$imokwl.x
+imgnkw hlp = doc$imokwl.hlp, src = imfort$imokwl.x
+imckwl hlp = doc$imokwl.hlp, src = imfort$imokwl.x
+imopen hlp = doc$imopen.hlp, src = imfort$imopen.x
+imopnc hlp = doc$imopnc.hlp, src = imfort$imopnc.x
+impixf hlp = doc$impixf.hlp, src = imfort$impixf.x
+impkw hlp = doc$impkw.hlp, src = imfort$impkw.x
+impl hlp = doc$impl.hlp, src = imfort$impl.x
+imps hlp = doc$imps.hlp, src = imfort$imps.x
+imrnam hlp = doc$imrnam.hlp, src = imfort$imrnam.x
+imtypk hlp = doc$imtypk.hlp, src = imfort$imtypk.x
diff --git a/sys/imfort/doc/imfort.ms b/sys/imfort/doc/imfort.ms
new file mode 100644
index 00000000..cc0c1919
--- /dev/null
+++ b/sys/imfort/doc/imfort.ms
@@ -0,0 +1,1711 @@
+.RP
+.TL
+A User's Guide to Fortran Programming in IRAF
+.br
+The IMFORT Interface
+.AU
+Doug Tody
+.AI
+.K2 "" "" "*"
+September 1986
+
+.AB
+The IMFORT interface is a Fortran programming environment suitable for general
+Fortran programming, with special emphasis on batch image processing.
+IMFORT is intended for use primarily by the scientist/user who occasionally
+needs to write a program for their own personal use, but who does not program
+often enough to make it worthwhile learning a larger, more complex but fully
+featured programming environment. IMFORT is therefore a small interface which
+is easy to learn and use, and which relies heavily upon host system (non-IRAF)
+facilities which the user is assumed to already be familiar with.
+Facilities are provided for accessing command line arguments, reading and
+writing IRAF images, and returning output to the CL. Provisions are made
+for editing, compiling, linking, and debugging programs without need to leave
+the IRAF environment, making use of familiar host system editing and debugging
+tools wherever possible.
+.AE
+
+.NH
+Introduction
+.PP
+The IMFORT interface is a library of Fortran callable subroutines which can
+be called from a host system Fortran program to perform such operations as
+fetching the arguments given on the command line when the task was invoked,
+or accessing the header or pixel information in an IRAF image (bulk data frame).
+Since the result is a host program rather than an IRAF program, only limited
+access to the facilities provided by the runtime IRAF system is possible,
+but on the other hand one has full access to the facilities provided by the
+host system. Programs which use IMFORT may be run as ordinary host system
+programs outside of IRAF, or may be interfaced to the IRAF command language
+(CL) as CL callable tasks. Within the IRAF environment these user written,
+non-IRAF tasks behave much like ordinary IRAF tasks, allowing background
+execution, use of i/o redirection and pipes, evaluation of expressions on
+the command line, programmed execution in scripts, and so on.
+
+.NH 2
+Who Should Use IMFORT
+.PP
+The most significant feature of the IMFORT interface is that it is designed
+for use by \fIhost\fR Fortran programs. The scientist/user will often already
+be using such programs when IRAF becomes available. IMFORT allows these
+pre-existing programs to be modified to work within the IRAF environment
+with a minimum of effort and with minimum changes to the existing program.
+The only alternative is to rework these programs as \fIIRAF\fR programs,
+but few existing Fortran programs could (or should) survive such a transition
+without being completely rewritten. If the program in question is useful
+enough such a rewrite might be warranted, but in most cases this will not
+be practical, hence something like the IMFORT interface is clearly needed
+to keep these old programs alive until they are no longer needed.
+.PP
+The second goal of the IMFORT interface is to provide a way for the user to
+add their own programs to IRAF without having to invest a lot of time learning
+the full blown IRAF programming environment. IMFORT makes it possible for
+the user to begin writing useful programs within hours of their first exposure
+to the system. It is possible that the IMFORT interface will provide all the
+capability that some users will ever need, especially when supplemented by other
+(non-IRAF) Fortran callable libraries available on the local host machine.
+Programs developed in this way are bound to have portability and other
+problems, but it should be up to the developer and user of the software to
+decide whether these problems are worth worrying about. IMFORT is simply
+a \fItool\fR, to be used as one sees fit; there is no attempt to dictate to
+the user how they should write their programs.
+.PP
+The alternative to IMFORT, if applications programming within IRAF is the goal,
+is the IRAF SPP/VOS programming environment. The SPP/VOS programming
+environment is a fully featured scientific programming environment which
+carefully addresses all the software engineering issues avoided by IMFORT.
+The VOS is a large and complex environment and therefore takes longer to learn
+than IMFORT, but it provides all the facilities needed by large applications
+hence is \fIeasier\fR to use than simpler interfaces like IMFORT, if one is
+faced with the already difficult task of coding a large program or package.
+Furthermore, the SPP/VOS environment fully addresses the problems of
+portability and device independence, critical issues for applications which
+must be supported and used simultaneously on a range of machines over a
+period of years, during which time the software is likely to be continually
+evolving. An overview of the SPP/VOS programming environment is given in
+\fIThe IRAF Data Reduction and Analysis System\fR, February 1986, by the author.
+.PP
+In summary, IMFORT is intended for use to interface old Fortran programs to
+IRAF with a minimum of effort, and as an entry level programming environment
+which new users can learn to use in a few hours. Experienced users,
+professional programmers, and developers of large applications will find that
+they can accomplish more with less effort once they have learned to use the
+more fully featured SPP/VOS programming environment.
+
+.bp
+.NH
+Getting Started
+.PP
+Although programs which use IMFORT can and often will be invoked from the
+host system command interpreter, it is likely that such programs will also
+be used interactively in combination with the tasks provided by the standard
+IRAF system. For example, the IRAF graphics and image display facilities
+are likely to be used to examine the results of an image operation performed
+by a user written Fortran/IMFORT program. Indeed, the standard IRAF tasks
+are likely to be used for testing new IMFORT programs as well as reducing data
+with old ones, so we shall assume that software development will take place
+from within the IRAF environment. Since IRAF provides full access to the
+facilities of the host system at all times, there is little reason not to
+work from within the IRAF environment.
+.PP
+As a first step, let's see what is required to enter, compile, link, and
+execute a small Fortran program which does nothing more than print the
+message \fLhello, world!\fR on the terminal. We shall assume that the
+reader has read the \fICL User's Guide\fR and is already familiar with
+basic CL command entry, the OS escape facility, the editor interface and so on.
+The first step is to call up the editor to enter the program into a file:
+.DS
+\fLcl> edit hello.f\fR
+.DE
+Note that the filename extension is ".f", which is what IRAF uses for
+Fortran files. The extension will be mapped into the local host system
+equivalent when IRAF communicates with the host system, but when working
+in the IRAF environment the IRAF name should be used.
+.LP
+Once in the editor, enter the following program text:
+.DS
+\fLprogram hello
+write (*,*) 'hello, world!'
+stop
+end\fR
+.DE
+The next step is to compile and link the \fLhello\fR program. This is done
+by the command \fIfc\fR (\fIf\fRortran-\fIc\fRompile), which produces an
+object file \fLhello.o\fR and an executable program file \fLhello.e\fR.
+Note that the \fIfc\fR task is defined in the default \fIuser\fR package in
+your \fLLOGIN.CL\fR file, hence a \fImkiraf\fR may be required to regenerate
+the \fLLOGIN.CL\fR file if the file is old or has been modified.
+.DS
+\fLcl> fc hello.f\fR
+.DE
+Since the \fLhello\fR program is a host Fortran program, it can be executed
+immediately with an OS escape, e.g., \fL!hello.e\fR on UNIX, or
+\fL!run hello\fR on VMS. A better approach if the task has command line
+arguments is to use the IRAF \fIforeign task\fR facility to define the
+program as a new IRAF task, as we shall see in the next section.
+
+.NH 2
+Example 1: Plotting a function
+.PP
+As a slightly more complicated example, let's construct a program to compute
+and plot a function using command line arguments to input the function
+parameters, with output consisting of a simple ASCII table sampling the
+computed function. Our example computes the Planck function, which gives the
+emissivity of a blackbody as a function of wavelength and temperature.
+The sample program is shown in Figure 1. Source code for this and all other
+examples in this paper may be found in the IRAF directory \fLimfort$tasks\fR.
+
+.DS
+\fL
+.ps 8
+.vs 9p
+c PLANCK -- Compute the Planck blackbody radiation distribution for a
+c given temperature and wavelength region.
+c
+c usage: planck temperature lambda1 lambda2
+c
+c The temperature is specified in degrees Kelvin and the wavelength
+c region in microns (1u=10000A). 100 [x,y] data points defining the
+c curve are output.
+c ----------------------------------------------------------------------
+
+ program planck
+
+ character*80 errmsg
+ integer nargs, ier, i
+ real w1, w2, dw, cm, t
+ real xv(100), yv(100)
+
+c --- Get the temperature in degrees kelvin.
+ call clargr (1, t, ier)
+ if (ier .ne. 0) then
+ write (*, '('' temperature (degrees kelvin): '',$)')
+ read (*,*) t
+ endif
+
+c --- Get the wavelength region to be computed.
+ call clnarg (nargs)
+ if (nargs .ge. 3) then
+ call clargr (2, w1, ier)
+ if (ier .ne. 0) goto 91
+ call clargr (3, w2, ier)
+ if (ier .ne. 0) goto 91
+ else
+ write (*, '('' start wavelength (microns): '',$)')
+ read (*,*) w1
+ write (*, '('' end wavelength (microns): '',$)')
+ read (*,*) w2
+ endif
+
+c --- Compute the blackbody curve.
+ dw = (w2 - w1) / 99.0
+ do 10 i = 1, 100
+ xv(i) = ((i-1) * dw) + w1
+ cm = xv(i) * 1.0E-4
+ yv(i) = (3.74185E-5 * (cm ** -5)) /
+ * (2.71828 ** (1.43883 / (cm * t)) - 1.0)
+ 10 continue
+
+c --- Print the curve as a table.
+ do 20 i = 1, 100
+ write (*, '(f7.4, g12.4)') xv(i), yv(i)
+ 20 continue
+
+ stop
+
+c --- Error exit.
+ 91 call imemsg (ier, errmsg)
+ write (*, '('' Error: '', a80)') errmsg
+ stop
+ end\fR
+.DE
+.vs
+.ps
+.sp
+.ce
+Figure 1. Sample program to compute the Planck function\(dd
+.FS
+\(ddThe trailing \fL$\fR carriage control code used in the format strings in
+the \fLWRITE\fR statements in this and the other sample Fortran programs
+is nonstandard Fortran and may not be available on all host machines.
+Its function is to defeat the carriage-return linefeed so that the user's
+response may be entered on the same line as the prompt.
+.FE
+
+.PP
+This example serves to demonstrate the use of the IMFORT \fIclarg\fR procedures
+to fetch the command line arguments, and the use of i/o redirection to capture
+the output to generate the plot. The command line to an IMFORT program consists
+of a sequence of arguments delimited by spaces or tabs. The subroutine
+\fIclnarg\fR returns the number of arguments present on the command line when
+the task was called. The \fIclargr\fR, \fIclargi\fR, etc. procedures fetch
+and decode the values of the individual arguments. Virtually all IMFORT
+procedures include an integer output variable \fIier\fR in their argument list;
+a zero status indicates success, anything else indicates failure and the actual
+error code identifies the cause of the problem. The \fIimemsg\fR procedure
+may be called to convert IMFORT error codes into error message strings, as in
+the example.
+.PP
+Once the program has been entered and compiled and linked with \fIfc\fR,
+we must declare the program as a foreign task to the CL. If this is not
+done the program can still be run via an OS escape, but none of the advanced
+CL features will be available, e.g., background execution, command line
+expression evaluation, i/o redirection, and so on. The technique used to
+declare a foreign task is machine dependent since it depends upon the syntax
+of the host command interpreter. For example, to declare the new CL foreign
+task \fIplanck\fR on a UNIX system, we enter the following command:
+.DS
+\fLcl> task $planck = $planck.e\fR
+.DE
+The same thing can be achieved on a VMS system with the following
+declaration (it can be simplified by moving the VMS foreign task declaration
+to your \fLLOGIN.COM\fR file):
+.DS
+\fLcl> task $planck = "$planck:==\\\\$\fIdisk\fP:[\fIdir\fP...]planck.exe!planck"\fR
+.DE
+The \fL$\fR characters are required to tell the CL that the new task does
+not have a parameter file, and is a foreign task rather than a regular
+IRAF task. The \fL!\fR in the VMS example is used to delimit multiple DCL
+commands; the command shown defines the DCL foreign task \fIplanck\fR and
+then executes it. The use of the \fItask\fR statement to declare foreign
+tasks is discussed in detail in \(sc3.3.
+.PP
+We have written the program in such a way that the arguments will be queried
+for if not given on the command line, so if we enter only the name of the
+command, an interaction such as the following will occur:
+.DS
+\fLcl> planck
+temperature (degrees kelvin): 3000
+start wavelength (microns): .1
+end wavelength (microns): 4\fR
+.DE
+Note that if the output of the \fIplanck\fR task is redirected this input
+mechanism will \fInot\fR work, since the queries will be redirected along
+with the output. Hence if we use a pipe to capture the output, as in the
+following example, the arguments must be given on the command line.
+.DS
+\fLcl> planck 3000 0.1 4.0 | graph
+.DE
+This command will compute and plot the emissivity for a 3000 degree kelvin
+blackbody from 0.1 to 4.0 microns (1000 to 40000 angstroms).
+.PP
+An interesting alternative way to implement the above program would be to
+output the function curve as a line in an image, rather than as a table of
+numbers. For example, a two dimensional image could be generated wherein
+each line corresponds to a different temperature. \fIGraph\fR or \fIimplot\fR
+could then be used to plot curves or overplot families of curves; this would
+be more efficient than the technique employed in our sample program.
+Image access via IMFORT is illustrated in our next example.
+
+.NH 2
+Example 2: Compute the range of pixel values in an image
+.PP
+The program shown in Figure 2 opens the named image, examines each line in
+the image to determine the minimum and maximum pixel values, keeping a running
+tally until the entire image has been examined (there is no provision for
+detecting and ignoring bad pixels in the image). The newly computed minimum
+and maximum pixel values are then updated in the image header as well as
+printed on the standard output.
+.DS
+\fL
+.ps 8
+.vs 9p
+c MINMAX -- Compute the minimum and maximum pixel values in an image.
+c The new values are printed as well as updated in the image header.
+c
+c usage: minmax image
+c ----------------------------------------------------------------------
+
+ program minmax
+
+ character*80 image, errmsg
+ real pix(4096), dmin, dmax, vmin, vmax
+ integer im, axlen(7), naxis, dtype, ier, j
+
+c --- Get image name.
+ call clargc (1, image, ier)
+ if (ier .ne. 0) then
+ write (*, '('' enter image name: '',$)')
+ read (*,*) image
+ endif
+
+c --- Open the image for readwrite access (we need to update the header).
+ call imopen (image, 3, im, ier)
+ if (ier .ne. 0) goto 91
+ call imgsiz (im, axlen, naxis, dtype, ier)
+ if (ier .ne. 0) goto 91
+
+c --- Read through the image and compute the limiting pixel values.
+ do 10 j = 1, axlen(2)
+ call imgl2r (im, pix, j, ier)
+ if (ier .ne. 0) goto 91
+ call alimr (pix, axlen(1), vmin, vmax)
+ if (j .eq. 1) then
+ dmin = vmin
+ dmax = vmax
+ else
+ dmin = min (dmin, vmin)
+ dmax = max (dmax, vmax)
+ endif
+ 10 continue
+
+c --- Update the image header.
+ call impkwr (im, 'datamin', dmin, ier)
+ if (ier .ne. 0) goto 91
+ call impkwr (im, 'datamax', dmax, ier)
+ if (ier .ne. 0) goto 91
+
+c --- Clean up.
+ call imclos (im, ier)
+ if (ier .ne. 0) goto 91
+ write (*, '(a20, 2 g12.5)') image, dmin, dmax
+ stop
+
+c --- Error exit.
+ 91 call imemsg (ier, errmsg)
+ write (*, '('' Error: '', a80)') errmsg
+ stop
+ end\fR
+.DE
+.vs
+.ps
+.sp
+.ce
+Figure 2. Compute the min and max pixel values in an image
+
+.PP
+The program as written can only deal with images of one or two dimensions,
+of pixel type short (16 bit integer) or real (32 bit floating), with a line
+length not to exceed 4096 pixels per line. We could easily change the program
+to deal with images of up to three dimensions, but the IMFORT interface does
+not provide dynamic memory allocation facilities so there is always going
+to be an upper limit on the line length if we use the simple get line i/o
+procedure \fIimgl2r\fR, as shown. The use of fixed size buffers simplifies
+the program, however, and is not expected to be a serious problem in most
+IMFORT applications.
+.PP
+The \fIalimr\fR subroutine in the previous example is from the IRAF VOPS
+(vector operators) package. The function of \fIalimr\fR is to compute
+the limiting (min and max) pixel values in a vector of type real, the
+function type being indicated by the \fIlim\fR, and the pixel datatype by
+the \fIr\fR. The VOPS package provides many other such vector operators,
+and is discussed further in \(sc 4.4.
+
+.NH 2
+Example 3: Copy an image
+.PP
+Our final example (Figure 3) shows how to create a new image as a copy of
+some existing image. This can be used as a template to create any binary
+image operator, i.e., any program which computes some transformation upon
+an existing image, writing a new image as output.
+.PP
+By now the functioning of this procedure should be self evident.
+The only thing here which is at all subtle is the subroutine \fIimopnc\fR,
+used to open (create) a new copy of an existing image. The open new copy
+operation creates a new image the same size and datatype as the old
+image, and copies the image header of the old image to the new image.
+Any user keywords in the header of the old image will be automatically
+passed to the new image, without requiring that the calling program
+have explicit knowledge of the contents of the image header.
+.PP
+Note that the program is written to work only on pixels of type real,
+hence will be inefficient if used to copy images of type short-integer.
+A more efficient approach for a general image copy operator would be
+to add a conditional test on the variable \fLdtype\fR, executing a
+different copy-loop for each datatype, to avoid having to convert from
+integer to real and back again when copying a short-integer image.
+The short-integer equivalents of \fIimgl3r\fR (get line, 3 dim image,
+type real) and \fIimpl3r\fR (put line, 3 dim image, type real) are
+called \fIimgl3s\fR and \fIimpl3s\fR.
+.PP
+The program as written will work for images of up to three dimensions,
+even though it is written to deal with only the three dimensional case.
+This works because the length of the "unused" axes in an image is
+set to one when the image is created. A program passed an image of
+higher dimension than it is written for will also work, but will not
+process all of the data. IMFORT does not support image sections,
+so only the first few lines of the image will be accessible to such
+a program.
+
+.PP
+Additional useful examples of Fortran programs using IMFORT are given in
+\fLimfort$tasks\fR. These include utility programs to make test images,
+print the contents of an image header, print the values of the pixels in
+a subraster, and so on. You may wish to copy the source for these to your
+own workspace for use as is, or for use as templates to construct similar
+programs.
+
+.DS
+\fL
+.ps 8
+.vs 9p
+c IMCOPY -- Copy an image. Works for images of up to three dimensions
+c with a pixel type of short or real and up to 4096 pixels per line.
+c
+c usage: imcopy oldimage newimage
+c ---------------------------------------------------------------------
+
+ program imcopy
+
+ real pix(4096)
+ character*80 oimage, nimage, errmsg
+ integer ncols, nlines, nbands, j, k, oim, nim
+ integer ier, axlen(7), naxis, dtype, nargs
+
+c --- Get command line arguments.
+ call clnarg (nargs)
+ if (nargs .eq. 2) then
+ call clargc (1, oimage, ier)
+ if (ier .ne. 0) goto 91
+ call clargc (2, nimage, ier)
+ if (ier .ne. 0) goto 91
+ else
+ write (*, '('' input image: '',$)')
+ read (*,*) oimage
+ write (*, '('' output image: '',$)')
+ read (*,*) nimage
+ endif
+
+c --- Open the input image and create a new-copy output image.
+ call imopen (oimage, 1, oim, ier)
+ if (ier .ne. 0) goto 91
+ call imopnc (nimage, oim, nim, ier)
+ if (ier .ne. 0) goto 91
+
+c --- Determine the size and pixel type of the image being copied.
+ call imgsiz (oim, axlen, naxis, dtype, ier)
+ if (ier .ne. 0) goto 91
+
+ ncols = axlen(1)
+ nlines = axlen(2)
+ nbands = axlen(3)
+
+c --- Copy the image.
+ do 15 k = 1, nbands
+ do 10 j = 1, nlines
+ call imgl3r (oim, pix, j, k, ier)
+ if (ier .ne. 0) goto 91
+ call impl3r (nim, pix, j, k, ier)
+ if (ier .ne. 0) goto 91
+ 10 continue
+ 15 continue
+
+c --- Clean up.
+ call imclos (oim, ier)
+ if (ier .ne. 0) goto 91
+ call imclos (nim, ier)
+ if (ier .ne. 0) goto 91
+
+ stop
+
+c --- Error actions.
+ 91 call imemsg (ier, errmsg)
+ write (*, '('' Error: '', a80)') errmsg
+ stop
+ end\fR
+.DE
+.vs
+.ps
+.sp
+.ce
+Figure 3. Image copy program
+
+.bp
+.NH
+The IMFORT Programming Environment
+.PP
+IRAF provides a small programming environment for the development of host
+Fortran programs using the IMFORT interface. This environment consists
+of the general CL tools, e.g., the editor, the \fIpage\fR and \fIlprint\fR
+tasks, etc., plus a few special tools, namely, the \fIfc\fR compile/link
+utility and the foreign task facility. In this section we discuss these
+special tools and facilities. Information is also provided for linking
+to the IMFORT libraries if program development is to take place at the host
+system level.
+.PP
+The classic third generation program development cycle (ignoring such minor
+details as designing the software) is edit \(em compile/link \(em debug.
+The edit phase uses the CL \fIedit\fR task, an interface to the host system
+editor of choice. The compile/link phase is performed by the \fIfc\fR utility.
+The debug phase is optional and is generally only necessary for large programs.
+The host system debug tool is used; while IRAF does not provide a special
+interface to the host debug tool, one can easily be constructed using the
+foreign task facility if desired.
+.PP
+Programs which use the IMFORT interface are inevitably host system dependent
+to some degree, since they are host programs. In the interests of providing
+the user with concrete examples, the discussion in this section must therefore
+delve into the specifics of certain host operating systems. We have chosen
+to use UNIX and VMS in the examples, since most IRAF implementations run on
+one or the other of these operating systems. The ties between the IMFORT
+programming environment and the host system are quite simple, however, so it
+should not be difficult to see how to modify the examples for a different host.
+
+.NH 2
+The FC Compile/Link Utility
+.PP
+The \fIfc\fR utility provides a consistent, machine independent interface to
+the host system compiler and linker which is convenient and easy to use.
+In addition, \fIfc\fR provides a means for linking host programs with the
+IRAF libraries without having to type a lot, and without having to build
+host command scripts. All of the IRAF libraries are accessible via \fIfc\fR,
+not just IMFORT (\fLlib$libimfort.a\fR) and the IRAF system libraries used
+by IMFORT, but all the other IRAF libraries as well, e.g., the math libraries.
+.PP
+The default action of \fIfc\fR is to compile and link the files listed on the
+command line, i.e., source files in various languages, object modules, and
+libraries. Any source files are first turned into object modules, then the
+objects are linked in the order given, searching any libraries in the order
+in which they are encountered on the command line (the IMFORT libraries are
+searched automatically, after any libraries listed on the command line).
+By default, the root name of the new executable will be the same as that of
+the first file listed on the command line; a different name may be assigned
+with the \fI-o\fR switch if desired.
+.LP
+The syntax of the \fIfc\fR command is as follows:
+.DS
+\fLfc [\fIswitches\fP] \fIfile\fL [\fIfile ...\fL] [-o \fIexefile\fL]\fR
+.DE
+The most interesting switches are as follows:
+.in 0.5i
+.IP \fB-c\fR
+Compile but do not link.
+.IP \fB-l\fIlibrary\fR
+.br
+Link to the named IRAF library. On a UNIX host this switch may also be
+used to reference the UNIX libraries. The \fI-llibrary\fR reference
+should be given in the file list at the point at which you want the
+library to be searched. The \fI-l\fR causes \fIfc\fR to look in a set
+of standard places for the named library; user libraries should be
+referenced directly by the filename of the library.
+.IP \fB-o\fR\ \fIexefile\fR
+.br
+Override the default name for the executable file produced by the linker.
+.IP \fB-x\fR
+Compile and link for debugging.
+.in
+
+.LP
+Since the \fIfc\fR command line can contain many different types of objects,
+a filename extension is required to identify the object type. The IRAF
+filename extensions \fImust\fR be used; these are listed in the table below.
+
+.TS
+box center;
+cb s
+ci | ci
+c | l.
+IRAF Filename Extensions
+_
+extn usage
+=
+\.a object library
+\.c C source file
+\.e executable
+\.f Fortran source file
+\.o object module
+\.s Assembler source file
+\.x SPP source file
+.TE
+
+.PP
+The \fIfc\fR utility is easy to learn and use. Here are a few examples
+illustrating the most common usage of the utility. To compile and link the
+Fortran program \fLprog.f\fR, producing the executable program \fLprog.e\fR:
+.DS
+\fLcl> fc prog.f\fR
+.DE
+To compile the file \fLutil.f\fR to produce the object \fLutil.o\fR,
+without linking anything:
+.DS
+\fLcl> fc -c util.f\fR
+.DE
+To link \fLprog.o\fR and \fLutil.o\fR, producing the executable program
+\fLprog.e\fR:
+.DS
+\fLcl> fc prog.o util.o\fR
+.DE
+To do the same thing, producing an executable named \fLfoo.e\fR instead
+of \fLprog.e\fR:
+.DS
+\fLcl> fc prog.o util.o -o foo.e\fR
+.DE
+To compile and link \fLprog.f\fR for debugging:
+.DS
+\fLcl> fc -x prog.f\fR
+.DE
+To link \fLprog.o\fR with the IRAF library \fLlib$libdeboor.a\fR (the DeBoor
+spline package), producing the executable \fLprog.e\fR as output:
+.DS
+\fLcl> fc prog.o -ldeboor\fR
+.DE
+To do the same thing, spooling the output in the file \fLspool\fR and
+running the whole thing in the background:
+.DS
+\fLcl> fc prog.o -ldeboor >& spool &\fR
+.DE
+To link instead with the library \fLlibfoo.a\fR, in the current directory
+(note that in this case the library is a module and not a switch):
+.DS
+\fLcl> fc prog.o libfoo.a\fR
+.DE
+.LP
+Just about any combination of switches and modules that makes sense will
+work. The order of libraries in the argument list is important, as they
+will be searched in the order in which they are listed on the command line.
+.PP
+The \fIfc\fR utility is actually just a front-end to the standard IRAF
+compiler \fIxc\fR, as we shall see in \(sc3.3. See the manual page for
+\fIxc\fR for additional information.
+
+.NH 2
+Host Level Linking to the IMFORT Libraries
+.PP
+In some cases it may be desirable to use host system facilities to compile
+and link programs which use the IMFORT interface. The procedure for doing
+this is host dependent and is completely up to the user, who no doubt will
+already have a preferred technique worked out. All one needs to know in
+this situation are the names of the libraries to be linked, and the order
+in which they are to be linked. The libraries are as follows, using the
+IRAF filenames for the libraries. All the libraries listed are referenced
+internally by the IMFORT code hence are required.
+
+.TS
+center;
+l l.
+lib$libimfort.a IMFORT itself
+lib$libsys.a Contains certain pure code modules used by IMFORT
+lib$libvops.a The VOPS vector operators library
+hlib$libos.a The IRAF kernel (i/o primitives)
+.TE
+.LP
+The host pathnames of these libraries will probably be evident, given the
+host pathname of the IRAF root directory (\fIlib\fR is a subdirectory of
+the IRAF root directory). If in doubt, the \fIosfn\fR intrinsic function may
+be used while in the CL to print the host pathname of the desired library.
+For example,
+.DS
+\fLcl> = osfn ("lib$libimfort.a")\fR
+.DE
+will cause the CL to print the host pathname of the main IMFORT library.
+
+.NH 2
+Calling Host Programs from the CL
+.PP
+Since Fortran programs which use IMFORT are host programs rather than IRAF
+programs, the CL \fIforeign task\fR interface is used to connect the programs
+to the CL as CL callable tasks. The foreign task interface may also be used
+to provide custom CL task interfaces to other host system utilities, e.g.,
+the debugger or the librarian.
+.PP
+The function of the \fItask\fR statement in the CL is to make a new task
+known to the CL. The CL must know the name of the new task, the name of
+the package to which it is to be added, whether or not the new task has a
+parameter file, the type of task being defined, and the name of the file in
+which the task resides. At present new tasks are always added to the
+"current" package. The possible types of tasks are normal IRAF executable
+tasks, CL script tasks, and foreign tasks. Our interest here is only in the
+forms of the task statement used to declare foreign tasks. There are two
+such forms at present. The simplest is the following:
+.DS
+\fLtask $\fItaskname\fR [, \fL$\fItaskname\fR...]\fL = $foreign\fR
+.DE
+This form is used when the command to be sent to the host system to run
+the task is identical to the name by which the task is known to the CL.
+Note that any number of new tasks may be declared at one time with this
+form of the task statement. The \fL$\fR prefixing each \fItaskname\fR
+tells the CL that the task does not have a parameter file. The \fL$foreign\fR
+tells the CL that the new tasks are foreign tasks and that the host command
+is the same as \fItaskname\fR. For example, most systems have a system
+utility \fImail\fR which is used to read or send electronic mail.
+To declare the \fImail\fR task as an IRAF foreign task, we could enter
+the following declaration, and then just call the \fImail\fR task from
+within the CL like any other IRAF task.
+.DS
+\fLtask $mail = $foreign\fR
+.DE
+The more general form of the foreign task statement is shown below.
+The host command string must be quoted if it contains blanks or any other
+special characters; \fL$\fR is a reserved character and must be escaped
+to be included in the command sent to the host system.
+.DS
+\fLtask $\fItaskname\fL = $\fIhost_command_string\fR
+.DE
+In this form of the task statement, the command to be sent to the host system
+to execute the new IRAF task may be any string. For example, on a VMS host,
+we might want to define the \fImail\fR task so that outgoing messages are
+always composed in the editor. This could be set up by adding the \fL/EDIT\fR
+switch to the command sent to VMS:
+.DS
+\fLtask $mail = $mail/edit\fR
+.DE
+Foreign task statements which reference user-written Fortran programs often
+refer to the program by its filename. For the task to work regardless of the
+current directory, either the full pathname of the executable file must be
+given, or some provision must be made at the host command interpreter level
+to ensure that the task can be found.
+.PP
+When a foreign task is called from the CL, the CL builds up the command string
+to be sent to the host command interpreter by converting each command line
+argument to a string and appending it to \fIhost_command_string\fR preceded
+by a space. This is the principal difference between the foreign task
+interface and the low level OS escape facility: in the case of a foreign task,
+the command line is fully parsed, permitting general expression evaluation,
+i/o redirection, background execution, minimum match abbreviations, and so on.
+.PP
+In most cases this simple method of composing the command to be sent to the
+host system is sufficient. There are occasional cases, however, where it is
+desirable to \fIembed\fR the command line arguments somewhere in the string
+to be sent to the host system. A special \fIargument substitution\fR notation
+is provided for this purpose. In this form of the task statement,
+\fIhost_command_string\fR contains special symbols which are replaced by the
+CL command line arguments to form the final host command string.
+These special symbols are defined in the table below.
+
+.TS
+center;
+c l.
+$0 replaced by \fItaskname\fR
+$1, $2, ..., $9 replaced by the indicated argument string
+$\(** replaced by the entire argument list
+$(N) use host equivalent of filename argument N (1-9 or \(**)
+.TE
+
+.PP
+An example of this form of the task statement is the \fIfc\fR task discussed
+in \(sc3.1. As we noted earlier, \fIfc\fR is merely a front-end to the more
+general IRAF HSI command/link utility \fIxc\fR. In fact, \fIfc\fR is
+implemented as a foreign task defined in the default \fIuser\fR package in
+the \fLLOGIN.CL\fR file. The task declaration used to define \fIfc\fR is
+shown below. The task statement shown is for UNIX; the VMS version is
+identical except that the \fL-O\fR switch must be quoted else DCL will convert
+it to lower case. In general, foreign task statements are necessarily
+machine dependent, since their function is to send a command to the host system.
+.DS
+\fLtask $fc = "$xc -h -O $\(** -limfort -lsys -lvops -los"\fR
+.DE
+The argument substitution facility is particularly useful when the host
+command template consists of several statements to be executed by the
+host command interpreter in sequence each time the CL foreign task is called.
+In this case, a delimiter character of some sort is required to delimit
+the host command interpreter statements. Once again, this is host system
+dependent, since the delimiter character to be used is defined by the syntax
+of the host command interpreter. On UNIX systems the command delimiter
+character is semicolon (`\fB;\fR'). VMS DCL does not allow multiple
+statements to be given on a single command line, but the IRAF interface
+to DCL does, using the exclamation character (`\fB!\fR'), which is the
+comment character in DCL.
+.PP
+The \fL$()\fR form of argument substitution is useful for foreign tasks
+with one or more filename arguments. The indicated argument or arguments
+are taken to be IRAF virtual filenames, and are mapped into their host
+filename equivalents to build up the host command string. For example,
+assume that we have an IMFORT task \fIphead\fR, the function of which is
+to print the header of an image in FITS format on the standard output
+(there really is such a program - look in \fLimfort$tasks/phead.f\fR).
+We might declare the task as follows (assuming that \fIphead\fR means
+something to the host system):
+.DS
+\fLtask $phead = "$phead $(*)"\fR
+.DE
+We could then call the new task from within the CL to list the header
+of, for example, the standard test image \fLdev$pix\fR, and page the output:
+.DS
+\fLcl> phead dev$pix | page\fR
+.DE
+Or we could direct the output to the line printer:
+.DS
+\fLcl> phead dev$pix | lpr\fR
+.DE
+Filename translation is available for all forms of argument substitution
+symbols, e.g., \fL$(1)\fR, \fL$(2)\fR, \fL$(\(**)\fR, and so on; merely
+add the parenthesis.
+.PP
+It is suggested that new foreign task statements, if not typed in
+interactively, be added to the \fIuser\fR package in your \fLLOGIN.CL\fR file,
+so that the definitions are not discarded when you log out of the CL or exit
+a package. If you want to make the new tasks available to other IRAF users
+they can be added to the \fIlocal\fR package by adding the task statements
+to the file \fLlocal$tasks/local.cl\fR. If this becomes unwieldy the
+next step is to define a new package and add it to the system; this is not
+difficult to do, but it is beyond the scope of this manual to explain how
+to do so.
+
+.NH 3
+Example 1 Revisited
+.PP
+Now that we are familiar with the details of the foreign task statement,
+it might be useful to review the examples of foreign task statements given
+in \(sc2.1, which introduced the \fIplanck\fR task. The UNIX example given
+was as follows:
+.DS
+\fLcl> task $planck = $planck.e\fR
+.DE
+This is fine, but only provided the \fIplanck\fR task is called from the
+directory containing the executable. To enable the executable to be called
+from any directory we can use a UNIX pathname instead, e.g.,
+.DS
+\fLcl> task $planck = $/usr/jones/iraf/tasks/planck.e\fR
+.DE
+Alternatively, one could place all such tasks in a certain directory, and
+either define the pathname of the directory as a shell environment variable
+to be referenced in the task statement, or include the task's directory in
+the shell search path. There are many other possibilities, of course, but
+it would be inappropriate to enumerate them here.
+.LP
+The VMS example given earlier was the following:
+.DS
+\fLcl> task $planck = "$planck:==\\\\$\fIdisk\fP:[\fIdir\fP...]planck.exe!planck"\fR
+.DE
+The command string at the right actually consists of two separate DCL commands
+separated by the VMS/IRAF DCL command delimiter `\fB!\fR'. If we invent a
+pathname for the executable, we can write down the the first command:
+.DS
+\fL$ planck :== $usr\\\\$2:[jones.iraf.tasks]planck.exe\fR
+.DE
+This is a DCL command which defines the new DCL foreign task \fIplanck\fR.
+We could shorten the CL foreign task statement by moving the DCL declaration
+to our DCL \fLLOGIN.COM\fR file; this has the additional benefit of allowing
+the task to be called directly from DCL, but is not as self-contained.
+If this were done the CL task statement could be shortened to the following.
+.DS
+\fLcl> task $planck = $foreign\fR
+.DE
+The same thing could be accomplished in Berkeley UNIX by defining a cshell
+\fIalias\fR for the task in the user's \fL.cshrc\fR file.
+
+.NH 2
+Debugging IMFORT Programs
+.PP
+Programs written and called from within the IRAF environment can be debugged
+using the host system debug facility without any inconvenience. The details
+of how to use the debugger are highly dependent upon the host system since
+the debugger is a host facility, but a few examples should help the reader
+understand what is involved.
+.PP
+Berkeley UNIX provides two debug tools, the assembly language debugger
+\fIadb\fR and the source language debugger \fIdbx\fR. Both are implemented
+as UNIX tasks and are called from within the IRAF environment as tasks,
+with the name of the program to be debugged as a command line argument
+(this example assumes that \fIadb\fR is a defined foreign task):
+.DS
+\fLcl> adb planck.e\fR
+.DE
+The program is then run with a debugger command, passing any command line
+arguments to the program as part of the debugger run-program command.
+Programs do not have to be compiled in any special way to be debugged
+with \fIadb\fR; programs should be compiled with \fIfc -x\fR to be debugged
+with \fIdbx\fR.
+.PP
+In VMS, the debugger is not a separate task but rather a shareable image
+which is linked directly into the program to be debugged. To debug a program,
+the program must first be linked with \fIfc -x\fR. The program is then run
+by simply calling it in the usual way from the CL, with any arguments given
+on the command line. When the program runs it comes up initially in the
+debugger, and a debugger command (\fIgo\fR) is required to execute the user
+program. Note that if the program is run directly with \fLrun/debug\fR
+there is no provision for passing an argument list to the task.
+
+.NH 2
+Calling IMFORT from Languages other than Fortran
+.PP
+Although our discussion and examples have concentrated exclusively on the
+use of the IMFORT library in host Fortran programs, the library is in fact
+language independent, i.e., it uses only low level, language independent
+system facilities and can therefore be called from any language available
+on the host system. The method by which Fortran subroutines and functions
+are called from another language, e.g., C or assembler, is highly machine
+dependent and it would be inappropriate for us to go into the details here.
+Note that \fIfc\fR may be used to compile and link C or assembler programs
+as well as Fortran programs.
+
+.NH 2
+Avoiding Library Name Collisions
+.PP
+Any program which uses IMFORT is being linked against the main IRAF system
+libraries, which together contain some thousands of external procedure names.
+Only a few hundred of these are likely to be linked into a host program,
+but there is always the chance that a user program module will have the
+same external name as one of the modules in the IRAF libraries.
+If such a library collision should occur, at best one would get an error
+message from the linker, and at worst one would end up with a program
+which fails mysteriously at run time.
+.PP
+At present there is no utility which can search a user program for externals
+and cross check these against the list of externals in the IRAF system
+libraries. A database of external names is however available in the file
+\fLlib$names\fR; this contains a sorted list of all the Fortran callable
+external names defined by procedures in the \fIimfort\fR, \fIex\fR, \fIsys\fR,
+\fIvops\fR, and \fIos\fR libraries (the \fIex\fR library is however not
+searched when linking IMFORT programs).
+.PP
+The \fImatch\fR task may be used to check individual user external names
+against the name list, or a host utility may be used for the same purpose.
+For example, to determine if the module \fIsubnam\fR is present in any
+of the IRAF system libraries:
+.DS
+\fLcl> match subnam lib$names\fR
+.DE
+The names database is also useful for finding the names of all the procedures
+sharing a particular package prefix. For example,
+.DS
+\fLcl> match "^cl" lib$names | table\fR
+.DE
+will find all the procedures whose names begin with the prefix "cl" and
+print them as a table (the \fIlists\fR package must be loaded first).
+
+.bp
+.NH
+The IMFORT Library
+.PP
+In this section we survey the procedures provided by the IMFORT interface,
+grouped according to the function they perform. There are currently four main
+groups: the command line access procedures, the image access procedures,
+the vector operators (VOPS), and a small binary file i/o package. With the
+exception of the VOPS procedures, all of the IMFORT routines were written
+especially for IMFORT and are not called in standard IRAF programs.
+The VOPS procedures are standard IRAF procedures, but are included in the
+IMFORT interface because they are coded at a sufficiently low level that they
+can be linked into any program, and they tend to be useful in image processing
+applications such as IMFORT is designed for.
+.PP
+The ANSI Fortran-77 standard requires that all names in Fortran programs have
+six or fewer characters. To eliminate guesswork, the names of all the IMFORT
+procedures are exactly six characters long and the names adhere to a
+\fBnaming convention\fR. The first one or two characters in each name
+identify the package or group to which the procedure belongs, e.g.,
+\fIcl\fR for the command line access package, \fIim\fR for the image
+access package, and so on. The package prefix is followed by the function name,
+and lastly a datatype code identifying the datatype upon which the procedure
+operates, in cases where multiple versions of the procedure are available for
+a range of datatypes.
+.DS
+\fIpackage_prefix // function_code // type_suffix\fR
+.DE
+The type suffix codes have already been introduced in the examples. They are
+the same as are used throughout IRAF. The full set is \fB[bcsilrdx]\fR, as
+illustrated in the following table (not all are used in the IMFORT procedures).
+
+.TS
+center box;
+cb s s s
+ci | ci | ci | ci
+c | l | c | l.
+Standard IRAF Datatypes
+_
+suffix name code typical fortran equivalent
+=
+b bool 1 \fLLOGICAL\fR
+c char 2 \fLINTEGER\(**2\fR (non-ANSI)
+s short 3 \fLINTEGER\(**2\fR (non-ANSI)
+i int 4 \fLINTEGER\fR
+l long 5 \fLINTEGER\(**4\fR (non-ANSI)
+r real 6 \fLREAL\fR
+d double 7 \fLDOUBLE PRECISION\fR
+x complex 8 \fLCOMPLEX\fR
+.TE
+.PP
+The actual mapping of IRAF datatypes into host system datatypes is machine
+dependent, i.e., \fIshort\fR may not map into INTEGER\(**2 on all machines.
+This should not matter since the datatype in which data is physically stored
+internally is hidden from user programs by the IMFORT interface.
+.PP
+In cases where multiple versions of a procedure are available for operands
+of different datatypes, a special nomenclature is used to refer to the class
+as a whole. For example,
+.DS
+\fLclarg[cird] (argno, [cird]val, ier)\fR
+.DE
+denotes the set of four procedures \fIclargc, clargi, clargr\fR, and
+\fIclargd\fR. The datatype of the output operand (\fIcval, ival\fR, etc.)
+must match the type specified by the procedure name.
+.PP
+With the exception of the low level binary file i/o procedures (BFIO),
+all IMFORT procedures are implemented as subroutines rather than functions,
+for reasons of consistency and to avoid problems with mistyping of undeclared
+functions by the Fortran compiler.
+
+.NH 2
+Command Line Access
+.PP
+The command line access procedures are used to decode the arguments present
+on the command line when the IMFORT program was invoked. This works both
+when the program is called from the IRAF CL, and when the program is called
+from the host system command interpreter. The command line access procedures
+are summarized in Figure 4, below.
+
+.TS
+center;
+n.
+\fLclnarg (\&nargs)\fR
+\fLclrawc (\&outstr, ier)\fR
+\fLclarg[cird] (\&argno, [cird]val, ier)\fR
+.TE
+.sp
+.ce
+Figure 4. Command Line Access Procedures
+
+.PP
+The \fIclnarg\fR procedure returns the number of command line arguments;
+zero is returned if an error occurs or if there were no command line arguments.
+The \fIclargc\fR, \fIclargi\fR, etc., procedures are used to fetch and decode
+the individual arguments; \fIclargc\fR returns a character string, \fIclargi\fR
+returns an integer, and so on. A nonzero \fIier\fR status indicates either
+that the command line did not contain the indexed argument, or that the
+argument could not be decoded in the manner specified. Character string
+arguments must be quoted on the command line if they contain any blanks or
+tabs, otherwise quoting is not necessary. The rarely used \fIclrawc\fR
+procedure returns the entire raw command line as a string.
+
+.NH 2
+Image Access
+.PP
+The image access procedures form the bulk of the IMFORT interface. There are
+three main categories of image access procedures, namely, the general image
+management procedures (open, close, create, get size, etc.), the header access
+procedures (used to get and put the values of header keywords), and the pixel
+i/o procedures, used to read and write image data.
+.PP
+IMFORT currently supports images of up to three dimensions,
+of type short-integer or real.
+There is no builtin limit on the size of an image, although
+the size of image a particular program can deal with is normally limited by
+the size of a statically allocated buffer in the user program. IMFORT does
+not map IRAF virtual filenames, hence host dependent names must be used when
+running a program which uses IMFORT.
+.PP
+IMFORT currently supports only the OIF image format, and images must be
+of type short-integer or real. Since normal IRAF programs support images of
+up to seven disk datatypes with a dimensionality of up to seven, as well as
+completely different image formats than that expected by IMFORT (e.g., STF),
+if you are not careful IRAF can create images which IMFORT programs cannot
+read (don't omit the error checking!). In normal use, however,
+types short-integer and real are by far the most common and images with
+more than two dimensions are rare, so these are not expected to be serious
+limitations.
+
+.NH 3
+General Image Access Procedures
+.PP
+The general image access and management procedures are listed in Figure 5.
+An image must be opened with \fIimopen\fR or \fIimopnc\fR before header access
+or pixel i/o can occur. The image open procedures return an
+\fIimage descriptor\fR (an integer magic number) which uniquely identifies
+the image in all subsequent accesses until the image is closed.
+When the operation is completed, an image must be closed with \fIimclos\fR to
+flush any buffered output, update the image header, and free any resources
+associated with the image descriptor. The maximum number of images which
+can be open at any one time is limited by the maximum number of open file
+descriptors permitted by the host operating system.
+.PP
+New images are created with \fIimopnc\fR and \fIimcrea\fR. The \fIimopnc\fR
+procedure creates a new copy of an existing image, copying the header of
+the old image to the new image but not the data. The new copy image must
+be the same size and datatype as the old image. For complete control over
+the attributes of a new image the \fIimcrea\fR procedure must be used.
+The \fIimopnc\fR operation is equivalent to an \fIimopen\fR followed by an
+\fIimgsiz\fR to determine the size and datatype of the old image, followed by
+an \fIimcrea\fR to create the new image, followed by an \fIimhcpy\fR to copy
+the header of the old image to the new image and then two \fIimclos\fR calls
+to close both images.
+.PP
+Note that \fIimgsiz always returns seven elements in the output array axlen\fR,
+regardless of the actual dimensionality of the image; this is so that current
+programs will continue to work in the future if IMFORT is extended to support
+images of dimensionality higher than three. Images may be deleted with
+\fIimdele\fR, or renamed with \fIimrnam\fR; the latter may also be used to
+move an image to a different directory. The \fIimflsh\fR procedure is used
+to flush any buffered output pixel data to an image opened for writing.
+
+.TS
+center;
+n.
+\fLimopen (\&image, acmode, im, ier) \fRacmode: 1=RO,3=RW
+\fLimopnc (\&nimage, oim, nim, ier) \fRacmode: always RW
+\fLimclos (\&im, ier)\fR
+
+\fLimcrea (\&image, axlen, naxis, dtype, ier)\fR
+\fLimdele (\&image, ier)\fR
+\fLimrnam (\&oldnam, newnam, ier)\fR
+
+\fLimflsh (\&im, ier)\fR
+\fLimgsiz (\&im, axlen, naxis, dtype, ier)\fR
+\fLimhcpy (\&oim, nim, ier)\fR
+\fLimpixf (\&im, pixfd, pixfil, pixoff, szline, ier)\fR
+.TE
+.sp
+.ce
+Figure 5. General Image Access Procedures
+
+.PP
+The \fIimpixf\fR procedure may be used to obtain the physical attributes
+of the pixel file, i.e., the pixel file name, the one-indexed \fIchar\fR
+offset to the first pixel, and the physical line length of an image as stored
+in the pixel file (the image lines may be aligned on device block boundaries).
+These parameters may be used to bypass the IMFORT pixel i/o procedures to
+directly access the pixels if desired (aside from the blocking of lines to
+fill device blocks, the pixels are stored as in a Fortran array).
+The BFIO file descriptor of the open pixel file is also returned, allowing
+direct access to the pixel file via BFIO if desired. If lower level (e.g.,
+host system) i/o facilities are to be used, \fIbfclos\fR or \fIimclos\fR
+should be called to close the pixel file before reopening it with the foreign
+i/o system.
+.PP
+Direct access to the pixel file is not recommended since it makes a program
+dependent upon the details of how the pixels are stored on disk; such a
+program may not work with future versions of the IMFORT interface, nor with
+implementations of the IMFORT interface for different (non-OIF) physical image
+storage formats. Direct access may be warranted when performing a minimum
+modification hack of an old program to make it work in the IRAF environment,
+or in applications with unusually demanding performance requirements,
+where the (usually negligible) overhead of the BFIO buffer is unacceptable.
+Note that in many applications, the reduction in disk accesses provided by
+the large BFIO buffer outweighs the additional cpu cycles required for memory
+to memory copies into and out of the buffer.
+
+.NH 3
+Image Header Keyword Access
+.PP
+The image header contains a small number of standard fields plus an arbitrary
+number of user or application defined fields. Each image has its own header
+and IMFORT does not in itself make any association between the header parameters
+of different images. The header access procedures are summarized in Figure 6.
+Note that the \fIimgsiz\fR procedure described in the previous section is the
+most convenient way to obtain the size and datatype of an open image, although
+the same thing can be achieved by a series of calls to obtain the values of
+the individual keywords, using the procedures described in this section.
+
+.TS
+center;
+n.
+\fLimacck (\&im, keyw, ier)\fR
+\fLimaddk (\&im, keyw, dtype, comm, ier)\fR
+\fLimdelk (\&im, keyw, ier)\fR
+\fLimtypk (\&im, keyw, dtype, comm, ier)\fR
+
+\fLimakw[bcdir] (\&im, keyw, [bcdir]val, comm, ier)\fR
+\fLimgkw[bcdir] (\&im, keyw, [bcdir]val, ier)\fR
+\fLimpkw[bcdir] (\&im, keyw, [bcdir]val, ier)\fR
+
+\fLimokwl (\&im, patstr, sortit, kwl, ier)\fR
+\fLimgnkw (\&kwl, outstr, ier)\fR
+\fLimckwl (\&kwl, ier)\fR
+.TE
+.sp
+.ce
+Figure 6. Image Header Access Procedures
+
+.PP
+Both the standard and user defined header parameters may be accessed via the
+procedures introduced in this section. The \fIimacck\fR procedure tests for
+the existence of the named keyword, returning a zero \fIier\fR if the keyword
+exists. New keywords may be added to the image header with \fIimaddk\fR,
+and old keywords may be deleted with \fIimdelk\fR. The datatype of a keyword
+may be determined with \fIimtypk\fR. The attributes of a keyword are its
+name, datatype, value, and an optional comment string describing the
+significance of the parameter. The comment string is normally invisible
+except when the header is listed, but may be set when a new keyword is added
+to the header, or fetched with \fIimtypk\fR.
+.PP
+The most commonly used procedures are likely to be the \fIimgkw\fR and
+\fIimpkw\fR families of procedures, used to get and put the values of named
+keywords; these procedures require that the keyword already be present in
+the header. The \fIimakw\fR procedures should be used instead of the
+\fIimpkw\fR procedures if it is desired that a keyword be automatically added
+to the header if not found, before setting the new value. Automatic datatype
+conversion is performed if the requested datatype does not match the actual
+datatype of the keyword.
+.PP
+The \fIkeyword list\fR package is the only way to obtain information from
+the header without knowing in advance the names of the header keywords.
+The \fIimokwl\fR procedure opens a keyword list consisting of all header
+keywords matching the given pattern, returning a \fIlist descriptor\fR to
+be used as input to the other procedures in the package. Successive
+keyword \fInames\fR are returned in calls to \fIimgnkw\fR; a nonzero
+\fIier\fR is returned when the end of the list is reached. The keyword
+name is typically used as input to other procedures such as \fIimtypk\fR
+or one of the \fIimgkw\fR procedures to obtain further information about
+the keyword. A keyword list should be closed with \fIimckwl\fR when it is
+no longer needed to free system resources associated with the list descriptor.
+
+.TS
+center box;
+cb s s
+ci | ci | ci
+l | c | l.
+Standard Image Header User Keywords
+_
+name datatype description
+=
+naxis int number of axes (dimensionality)
+naxis[1:3] int length of each axis, pixels
+pixtype int pixel datatype
+datamin real minimum pixel value
+datamax real maximum pixel value
+ctime int image creation time
+mtime int image modification time
+limtime int time min/max last updated
+title string image title string (for plots etc.)
+.TE
+
+.PP
+The keyword list pattern string follows the usual IRAF conventions; some
+useful patterns are "\(**", which matches the entire header, and "i_", which
+matches only the standard header keywords (the standard header keywords are
+really named "i_naxis", "i_pixtype", etc., although the "i_" may be omitted
+in most cases). A pattern which does not include any pattern matching
+metacharacters is taken to be a prefix string, matching all keywords whose
+names start with the pattern string.
+.PP
+An image must be opened with read-write access for header updates to have
+any effect. An attempt to update a header without write permission will
+not produce an error status return until \fIimclos\fR is called to update
+the header on disk (and close the image).
+
+.NH 3
+Image Pixel Access
+.PP
+The IMFORT image pixel i/o procedures are used to get and put entire image
+lines to N-dimensional images, or to get and put N-dimensional subrasters
+to N-dimensional images. In all cases the caller supplies a buffer into
+which the pixels are to be put, or from which the pixels are to be taken.
+The pixel i/o procedures are summarized in Figure 7.
+.PP
+As shown in the figure, there are four main classes of pixel i/o procedures,
+the get-line, put-line, get-section, and put-section procedures. The get-line
+and put-line procedures are special cases of the get/put section procedures,
+provided for programming convenience in the usual line by line sequential
+image operator (they are also slightly more efficient than the subraster
+procedures for line by line i/o). It is illegal to reference out of bounds
+and \fIi1\fR must be less than or equal to \fIi2\fR (IMFORT will not flip
+lines); the remaining subscripts may be swapped if desired. Access may be
+completely random if desired, but sequential access (in storage order) implies
+fewer buffer faults and is more efficient.
+
+.KS
+.TS
+center;
+n.
+\fLim[gp]l1[rs] (\&im, buf, ier)\fR
+\fLim[gp]l2[rs] (\&im, buf, lineno, ier)\fR
+\fLim[gp]l3[rs] (\&im, buf, lineno, bandno, ier)\fR
+\fLim[gp]s1[rs] (\&im, buf, i1, i2, ier)\fR
+\fLim[gp]s2[rs] (\&im, buf, i1, i2, j1, j2, ier)\fR
+\fLim[gp]s3[rs] (\&im, buf, i1, i2, j1, j2, k1, k2, ier)\fR
+.TE
+.sp
+.ce
+Figure 7. Image Pixel I/O Procedures
+.KE
+
+.PP
+Type short and type real versions of each i/o procedure are provided.
+The type real procedures may be used to access images of either type short
+or type real, with automatic datatype conversion being provided if the disk
+and program datatypes do not match. The type short-integer i/o procedures
+may only be used with type short images.
+.PP
+The user who is familiar with the type of image i/o interface which maps
+the pixel array into virtual memory may wonder why IMFORT uses the more old
+fashioned buffered technique. There are two major reasons why this approach
+was chosen. Firstly, the virtual memory mapping technique, in common use on
+VMS systems, is \fInot portable\fR. On a host which does not support the
+mapping of file segments into paged memory, the entire image must be copied
+into paged memory when the image is opened, then copied again when the image
+operation takes place, then copied once again from memory to disk when the
+image is closed. Needless to say this is very inefficient, particularly for
+large images, and some of our applications deal with images 2048 or even 6000
+pixels square.
+.PP
+Even on a machine that supports mapping of file segments into memory, mapped
+access will probably not be efficient for sequential access to large images,
+since it causes the system to page heavily; data pages which will never be
+used again fill up the system page caches, displacing text pages that must
+then be paged back in. This happens on even the best systems, and on a system
+that does not implement virtual memory efficiently, performance may suffer
+greatly.
+.PP
+A less obvious reason is that mapping the image directly into memory violates
+the principle of \fIdata independence\fR, i.e., a program which uses this
+type of interface has a builtin dependence on the particular physical image
+storage format in use when the program was developed. This rules out even
+such simple interface features as automatic datatype conversion, and prevents
+the expansion of the interface in the future, e.g., to provide such attractive
+features as an image section capability (as in the real IRAF image interface),
+network access to images stored on a remote node, support for pixel storage
+schemes other than line storage mode (e.g., isotropic mappings or sparse image
+storage), and so on.
+.PP
+The majority of image operations are either sequential whole-image operations
+or operations upon subrasters, and are just as easily programmed with a
+buffered interface as with a memory mapped interface. The very serious
+drawbacks of the memory mapped interface dictate that it not be used except
+in special applications that must randomly access individual pixels in an
+image too large to be read in as a subraster.
+
+.NH 2
+Error Handling
+.PP
+The IMFORT error handling mechanism is extremely simple. All procedures in
+which an error condition can occur return a nonzero \fIier\fR error code
+if an error occurs. The value of \fIier\fR identifies which of many possible
+errors actually occurred. These error codes may be converted into error
+message strings with the following procedure:
+.DS
+\fLimemsg (\&ier, errmsg)\fR
+.DE
+It is suggested that every main program contain an error handling section at
+the end of the program which calls \fIimemsg\fR and halts program execution
+with an informative error message, as in the examples in \(sc2.
+This is especially helpful when debugging new programs.
+
+.NH 2
+Vector Operators
+.PP
+The vector operators (VOPS) package is a subroutine library implementing
+a large number of primitive operations upon one dimensional vectors of any
+datatype. Some of the operations implemented by the VOPS routines are
+non-trivial to implement, in which case the justification for a library
+subroutine is clear. Even in the simplest cases, however, the use of a
+VOPS procedure is advantageous because it provides scope for optimizing
+all programs which use the VOPS operator, without having to modify the
+calling programs. For example, if the host machine has vector hardware
+or special machine instructions (e.g., the block move and bitfield instructions
+of the VAX), the VOPS operator can be optimized in a machine dependent way
+to take advantage of the special capabilities of the hardware, without
+compromising the portability of the applications software using the procedure.
+.PP
+The VOPS procedures adhere to the naming convention described in \(sc4.
+The package prefix is \fIa\fR, the function code is always three characters,
+and the remaining one or two characters define the datatype or types upon
+which the procedure operates. For example, \fIaaddr\fR performs a vector
+add upon type real operands. If the character \fIk\fR is added to the
+three character function name, one of the operands will be a scalar.
+For example, \fIaaddkr\fR adds a scalar to a vector, with both the scalar
+and the vector being of type real.
+.PP
+Most vector operators operate upon operands of a single datatype: one notable
+exception is the \fIacht\fR (change datatype) operator, used to convert a
+vector from one datatype to another. For example, \fIachtbi\fR will unpack
+each byte in a byte array into an integer in the output array, providing a
+capability that cannot be implemented in portable Fortran. Any datatype
+suffix characters may be substituted for the \fIbi\fR, to convert a vector
+from any datatype to any other datatype.
+.PP
+In general, there are are three main classes of vector operators, the
+\fIunary\fR operators, the \fIbinary\fR operators, and the \fIprojection\fR
+operators. The unary operators perform some operation upon a single input
+vector, producing an output vector as the result. The binary operators
+perform some operation upon two input vectors, producing an output vector
+as the result. The projection operators compute some function of a single
+input vector, producing a scalar function value (rather than a vector) as
+the result. Unary operators typically have three arguments, binary
+operators four, and projection operators two arguments and one output
+function value. For example, \fIaabsi\fR is the unary absolute value
+vector operator, type integer (here, \fIa\fR is the input vector, \fIb\fR
+is the output vector, and \fInpix\fR is the number of vector elements):
+.DS
+\fLaabsi (a, b, npix)\fR
+.DE
+A typical example of a binary operator is the vector add operator, \fIaaddr\fR.
+Here, \fIa\fR and \fIb\fR are the input vectors, and \fIc\fR is the output
+vector:
+.DS
+\fLaaddr (a, b, c, npix)\fR
+.DE
+In all cases except where the output vector contains fewer elements than one
+of the input vectors, the output vector may be the same as one of the input
+vectors. A full range of datatypes are provided for each vector operator,
+except that there are no boolean vector operators (integer is used instead),
+and \fIchar\fR and \fIcomplex\fR are only partially implemented, since they
+are not sensible datatypes for many vector operations. In any case, the VOPS
+\fIchar\fR is the SPP char and should be avoided in Fortran programs.
+.PP
+Once these rules are understood, the calling sequence of a particular VOPS
+operator can usually be predicted with little effort. The more complex
+operators, of course, may have special arguments, and some study is typically
+required to determine their exact function and how they are used. A list of
+the VOPS operators currently provided is given below (the datatype suffix
+characters must be added to the names shown to form the full procedure names).
+
+.TS
+center;
+n.
+aabs -\& Absolute value of a vector
+aadd -\& Add two vectors
+aaddk -\& Add a vector and a scalar
+aand -\& Bitwise boolean AND of two vectors
+aandk -\& Bitwise boolean AND of a vector and a scalar
+aavg -\& Compute the mean and standard deviation of a vector
+abav -\& Block average a vector
+abeq -\& Vector equals vector
+abeqk -\& Vector equals scalar
+abge -\& Vector greater than or equal to vector
+abgek -\& Vector greater than or equal to scalar
+abgt -\& Vector greater than vector
+abgtk -\& Vector greater than scalar
+able -\& Vector less than or equal to vector
+ablek -\& Vector less than or equal to scalar
+ablt -\& Vector less than vector
+abltk -\& Vector less than scalar
+abne -\& Vector not equal to vector
+abnek -\& Vector not equal to scalar
+abor -\& Bitwise boolean OR of two vectors
+abork -\& Bitwise boolean OR of a vector and a scalar
+absu -\& Block sum a vector
+acht -\& Change datatype of a vector
+acjgx -\& Complex conjugate of a complex vector
+aclr -\& Clear (zero) a vector
+acnv -\& Convolve two vectors
+acnvr -\& Convolve a vector with a real kernel
+adiv -\& Divide two vectors
+adivk -\& Divide a vector by a scalar
+adot -\& Dot product of two vectors
+advz -\& Vector divide with divide by zero detection
+aexp -\& Vector to a real vector exponent
+aexpk -\& Vector to a real scalar exponent
+afftr -\& Forward real discrete fourier transform
+afftx -\& Forward complex discrete fourier transform
+aglt -\& General piecewise linear transformation
+ahgm -\& Accumulate the histogram of a series of vectors
+ahiv -\& Compute the high (maximum) value of a vector
+aiftr -\& Inverse real discrete fourier transform
+aiftx -\& Inverse complex discrete fourier transform
+aimg -\& Imaginary part of a complex vector
+alim -\& Compute the limits (minimum and maximum values) of a vector
+alln -\& Natural logarithm of a vector
+alog -\& Logarithm of a vector
+alov -\& Compute the low (minimum) value of a vector
+altr -\& Linear transformation of a vector
+alui -\& Vector lookup and interpolate (linear)
+alut -\& Vector transform via lookup table
+amag -\& Magnitude of two vectors (sqrt of sum of squares)
+amap -\& Linear mapping of a vector with clipping
+amax -\& Vector maximum of two vectors
+amaxk -\& Vector maximum of a vector and a scalar
+amed -\& Median value of a vector
+amed3 -\& Vector median of three vectors
+amed4 -\& Vector median of four vectors
+amed5 -\& Vector median of five vectors
+amgs -\& Magnitude squared of two vectors (sum of squares)
+amin -\& Vector minimum of two vectors
+amink -\& Vector minimum of a vector and a scalar
+amod -\& Modulus of two vectors
+amodk -\& Modulus of a vector and a scalar
+amov -\& Move (copy or shift) a vector
+amovk -\& Move a scalar into a vector
+amul -\& Multiply two vectors
+amulk -\& Multiply a vector and a scalar
+aneg -\& Negate a vector (change the sign of each pixel)
+anot -\& Bitwise boolean NOT of a vector
+apkx -\& Pack a complex vector given the real and imaginary parts
+apol -\& Polynomial evaluation
+apow -\& Vector to an integer vector power
+apowk -\& Vector to an integer scalar power
+arav -\& Mean and standard deviation of a vector with pixel rejection
+arcp -\& Reciprocal of a scalar and a vector
+arcz -\& Reciprocal with detection of divide by zero
+arlt -\& Vector replace pixel if less than scalar
+argt -\& Vector replace pixel if greater than scalar
+asel -\& Vector select from two vectors based on boolean flag vector
+asok -\& Selection of the Kth smallest element of a vector
+asqr -\& Square root of a vector
+asrt -\& Sort a vector in order of increasing pixel value
+assq -\& Sum of squares of a vector
+asub -\& Subtract two vectors
+asubk -\& Subtract a scalar from a vector
+asum -\& Sum of a vector
+aupx -\& Unpack the real and imaginary parts of a complex vector
+awsu -\& Weighted sum of two vectors
+awvg -\& Mean and standard deviation of a windowed vector
+axor -\& Bitwise boolean XOR (exclusive or) of two vectors
+axork -\& Bitwise boolean XOR (exclusive or) of a vector and a scalar
+.TE
+
+.PP
+A non-trivial example of the use of vector operators is the case of bilinear
+interpolation on a two dimensional image. The value of each pixel in the
+output image is a linear sum of the values of four pixels in the input image.
+The obvious solution is to set up a do-loop over the pixels in each line of
+the output image, computing the linear sum over four pixels from the input
+image for each pixel in the output line; this is repeated for each line in the
+output image.
+.PP
+The solution using the VOPS operators involves the \fIalui\fR (vector look up
+and interpolate) and \fIawsu\fR (weighted sum) vector operators. A lookup table
+defining the X-coordinate in the input image of each pixel in a line of the
+output image is first generated. Then, for each line of the output image,
+the two lines from the input image which will contribute to the output image
+line are extracted. \fIAlui\fR is used to interpolate each line in X, then
+\fIawsu\fR is used to form the weighted sum to interpolate in the Y direction.
+This technique is especially efficient when bilinear interpolation is being
+used to expand the image, in which case the \fIalui\fR interpolated X-vectors,
+for example, are computed once but then used to generate several lines of
+the output image by taking the weighted sum, a simple and fast operation.
+When moving sequentially up through the image, the high X-vector becomes the
+low X-vector for the next pair of input lines, hence only a single call to
+\fIalui\fR is required to set up the next region.
+.PP
+The point of this example is that many or most image operations can be
+expressed in terms of primitive one dimensional vector operations,
+regardless of the dimensionality of the image being operated upon.
+The resultant algorithm will often run more efficiently even on a conventional
+scalar machine than the equivalent nonvectorized code, and will probably run
+efficiently without modification on a vector machine.
+.PP
+Detailed specification sheets (manual pages) are not currently available for
+the VOPS procedures. A summary of the calling sequences is given in the file
+\fLvops$vops.syn\fR, which can be paged or printed by that name while in the
+CL, assuming that the system has not been stripped and that the sources are
+still on line. The lack of documentation is really not a problem for these
+operators, since they are all fairly simple, and it is easy to page the source
+file (in the \fIvops\fR directory) to determine the exact calling sequence.
+For example, to examine the source for \fIawsu\fR, type
+.DS
+\fLcl> page vops$awsu.gx\fR
+.DE
+to page the generic source, regardless of the specific datatype of interest.
+If you have trouble deciphering the generic source,
+use \fLxc -f file.x\fR to produce the Fortran translation
+of one of the type specific files in the subdirectories
+\fLvops$ak\fR and \fLvops$lz\fR.
+
+.NH 2
+Binary File I/O (BFIO)
+.PP
+The IMFORT binary file i/o package (BFIO) is a small package, written
+originally as an internal package for use by the IMFORT image i/o routines
+for accessing header and pixel files (the VOS FIO package could not be used
+in IMFORT without linking the entire IRAF/VOS runtime system into the Fortran
+program). Despite its original conception as an internal package, the package
+provides a useful capability and is portable, hence has been included in the
+IMFORT interface definition. Nonetheless, the user should be warned that BFIO
+is a fairly low level interface and some care is required to use it safely.
+If other suitable facilities are available it may be better to use those,
+although few interfaces will be found which are simpler or more efficient
+than BFIO for randomly accessing pre-existing or preallocated binary files.
+.PP
+The principal capability provided by BFIO is the ability to randomly access
+a binary file, reading or writing an arbitrary number of char-units of storage
+at any (one-indexed) char offset in the file. The file itself is a non-record
+structured file containing no embedded record manager information,
+hence is suitable for access by any program, including non-Fortran programs,
+and for export to other machines (this is usually not the case with a Fortran
+unformatted direct access file). Unlike the mainline IMFORT procedures,
+many of the BFIO procedures are integer functions returning a positive count
+value if the operation is successful (e.g., the number of char units of storage
+read or written), or a negative value if an error occurs. Zero is returned
+for a read at end of file.
+
+.TS
+center;
+n.
+\fLbfaloc (\&fname, nchars, status)\fR
+\fLfd = bfopen (\&fname, acmode, advice) \fRacmode: 1=RO,3=RW,5=NF
+\fLbfclos (\&fd, status) \fRadvice: 1=random,2=seq
+
+\fLnchars = bfread (\&fd, buf, nchars, offset)\fR
+\fLnchars = bfwrit (\&fd, buf, nchars, offset)\fR
+
+\fLnchars = bfbsiz (\&fd)\fR
+\fLnchars = bffsiz (\&fd)\fR
+\fLchan = bfchan (\&fd)\fR
+\fLstat = bfflsh (\&fd)\fR
+.TE
+.sp
+.ce
+Figure 8. Low Level Binary File I/O Procedures
+
+.PP
+BFIO binary files may be preallocated with \fIbfaloc\fR, or created with
+\fIbfopen\fR and then initialized by writing at the end of file.
+Preallocating a file is useful when the file size is known in advance, e.g.,
+when creating the pixel file for a new image. The contents of a file
+allocated with \fIbfaloc\fR are uninitialized. To extend a file by writing
+at the end of file the file size must be known; the file size may be obtained
+by calling \fIbffsiz\fR on the open file.
+.PP
+Before i/o to a file can occur, the file must be opened with \fIbfopen\fR.
+The \fIbfopen\fR procedure returns as its function value an integer
+\fIfile descriptor\fR which is used to refer to the file in all subsequent
+accesses until the file is closed with \fIbfclos\fR. Binary data is read
+from the file with \fIbfread\fR, and written to the file with \fIbfwrit\fR.
+Any amount of data may be read or written in a single call to \fIbfread\fR
+or \fIbfwrit\fR. All user level i/o is synchronous and data is buffered
+internally by BFIO to minimize disk transfers and provide for the blocking
+and deblocking of data into device blocks. Any buffered output data may be
+flushed to disk with \fIbfflsh\fR. The function \fIbfchan\fR returns the
+descriptor of the raw i/o channel as required by the IRAF binary file driver.
+.PP
+BFIO manages an internal buffer, necessary for efficient sequential i/o and
+to hide the device block size from the user program. Larger buffers are
+desirable for sequential i/o on large files; smaller buffers are best for
+small files or for randomly accessing large files. The buffer size may be
+set at \fIbfopen\fR time with the \fIadvice\fR parameter. An \fIadvice\fR
+value of 1 implies random access and causes a small buffer to be allocated;
+a value of 2 implies sequential access and causes a large buffer to be
+allocated. Any other value is taken to be the actual buffer size in chars,
+but care must be used since the value specified must be some multiple of the
+device block size, and less than the maximum transfer size permitted by the
+kernel file driver. Note that when writing at end of file, the full contents
+of the internal buffer will be written, even if the entire buffer contents
+were not written into in a \fIbfwrit\fR call. The buffer size in chars is
+returned by \fIbfbsiz\fR.
+.PP
+Since BFIO is a low level interface, the file offset must always be specified
+when reading from or writing to the file, even when the file is being accessed
+sequentially. Contrary to what one might think, file offsets are one-indexed
+in the Fortran tradition, and are specified in units of \fIchars\fR.
+Do not confuse \fIchar\fR with the Fortran \fLCHARACTER\fR; \fIchar\fR is the
+fundamental unit of storage in IRAF, the smallest datum which can be accessed
+as an integer quantity with the host Fortran compiler, normally
+\fLINTEGER\(**2\fR (16 bits or two bytes on all current IRAF hosts).
+
+.bp
+.SH
+Appendix: Manual Pages for the Imfort Procedures
+.PP
+This section presents the ``manual pages'' for the IMFORT and BFIO procedures.
+The manual pages present the exact technical specifications of each procedure,
+i.e., the procedure name and arguments (not necessarily obvious in the case of
+a typed family of procedures), the datatypes and dimensions of the arguments,
+and a precise description of the operation of the procedure.
+Each procedure is presented on a separate page for ease of reference.
+.PP
+The following conventions have been devised to organize the information
+presented in this section:
+.RS
+.IP \(bu
+The manual pages are presented in alphabetical order indexed by the procedure
+name.
+.IP \(bu
+A single manual page is used to present an entire family of procedures which
+differ only in the datatype of their primary operand. The name on the manual
+page is the generic name of the family, e.g., \fIclargi\fR, \fIclargr\fR, etc.,
+are described in the manual page \fIclarg\fR.
+.IP \(bu
+In some cases it makes sense to describe several related procedures with a
+single manual page. An example is the keyword-list package, consisting of
+the procedures \fIimokwl\fR, \fIimgnkw\fR, and \fIimckwl\fR. In such a case,
+since the procedures have different names the manual page for the group is
+duplicated for each procedure in the group, so that the user will not have
+to guess which name the manual page is filed under.
+.IP \(bu
+The \fIsynopsis\fR section of each manual page defines the calling sequence of
+each procedure, the datatypes and dimensions of the arguments, and notes
+whether each argument is an input argument (\fL#I\fR) or an output argument
+(\fL#O\fR).
+.IP \(bu
+The \fIreturn value\fR section describes the conditions required for
+successful execution of the procedure, normally indicated by a zero status
+in \fIier\fR. A symbolic list of the possible error codes is also given.
+The numeric values of these error codes are defined in \fLimfort$imfort.h\fR
+and in \fLlib$syserr.h\fR, but the exact numeric codes should be used only for
+debugging purposes or passed on to the \fIimemsg\fR procedure to get the error
+message string. The numeric error codes are likely to change in future versions
+of the interface hence their values should not be "wired into" programs.
+.RE
+.PP
+Manual pages for the VOPS procedures are not included since VOPS is not really
+part of the IMFORT interface, and it is not yet clear if the VOPS procedures
+are complex enough to justify the production of individual manual pages.
diff --git a/sys/imfort/doc/imfort.toc b/sys/imfort/doc/imfort.toc
new file mode 100644
index 00000000..b68c5b69
--- /dev/null
+++ b/sys/imfort/doc/imfort.toc
@@ -0,0 +1,54 @@
+.LP
+.ps +2
+.ce
+\fBContents\fR
+.ps
+.sp 3
+.sp
+1.\h'|0.4i'\fBIntroduction\fP\l'|5.6i.'\0\01
+.br
+\h'|0.4i'1.1.\h'|0.9i'Who Should Use IMFORT\l'|5.6i.'\0\01
+.sp
+2.\h'|0.4i'\fBGetting Started\fP\l'|5.6i.'\0\03
+.br
+\h'|0.4i'2.1.\h'|0.9i'Example 1: Plotting a function\l'|5.6i.'\0\03
+.br
+\h'|0.4i'2.2.\h'|0.9i'Example 2: Compute the range of pixel values in an image\l'|5.6i.'\0\06
+.br
+\h'|0.4i'2.3.\h'|0.9i'Example 3: Copy an image\l'|5.6i.'\0\07
+.sp
+3.\h'|0.4i'\fBThe IMFORT Programming Environment\fP\l'|5.6i.'\0\09
+.br
+\h'|0.4i'3.1.\h'|0.9i'The FC Compile/Link Utility\l'|5.6i.'\0\09
+.br
+\h'|0.4i'3.2.\h'|0.9i'Host Level Linking to the IMFORT Libraries\l'|5.6i.'\0\11
+.br
+\h'|0.4i'3.3.\h'|0.9i'Calling Host Programs from the CL\l'|5.6i.'\0\11
+.br
+\h'|0.9i'3.3.1.\h'|1.5i'Example 1 Revisited\l'|5.6i.'\0\13
+.br
+\h'|0.4i'3.4.\h'|0.9i'Debugging IMFORT Programs\l'|5.6i.'\0\14
+.br
+\h'|0.4i'3.5.\h'|0.9i'Calling IMFORT from Languages other than Fortran\l'|5.6i.'\0\15
+.br
+\h'|0.4i'3.6.\h'|0.9i'Avoiding Library Name Collisions\l'|5.6i.'\0\15
+.sp
+4.\h'|0.4i'\fBThe IMFORT Library\fP\l'|5.6i.'\0\16
+.br
+\h'|0.4i'4.1.\h'|0.9i'Command Line Access\l'|5.6i.'\0\17
+.br
+\h'|0.4i'4.2.\h'|0.9i'Image Access\l'|5.6i.'\0\17
+.br
+\h'|0.9i'4.2.1.\h'|1.5i'General Image Access Procedures\l'|5.6i.'\0\18
+.br
+\h'|0.9i'4.2.2.\h'|1.5i'Image Header Keyword Access\l'|5.6i.'\0\19
+.br
+\h'|0.9i'4.2.3.\h'|1.5i'Image Pixel Access\l'|5.6i.'\0\20
+.br
+\h'|0.4i'4.3.\h'|0.9i'Error Handling\l'|5.6i.'\0\22
+.br
+\h'|0.4i'4.4.\h'|0.9i'Vector Operators\l'|5.6i.'\0\22
+.br
+\h'|0.4i'4.5.\h'|0.9i'Binary File I/O (BFIO)\l'|5.6i.'\0\26
+.sp
+\h'|0.4i'\fBAppendix A:\fR Manual Pages for the IMFORT Procedures\l'|5.6i.'\0\28
diff --git a/sys/imfort/doc/imgkw.hlp b/sys/imfort/doc/imgkw.hlp
new file mode 100644
index 00000000..412113da
--- /dev/null
+++ b/sys/imfort/doc/imgkw.hlp
@@ -0,0 +1,41 @@
+.help imgkw Sep86 imfort
+.ih
+NAME
+imgkw -- get the value of an image header keyword
+.ih
+SYNOPSIS
+.nf
+subroutine imgkwb (im, keyw, bval, ier)
+subroutine imgkwc (im, keyw, cval, ier)
+subroutine imgkwi (im, keyw, ival, ier)
+subroutine imgkwr (im, keyw, rval, ier)
+subroutine imgkwd (im, keyw, dval, ier)
+
+integer im #I image descriptor of open image
+character*(*) keyw #I name of the keyword to be set
+integer ier #O status return
+
+logical bval #O logical (boolean) keyword value
+character*(*) cval #O character string keyword value
+integer ival #O integer keyword value
+real rval #O real keyword value
+doubleprecision dval #O double precision keyword value
+.fi
+.ih
+DESCRIPTION
+The \fIimgkw\fR procedures are used to get the values of image header keywords.
+Automatic datatype conversion is provided, hence the datatype requested need
+not be an exact match to the actual datatype of the keyword.
+.ih
+RETURN VALUE
+A zero status is returned if the named keyword exists and if the datatype
+coercion implied is permissible.
+
+.nf
+SYS_IDBKEYNF: image header keyword not found
+SYS_IDBTYPE: illegal header parameter data type conversion
+.fi
+.ih
+SEE ALSO
+impkw, imaddk, imacck
+.endhelp
diff --git a/sys/imfort/doc/imgl.hlp b/sys/imfort/doc/imgl.hlp
new file mode 100644
index 00000000..389031ae
--- /dev/null
+++ b/sys/imfort/doc/imgl.hlp
@@ -0,0 +1,48 @@
+.help imgl Sep86 imfort
+.ih
+NAME
+.nf
+imgl -- get (read) an image line
+.fi
+.ih
+SYNOPSIS
+.nf
+subroutine imgl1r (im, rbuf, ier)
+subroutine imgl1s (im, sbuf, ier)
+subroutine imgl2r (im, rbuf, lineno, ier)
+subroutine imgl2s (im, sbuf, lineno, ier)
+subroutine imgl3r (im, rbuf, lineno, bandno, ier)
+subroutine imgl3s (im, sbuf, lineno, bandno, ier)
+
+integer im #I image descriptor of open image
+real rbuf(*) #O output pixel buffer, type real
+integer*2 sbuf(*) #O output pixel buffer, type short
+integer lineno #I line (row) number (1:axlen(2))
+integer bandno #I band number (1:axlen(3))
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimgl\fR procedures are used to get a line (row) from an image.
+Procedures are provided for images of from one to three dimensions,
+of pixel type short integer or real. The type real procedures may be
+applied to images of either type, but the type short procedures may only
+be used to access images of type short. The output buffer must provide
+storage for at least \fIaxlen(1)\fR pixels or a buffer overrun will occur.
+.ih
+RETURN VALUE
+A zero status is returned if the referenced image line is in-bounds and
+the actual pixel datatype of the image is one of the types permitted by
+the particular operator called.
+
+.nf
+IE_NOTSHORT: imfort short integer i/o requires a type short image
+IE_PIXTYPE: image pixel type must be short or real
+IE_RDPIX: error reading image pixel file
+IE_YOOB: image y coordinates out of range
+IE_ZOOB: image z coordinates out of range
+.fi
+.ih
+SEE ALSO
+impl, imgs, imps
+.endhelp
diff --git a/sys/imfort/doc/imgs.hlp b/sys/imfort/doc/imgs.hlp
new file mode 100644
index 00000000..73ba756b
--- /dev/null
+++ b/sys/imfort/doc/imgs.hlp
@@ -0,0 +1,54 @@
+.help imgs Sep86 imfort
+.ih
+NAME
+.nf
+imgs -- get (read) an image section
+.fi
+.ih
+SYNOPSIS
+.nf
+subroutine imgs1r (im, rbuf, i1,i2, ier)
+subroutine imgs1s (im, sbuf, i1,i2, ier)
+subroutine imgs2r (im, rbuf, i1,i2, j1,j2, ier)
+subroutine imgs2s (im, sbuf, i1,i2, j1,j2, ier)
+subroutine imgs3r (im, rbuf, i1,i2, j1,j2, k1,k2, ier)
+subroutine imgs3s (im, sbuf, i1,i2, j1,j2, k1,k2, ier)
+
+integer im #I image descriptor of open image
+real rbuf(*) #O output pixel buffer, type real
+integer*2 sbuf(*) #O output pixel buffer, type short
+integer i1, i2 #I range of columns to be extracted
+integer j1, j2 #I range of lines to be extracted
+integer k1, k2 #I range of bands to be extracted
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimgs\fR procedures are used to get a section (subraster) from an image.
+Procedures are provided for images of from one to three dimensions,
+of pixel type short integer or real. The type real procedures may be
+applied to images of either type, but the type short procedures may only
+be used to access images of type short. The output buffer must provide
+space for at least (i1-i2+1) pixels (\fIgs1\fR), ((j2-j1+1) * (i2-i1+1)) pixels
+(\fIgs2\fR), or ((k2-k1+1) * (j2-j1+1) * (i2-i1+1)) pixels (\fIgs3\fR).
+The pixels are returned in Fortran storage order. The column index \fIi2\fR
+must be greater than or equal to \fIi1\fR, but the remaining subscripts may
+be swapped if desired.
+.ih
+RETURN VALUE
+A zero status is returned if the referenced image section is in-bounds and
+the actual pixel datatype of the image is one of the types permitted by
+the particular operator called.
+
+.nf
+IE_NOTSHORT: imfort short integer i/o requires a type short image
+IE_PIXTYPE: image pixel type must be short or real
+IE_RDPIX: error reading image pixel file
+IE_XOOB: image x coordinates out of range or out of order
+IE_YOOB: image y coordinates out of range
+IE_ZOOB: image z coordinates out of range
+.fi
+.ih
+SEE ALSO
+imps, imgl, impl
+.endhelp
diff --git a/sys/imfort/doc/imgsiz.hlp b/sys/imfort/doc/imgsiz.hlp
new file mode 100644
index 00000000..bd2e3972
--- /dev/null
+++ b/sys/imfort/doc/imgsiz.hlp
@@ -0,0 +1,51 @@
+.help imgsiz Sep86 imfort
+.ih
+NAME
+imgsiz -- determine the size and datatype of an open image
+.ih
+SYNOPSIS
+.nf
+subroutine imgsiz (im, axlen, naxis, dtype, ier)
+
+integer im #I image descriptor of open image
+integer axlen(7) #O length of each axis
+integer naxis #O number of axes (dimensionality)
+integer dtype #O pixel datatype
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimgsiz\fR procedure is called to determine the dimensionality, size,
+and datatype of an open image, i.e., the physical attributes of the pixel
+array. Upon output, \fIaxlen\fR will contain the length of each axis of
+the image, where \fIaxlen(1)\fR is the number of pixels in each image line
+(the number of columns), \fIaxlen(2)\fR is the number of lines in each band
+of the image, \fIaxlen(3)\fR is the number of bands, and so on.
+Seven array elements are returned regardless of the actual dimensionality of
+the image; the lengths of the excess axes are set to one. The logical
+dimensionality of the image is returned in \fInaxis\fR. A code identifying
+the datatype of the pixels is returned in \fIpixtype\fR; the range of possible
+pixel datatypes is enumerated in the table below.
+
+.nf
+ 3 short integer (usually 16 bits signed)
+ 4 integer (generally the same as long integer)
+ 5 long integer (usually 32 bits signed)
+ 6 single precision floating (real)
+ 7 double precision floating
+ 8 complex
+ 11 unsigned short (16 bits unsigned)
+.fi
+
+Note that although the image storage format may support all of these datatypes,
+IMFORT is currently only capable of accessing images of type short or real.
+.ih
+RETURN VALUE
+A zero status is returned for any valid open image, i.e., provided the image
+descriptor given is valid.
+
+IE_MAGIC: illegal imfort image descriptor
+.ih
+SEE ALSO
+imgkwi, imcrea
+.endhelp
diff --git a/sys/imfort/doc/imhcpy.hlp b/sys/imfort/doc/imhcpy.hlp
new file mode 100644
index 00000000..3a36816d
--- /dev/null
+++ b/sys/imfort/doc/imhcpy.hlp
@@ -0,0 +1,30 @@
+.help imhcpy Sep86 imfort
+.ih
+NAME
+imhcpy -- copy an image header
+.ih
+SYNOPSIS
+.nf
+subroutine imhcpy (oim, nim, ier)
+
+integer oim #I image descriptor of input image
+integer nim #I image descriptor of output image
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimhcpy\fR procedure is used to copy the non-pixel fields in the header
+of one image to another image, given the runtime descriptors of the two images.
+The images must previously have been opened with \fIimopen\fR or \fIimopnc\fR.
+The header fields which are \fInot\fR copied are those describing the physical
+attributes the pixel array, i.e., the number of axes, the physical dimensions
+of the image, the pixel datatype code, and the minimum and maximum pixel values.
+.ih
+RETURN VALUE
+A zero status will be returned provided both image descriptors are valid.
+
+IE_MAGIC: illegal imfort image descriptor
+.ih
+SEE ALSO
+imgsiz, imgkw, impkw
+.endhelp
diff --git a/sys/imfort/doc/imokwl.hlp b/sys/imfort/doc/imokwl.hlp
new file mode 100644
index 00000000..6e860cb7
--- /dev/null
+++ b/sys/imfort/doc/imokwl.hlp
@@ -0,0 +1,65 @@
+.help imokwl,imgnkw,imckwl Sep86 imfort
+.ih
+NAME
+.nf
+imokwl -- open an image header keyword list
+imgnkw -- get the next keyword from the list
+imckwl -- close the keyword list
+.fi
+.ih
+SYNOPSIS
+.nf
+subroutine imokwl (im, patstr, sortit, kwl, ier)
+
+integer im #I image descriptor of open image
+character*(*) patstr #I pattern matching subset of keywords
+logical sortit #I sort the list by keyword name?
+integer kwl #O keyword list descriptor
+integer ier #O status return
+
+subroutine imgnkw (kwl, outstr, ier)
+
+integer kwl #I keyword list descriptor
+character*(*) outstr #O the next keyword name
+integer ier #O status return
+
+subroutine imckwl (kwl, ier)
+
+integer kwl #I keyword list descriptor
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The keyword list package is used to define some subset of the keywords in an
+image header, and then read successive elements of the set, i.e., read back
+the keyword names. The keyword names are normally used as input to
+\fIimtypk\fR or one of the \fIimgkw\fR procedures to obtain additional
+information about each keyword. The keyword list package is the only means
+whereby a program can examine the contents of an image header without knowing
+in advance the names of the individual header keywords. A typical application
+of the keyword list package is listing the contents of an image header.
+
+The pattern string \fIpatstr\fR is used to specify the subset of header keywords
+to be used to form the output list. Some useful values are "*", which returns
+the names of all header keywords, and "i_", which returns the names of only the
+standard header keywords. If the pattern string does not contain any pattern
+matching meta-characters it is treated as a prefix string (e.g., as "^patstr*").
+.ih
+RETURN VALUE
+The \fIimokwl\fR procedure returns a nonzero status only if it runs out of
+storage for the keyword list. It is not an error for a list to be empty.
+The \fIimgnkw\fR procedure returns a nonzero status when the end of the
+keyword list is reached.
+
+.nf
+SYS_IMFNOVFL: out of space for header keyword name list
+IE_EOF: end of file or list detected
+.fi
+.ih
+NOTES
+An example illustrating the use of the keyword list package may be found
+in imfort$tasks/phead.f.
+.ih
+SEE ALSO
+imtypk, imgkw
+.endhelp
diff --git a/sys/imfort/doc/imopen.hlp b/sys/imfort/doc/imopen.hlp
new file mode 100644
index 00000000..3df3ca51
--- /dev/null
+++ b/sys/imfort/doc/imopen.hlp
@@ -0,0 +1,35 @@
+.help imopen Sep86 imfort
+.ih
+NAME
+imopen -- open an existing image
+.ih
+SYNOPSIS
+.nf
+subroutine imopen (image, acmode, im, ier)
+
+character*(*) image #I host image to be opened
+integer acmode #I access mode
+integer im #O receives image descriptor
+integer ier #O status code
+.fi
+.ih
+DESCRIPTION
+The \fIimopen\fR procedure is used to open an existing image for either
+read only access (\fIacmode\fR=1) or read write access (\fIacmode\fR=3).
+The image name must be the host system filename of the image, although
+the extension may be omitted if desired. If the image open is successful
+an image descriptor is returned in \fIim\fR.
+.ih
+RETURN VALUE
+A nonzero status code is returned if the image does not exist or cannot
+be opened with the indicated access mode.
+
+.nf
+IE_OPEN: cannot open image
+IE_NOTIMH: attempt to access a non-image file as an image
+IE_OPNPIX: cannot open pixel file
+.fi
+.ih
+SEE ALSO
+imclos, imcrea, imopnc, imdele, imrnam
+.endhelp
diff --git a/sys/imfort/doc/imopnc.hlp b/sys/imfort/doc/imopnc.hlp
new file mode 100644
index 00000000..b4f5d9a9
--- /dev/null
+++ b/sys/imfort/doc/imopnc.hlp
@@ -0,0 +1,49 @@
+.help imopnc Sep86 imfort
+.ih
+NAME
+imopnc -- open a new copy of an existing image
+.ih
+SYNOPSIS
+.nf
+imopnc (nimage, oim, nim, ier)
+
+character*(*) nimage #I host name of the new image
+integer oim #I image descriptor of existing image
+integer nim #O image descriptor of the new image
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimopnc\fR procedure is used to open a new copy of an existing image,
+copying the non-pixel fields of the old image header to the new image.
+The new image must be the same size and datatype as the old image.
+The new image is created, the header information is copied, and the pixel
+file is allocated, but no pixel data is copied, and the \fIdatamin\fR and
+\fIdatamax\fR fields of the image header are reset to zero. The new image
+is opened for read-write access and the image descriptor of the new image
+is returned in \fInim\fR.
+.ih
+RETURN VALUE
+A zero status value is returned if the operation is successful, i.e., if
+\fIoim\fR is a valid image descriptor of an existing image already opened
+with \fIimopen\fR or \fIimopnc\fR, the new image was successfully created,
+and the header was successfully copied.
+
+.nf
+IE_ACCPIX: error writing into pixel file during image create
+IE_ALCPIX: cannot create or allocate space for pixel file
+IE_CREHDR: cannot create image
+IE_MAGIC: illegal imfort image descriptor
+IE_OPEN: cannot open image
+IE_OPNPIX: cannot open pixel file
+IE_UPDHDR: error updating image header file
+.fi
+.ih
+NOTES
+If it is desired that the new image be of a different size or datatype than
+the old image, the new image must be explicitly created with \fIimcrea\fR,
+opened with \fIimopen\fR, and the old header copied with \fIimhcpy\fR.
+.ih
+SEE ALSO
+imcrea, imopen, imgsiz, imhcpy, imclos
+.endhelp
diff --git a/sys/imfort/doc/impixf.hlp b/sys/imfort/doc/impixf.hlp
new file mode 100644
index 00000000..b5ccb335
--- /dev/null
+++ b/sys/imfort/doc/impixf.hlp
@@ -0,0 +1,53 @@
+.help impixf Sep86 imfort
+.ih
+NAME
+impixf -- get the physical attributes of the pixel file
+.ih
+SYNOPSIS
+.nf
+subroutine impixf (im, pixfd, pixfil, pixoff, szline, ier)
+
+integer im #I image descriptor of open image
+integer pixfd #O BFIO file descriptor of pixel file
+character*(*) pixfil #O host filename of pixel file
+integer pixoff #O 1-indexed "char" offset of pixels
+integer szline #O "chars" per physical image line
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimpixf\fR procedure is used to obtain information describing the
+physical layout of the pixel segment of an image in a binary disk file.
+The pixel array of an image accessible via the IMFORT interface is stored
+externally in the host file \fIpixfil\fR in line storage mode (as in a
+Fortran array). Each line of the image is stored as a contiguous array of
+pixels accessible via a BFIO \fIbfread\fR or \fIbfwrit\fR request at the
+offset of the first pixel in the line. The first image line (beginning at
+pixel [1,1,1,...]) is stored at the file offset given by \fIpixoff\fR.
+Each line consumes exactly \fIszline\fR chars of storage; lines may be
+blocked to fill an integral number of disk blocks for more efficient access,
+hence \fIszline\fR is not directly computable from \fIaxlen(1)\fR.
+
+Since \fIimpixf\fR is called on an open image, the pixel file will already
+have been opened for random access buffered binary file i/o via the BFIO
+interface. The BFIO file descriptor of the open pixel file is returned in
+\fIpixfd\fR. This may be used in conjunction with BFIO to directly access
+the pixel data. If the pixel data is to be accessed via explicit calls
+to lower level host system facilities, the image should first be closed
+with \fIimclos\fR to avoid possible problems with having the same file
+opened multiple times.
+.ih
+RETURN VALUE
+A zero status is returned for any image which has a valid image descriptor.
+
+IE_MAGIC: illegal imfort image descriptor
+.ih
+NOTES
+Programs which make use of the information provided by \fIimpixf\fR have
+explicit knowledge of the physical image storage format and hence may not
+work with future versions of the IMFORT interface supporting new physical
+image storage formats.
+.ih
+SEE ALSO
+imgsiz, imgs, imps, imgl, impl, bfread, bfwrit
+.endhelp
diff --git a/sys/imfort/doc/impkw.hlp b/sys/imfort/doc/impkw.hlp
new file mode 100644
index 00000000..8381e828
--- /dev/null
+++ b/sys/imfort/doc/impkw.hlp
@@ -0,0 +1,51 @@
+.help impkw Sep86 imfort
+.ih
+NAME
+impkw -- set the value of an image header keyword
+.ih
+SYNOPSIS
+.nf
+subroutine impkwb (im, keyw, bval, ier)
+subroutine impkwc (im, keyw, cval, ier)
+subroutine impkwi (im, keyw, ival, ier)
+subroutine impkwr (im, keyw, rval, ier)
+subroutine impkwd (im, keyw, dval, ier)
+
+integer im #I image descriptor of open image
+character*(*) keyw #I name of the keyword to be set
+integer ier #O status return
+
+logical bval #I logical (boolean) keyword value
+character*(*) cval #I character string keyword value
+integer ival #I integer keyword value
+real rval #I real keyword value
+doubleprecision dval #I double precision keyword value
+.fi
+.ih
+DESCRIPTION
+The \fIimpkw\fR procedures are used to set the values of existing image
+header keywords. It is an error if the named keyword does not already
+exist; the \fIimakw\fR procedures should be used if one wants the keyword
+to be automatically added if not found, but if the keyword is known
+to exist it is preferable to use the \fIimpkw\fR procedures since they
+are more efficient and will detect misspelled keyword names and foreign
+images. Automatic datatype conversion is provided, i.e., it is not
+necessary to know the exact datatype of a keyword to update its value.
+.ih
+RETURN VALUE
+A zero status is returned if the named keyword exists, is writable, and if
+the datatype coercion implied is permissible.
+
+.nf
+SYS_IDBKEYNF: image header keyword not found
+SYS_IDBTYPE: illegal header parameter data type conversion
+.fi
+.ih
+NOTES
+It is not an error to update the value of a keyword in an image opened
+for read-only access, but an error status will be returned at \fIimclos\fR or
+\fIimflsh\fR time since the header cannot be updated on disk.
+.ih
+SEE ALSO
+imacck, imakw, imgkw
+.endhelp
diff --git a/sys/imfort/doc/impl.hlp b/sys/imfort/doc/impl.hlp
new file mode 100644
index 00000000..4081f69f
--- /dev/null
+++ b/sys/imfort/doc/impl.hlp
@@ -0,0 +1,49 @@
+.help impl Sep86 imfort
+.ih
+NAME
+.nf
+impl -- put (rewrite) an image line
+.fi
+.ih
+SYNOPSIS
+.nf
+subroutine impl1r (im, rbuf, ier)
+subroutine impl1s (im, sbuf, ier)
+subroutine impl2r (im, rbuf, lineno, ier)
+subroutine impl2s (im, sbuf, lineno, ier)
+subroutine impl3r (im, rbuf, lineno, bandno, ier)
+subroutine impl3s (im, sbuf, lineno, bandno, ier)
+
+integer im #I image descriptor of open image
+real rbuf(*) #I output pixel buffer, type real
+integer*2 sbuf(*) #I output pixel buffer, type short
+integer lineno #I line (row) number (1:axlen(2))
+integer bandno #I band number (1:axlen(3))
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimpl\fR procedures are used to rewrite a line (row) of an image.
+Procedures are provided for images of from one to three dimensions,
+of pixel type short integer or real. The type real procedures may be
+applied to images of either type, but the type short procedures may only
+be used to access images of type short. The input buffer should contain
+\fIaxlen(1)\fR pixels ready to be written to the image when the \fIimpl\fR
+procedure is called.
+.ih
+RETURN VALUE
+A zero status is returned if the referenced image line is in-bounds and
+the actual pixel datatype of the image is one of the types permitted by
+the particular operator called.
+
+.nf
+IE_NOTSHORT: imfort short integer i/o requires a type short image
+IE_PIXTYPE: image pixel type must be short or real
+IE_WRPIX: error writing image pixel file
+IE_YOOB: image y coordinates out of range
+IE_ZOOB: image z coordinates out of range
+.fi
+.ih
+SEE ALSO
+imgl, imgs, imps
+.endhelp
diff --git a/sys/imfort/doc/imps.hlp b/sys/imfort/doc/imps.hlp
new file mode 100644
index 00000000..6850f052
--- /dev/null
+++ b/sys/imfort/doc/imps.hlp
@@ -0,0 +1,54 @@
+.help imps Sep86 imfort
+.ih
+NAME
+.nf
+imps -- put (rewrite) an image section
+.fi
+.ih
+SYNOPSIS
+.nf
+subroutine imps1r (im, rbuf, i1,i2, ier)
+subroutine imps1s (im, sbuf, i1,i2, ier)
+subroutine imps2r (im, rbuf, i1,i2, j1,j2, ier)
+subroutine imps2s (im, sbuf, i1,i2, j1,j2, ier)
+subroutine imps3r (im, rbuf, i1,i2, j1,j2, k1,k2, ier)
+subroutine imps3s (im, sbuf, i1,i2, j1,j2, k1,k2, ier)
+
+integer im #I image descriptor of open image
+real rbuf(*) #I output pixel buffer, type real
+integer*2 sbuf(*) #I output pixel buffer, type short
+integer i1, i2 #I range of columns to be updated
+integer j1, j2 #I range of lines to be updated
+integer k1, k2 #I range of bands to be updated
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimps\fR procedures are used to rewrite a section (subraster) of an image.
+Procedures are provided for images of from one to three dimensions,
+of pixel type short integer or real. The type real procedures may be
+applied to images of either type, but the type short procedures may only
+be used to access images of type short. The output buffer should contain
+at least (i1-i2+1) pixels (\fIps1\fR), ((j2-j1+1) * (i2-i1+1)) pixels
+(\fIps2\fR), or ((k2-k1+1) * (j2-j1+1) * (i2-i1+1)) pixels (\fIps3\fR).
+The pixels are assumed to be in Fortran storage order. The column index
+\fIi2\fR must be greater than or equal to \fIi1\fR, but the remaining
+subscripts may be swapped if desired.
+.ih
+RETURN VALUE
+A zero status is returned if the referenced image line is in-bounds and
+the actual pixel datatype of the image is one of the types permitted by
+the particular operator called.
+
+.nf
+IE_NOTSHORT: imfort short integer i/o requires a type short image
+IE_PIXTYPE: image pixel type must be short or real
+IE_WRPIX: error writing image pixel file
+IE_XOOB: image x coordinates out of range or out of order
+IE_YOOB: image y coordinates out of range
+IE_ZOOB: image z coordinates out of range
+.fi
+.ih
+SEE ALSO
+imgs, imgl, impl
+.endhelp
diff --git a/sys/imfort/doc/imrnam.hlp b/sys/imfort/doc/imrnam.hlp
new file mode 100644
index 00000000..03ba6d6b
--- /dev/null
+++ b/sys/imfort/doc/imrnam.hlp
@@ -0,0 +1,35 @@
+.help imrnam Sep86 imfort
+.ih
+NAME
+imrnam -- rename an image
+.ih
+SYNOPSIS
+.nf
+subroutine imrnam (oldnam, newnam, ier)
+
+character*(*) oldnam #I host name of existing image
+character*(*) newnam #I new host name for image
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimrnam\fR procedure renames an image, i.e., changes the filenames
+of both the header and pixel files. An image may be renamed to a different
+directory if desired, in effect moving the image to the new directory.
+.ih
+RETURN VALUE
+A zero status is returned if the image exists and was successfully renamed.
+
+.nf
+IE_IMRNAMNEXIM: attempt to rename a nonexistent image
+IE_IMRENAME: cannot rename image
+.fi
+.ih
+NOTES
+Since the filename of the pixel file associated with an image may be
+saved in the image header, it is not advisable to use an ordinary file
+rename operator to rename an image.
+.ih
+SEE ALSO
+imdele, imcrea
+.endhelp
diff --git a/sys/imfort/doc/imtypk.hlp b/sys/imfort/doc/imtypk.hlp
new file mode 100644
index 00000000..b8f3b4b0
--- /dev/null
+++ b/sys/imfort/doc/imtypk.hlp
@@ -0,0 +1,33 @@
+.help imtypk Sep86 imfort
+.ih
+NAME
+imtypk -- get the type information for a header keyword
+.ih
+SYNOPSIS
+.nf
+subroutine imtypk (im, keyw, dtype, comm, ier)
+
+integer im #I image descriptor of open image
+character*(*) keyw #I name of the new keyword
+integer dtype #O keyword datatype code
+character*(*) comm #O comment string describing keyword
+integer ier #O status return
+.fi
+.ih
+DESCRIPTION
+The \fIimtypk\fR procedure is used to fetch the information defining
+the type and usage of an image header keyword, i.e., the datatype code
+and comment string. Knowledge of the keyword datatype may be required
+before accessing the value of a keyword to avoid a format conversion error
+if only the name of the keyword is known (e.g., when using the keyword-list
+package). The \fIimtypk\fR procedure is the only means currently available
+for retrieving the comment string associated with a header keyword.
+.ih
+RETURN VALUE
+A zero status is returned if the named keyword exists.
+
+SYS_IDBKEYNF: image header keyword not found
+.ih
+SEE ALSO
+imaddk, imacck
+.endhelp