Directory Contents
------------------

README      - This file.
image.h     - The global declarations for the image access routines.
image.c     - The source for the image access routines.
pdim.c	    - The source for the PDIM routines.
test_im.c   - A menu based test program for the image access routines.
test_pdim.c - A menu based test program for the PDIM routines.
Makefile    - Makefile for the above on most machines.
Makefile.*  - Makefile for the above on particular machines.

Installation Guide
------------------

To generate a new library and install it, we need to:

1)  Remove old object files (make clean).
2)  Recompile and install the library (make install).  The include 
    file, image.h, will also be copied to /usr/image/lib.
3)  It is a good idea next to do step 1 again (make clean).  This will
    result in some small disk space savings.

To test the image access routines, we need to:

1)  Recompile the test program (make test_im)
2)  Run the menu based program (test_im).
3)  Test each of the routines in the menu.

To test the PDIM routines, we need to:

1)  Recompile the test program (make test_pdim)
2)  Run the menu based program (test_pdim).
3)  Test each of the routines in the menu.


Internal Documentation for image.c
----------------------------------

The image access library (image.c) provides a collection of routines
for reading and writing images of arbitrary sizes.  The details of how 
the image is stored in the image file and the algorithms used to access 
this data are described in this document.  This information is provided 
for the maintainers and developers of image.c.  Users of the system 
need only read the iman pages for routines in the library.

File formats 
------------

All images created and manipulated by the image library are stored in 
standard UNIX files.  Each image file contains:

   a)  The image header.  This is a fixed length field which describes 
       important properties of the image (size, title, etc).

   b)  The image pixels.  This is a variable length field which contains
       the pixel data for the image.

   c)  The image information field.  This is a variable length field
       which contains a collection of ASCII strings describing various
       properties of the image (comments, pdim, etc).

A structure called IMAGE is specified in the file image.h. It specifies
the memory mapping of a portion of an image file.  Since programs only 
read the image pixels from files when necessary, the pixel arrays are 
not part of this structure.  Thus parts a and c in the above list are
stored in struct IMAGE.  The IMAGE structure will be referred to 
occasionally below, as the format of images is discussed.  The imopen()
and imclose() routines perform I/O of the IMAGE structure.  They should
be considered the ultimate definition of this structure.  The pixel data 
are transfered by the pixel I/O functions, imread(), imwrite(), 
GetPut2D(), GetPut3D(), and GetPutND() in image.c.

In addition to the header and information fields, the IMAGE structure 
also contains three computed fields: the UNIX file descriptor, the number 
of bytes in each pixel (PixelSize) and the number of pixels in the image 
(PixelCnt).  These fields are always computed when an image is opened or 
created.
        
The variable length nature of image files make it possible to create
and manipulate images of arbitrary sizes.  To implement this feature,
addresses of the starting byte of the variable length fields are stored
in the image header.

The Image Header
----------------

The image header is stored in the first K bytes of the image file.  The 
fields of this header are ALWAYS stored in the following order:

   a)  The address field (9 integers).  This array contains the address
       of the starting byte for the MAXMIN, HISTO, TITLE, PIXFORM, DIMC, 
       DIMV, PIXELS, INFO and VERNO fields in that order.  Image.c 
       contains definitions of index values for each of these.  The names 
       of these indexes are made by prefixing the letter "a" to the field 
       name.  To read each of these fields, we simply lseek to the proper 
       starting byte, Image.Address[index], and read the appropriate 
       number of bytes.

   b)  The title field (81 characters).  This contains a null terminated
       string which is the title of the image.  This data is located
       Address[aTITLE] bytes from start of file.

   c)  The validity flag for the maxmin field (1 integer).  This is a 
       Boolean flag which indicates if the MAXMIN field is valid or not.
       This data is located Address[aMAXMIN] bytes from the start of file.

   d)  The maxmin field (2 integers).  This array contains the minimum
       value of the image (in position 0) and the maximum value in the 
       image (in position 1).  This field is updated whenever pixels are
       written to the image.  This data is located Address[aMAXMIN] + 4
       bytes from the start of file.

   e)  The validity flag for the histogram field (1 integer).  This is a 
       Boolean flag which indicates if the HISTO field is valid or not.
       This data is located Address[aHISTO] bytes from the start of file.

   f)  The histogram field (4094 short integers).  This array contains the
       histogram for the pixel data.  The system only generates this field
       for GREY images when im_gethisto is called.  This data is located 
       Address[aHISTO] + 4 bytes from the start of file.

   g)  The pixel format field (1 integer).  This integer contains a code
       identifying the type of pixels to be stored.  See image.h for a 
       list of possible values.  This data is located Address[aPIXFORM]
       bytes from the start of file.

   h)  The dimension count field (1 integer).  This integer specifies 
       the number of dimensions in the current image.  The valid range
       is [1..10].  This data is located Address[aDIMC] bytes from the
       start of file.

   i)  The dimension vector field (10 integers).  This array specifies
       the size of each dimension in the image.  Although we claim to 
       handle an arbitrary number of dimensions, the present limit is 
       ten (the size of the array).  This data is located Address[aDIMV] 
       bytes from the start of file.

The Image Pixels
----------------

We can store pixels for images of arbitrary size and with any number of
dimensions.  This is accomplished by storing a variable number of pixels
in the image file.  These pixels are stored in M bytes immediately after 
the image header (where M is the product of all N dimension lengths and
the pixel size).  

The implementation of pixel access is transparent to the user.  In order
for the system routines im_read, im_write, im_getpix, and im_putpix to 
extract a given pixel whose index is (i0,i1, ... ,iN) from this data 
we must determine:

   a)  The pixel offset.  We use an N dimensional extension of 
       row-major addressing of multi-dimensional arrays to access pixels 
       in an image file.  For example, to calculate the pixel offset 
       of (i0,i1, ... ,iN) we find the sum of index * dimension size
       for all indices (just like how arrays are indexed in C).

   b)  The size of individual pixels.  Pixels can be 1,2,4 or 8 bytes
       long depending on the pixel type.  Once the pixel offset is 
       known, the byte index is found by multiplying by the pixel
       length.

Because 2D and 3D images are so common, the process of reading and writing 
blocks of pixels from 2D and 3D image files has been optimized to reduce 
the total number of I/O calls (lseek, read and write) required.  This is
why we have GetPut2D, GetPut3d and GetPutND routines.

The Image Information Field
---------------------------

The information field is a mechanism for saving application specific
data with an image.  This is implemented as a variable length ASCII
string which is made up of a variable number of (field_name, field_data) 
pairs.  The field_name is a null terminated string which identifies the
data being stored (i.e. "comment").  The field_data is a null terminated
string which contains the corresponding data (i.e. "This is a test image").
At the end of this list of pairs is an extra null character.

When an image is opened, the list of (field_name, field_data) pairs 
is read into a structure in the image header.  All subsequent calls to
access these information fields manipulate this record.  When the image
is closed, the updated information string is written out to disk.  At
present the maximum number of information fields which can be saved in 
an image is 100.  This can be increased by changing image.h.

