\documentstyle[a4,12pt]{article}
\begin{document}
\author{John Butler}
\title{IFF Utilities}
\maketitle
\parskip .1 in
\setcounter{secnumdepth}{10}
\parindent 0in
\section{Preamble}
File IFF:UTILS.DOC - Documentation of IFF utilities and file formats 23/11/87

This file describes how to use the APM IFF library.
The library is intended to cope with the difficult bits of handling images.
The routines are designed for image work but will operate on any
rectangular array of values. You will need a graphics system or laser printer
to do much with them.

\section{Introduction}

The routines exist on APMs and EMAS in this form and the original IFF utilities
exist on Unix. The APM versions are written in IMP but can be called from Pascal.

IFF stands for Image File Format. \hspace{0.2 in} There are numerous such formats - this is
one specified by the vision group at Edinburgh and Sheffield and these routines
work with an extended form developed in a very ad-hoc manner by John Butler at
Edinburgh. The main purpose was to provide a suite of facilities to make image
handling quick and easy and to kill off a multitude of formats which threatened
to make life impossible. Contributions are welcomed!

They allow you to read write and display IFF files, analyse their contents, dump
them to a laser printer, view them in 3-D, invert them, patch them and create
IFF files of images written to the APM screen by LEVEL1: routines.
You can trim the black bits off the edge, merge two or more images into the one
screenful or display three monochrome images (Red, Green, Blue) as a composite
RGB image and/or merge them into a file at the same time. You can compare two
images as a scattergram. The SEESCAN camera system can be used to capture
images in IFF form.

These routines were written in odd moments when the phone stopped ringing so
doubtless still have the odd bug. Report anything strange to JHB. Most stuff is
in directory IFF: (the version on 'B' is the master copy), with some extras in
CAMERA:. Everything should be read-permitted.


\section{Contents of directories IFF and CAMERA (alphabetical order)}

\subsection{ANALYSE}

Display the colour-value histogram of an image and its colour map.

\subsection{CORREL}

Show the correlation between two IFF images as a scattergram.

\subsection{DEMO.IMP, DEMO.PAS}

IFF utilities demo program (IMP and Pascal respectively)

\subsection{DISP}

displays an IFF file to the screen
NOTE: DISP expects a file of grey levels in the range 0-255
(though it'll work with anything). If you are generating binary
images use 0 for off and 255 for on or your DISP'd images will
have virtually no contrast.

\subsection{DOT}

Takes a multi-grey level IFF file and converts it to a form
suitable for outputting to the CLAN laser printer. The file is
dithered and can be scaled or grey-inverted. Note that SPLAT below
can only handle 2 grey levels (though does it faster).

\subsection{GALLERY}

Takes a steering file containing IFF filenames, paragraphs of
descriptive text and coordinates. \hspace{0.2 in} The coordinates are used to
overlay the IFF images (in sequence) with boxes full of the text.
It gives a "slide-show" for demonstration purposes.

\subsection{GRAPH (Level 1 emulation)}

Level 1 graphics emulation routines

These are a set of routines which mimic the Level1: routines but write to
an IFF file instead of or as well as writing to the screen.
This provides a means of saving (and then taking a hard copy of) APM screens.

You use them as follows:

In your IMP or Pascal program source..

\small\tt \begin{verbatim}1) Replace your %include "level1:graphinc.imp"   or 'level1:graphinc.pas'
   by           %include "iff:graphinc.imp"      or 'iff:graphinc.pas'

2) Insert a call on IFF OPEN FRAME before the first call on a level1 graphics
   routine and a call on IFF CLOSE FRAME after the last one. (iffopenframe and
   iffcloseframe respectively in Pascal)
\end{verbatim}\rm  \normalsize 
Recompile.

INSTALL IFF:GRAPH

and run your program. It should generate the required file.
Note it will run much more slowly than the level1: graphics.

\subsubsection{The library (for IMP programs):}

\small\tt \begin{verbatim}%externalintegerfn IFF OPEN FRAME %alias "IFF_OPEN_FRAME"( %c
%string (255) filename, title, %integer mode)
\end{verbatim}\rm  \normalsize 
Open access to an IFF file for writing a level1 screen.

FILENAME will be generated with the extension .IFF if no extension was
provided.

TITLE is your text string describing the image.

MODE is a bitmap which controls the write operation. The following two values
are defined for you in the \%include file:

\small\tt \begin{verbatim}   IFF SCREEN  (bit 2^0) :  If set will write to the screen providing there's a
                            screen to write to.
   IFF FILE    (bit 2^1) :  If set will write to the file.
\end{verbatim}\rm  \normalsize 
Note: Calling the routines with MODE=0 will do NOTHING.

The IFF file generated will be 688 pixels wide * 512 high and will show
the portion of the screen visible when IFF CLOSE FRAME was called.

The colour map written to the file will be that in force at the time
IFF CLOSE FRAME is called.


\small\tt \begin{verbatim}%externalroutine IFF CLOSE FRAME %alias "IFF_CLOSE_FRAME"
\end{verbatim}\rm  \normalsize 
This closes the IFF file and writes it. Omit this call and you won't have a
file.


\subsubsection{The library (for Pascal programs):}

\small\tt \begin{verbatim}type str255 = VARYING [ 255 ] OF CHAR ;

function iffopenframe %alias 'IFF_OPEN_FRAME'
(filename, title : str255; mode : INTEGER) : INTEGER ; EXTERNAL ;
\end{verbatim}\rm  \normalsize 
Open access to an IFF file for writing a level1 screen.

FILENAME will be generated with the extension .IFF if no extension was
provided.

TITLE is your text string describing the image.

MODE is a bitmap which controls the write operation. The following two values
are defined for you in the \%include file:

\small\tt \begin{verbatim}   iff_screen  (bit 2^0) :  If set will write to the screen providing there's a
                            screen to write to.
   iff_file    (bit 2^1) :  If set will write to the file.
\end{verbatim}\rm  \normalsize 
Note: Calling the routines with MODE=0 will do NOTHING.

The IFF file generated will be 688 pixels wide * 512 high and will show
the portion of the screen visible when iffcloseframe was called.

The colour map written to the file will be that in force at the time
iffcloseframe is called.

\small\tt \begin{verbatim}procedure iffcloseframe %alias 'IFF_CLOSE_FRAME' ; EXTERNAL ;
\end{verbatim}\rm  \normalsize 
This closes the IFF file and writes it. Omit this call and you won't have a
file.



\subsection{HTMERGE}

Take 3 monochrome IFF files (Red, Green, Blue), overlay them
and display them as a composite. Write the composite image as
a file if an output file is specified.

\subsection{MERGE}

Take a set of IFF files, place the images at different parts of
screen and create a composite file if an output file is specified.

\subsection{PATCH}

Utility for editing IFF headers.

\subsection{SOLID}

Peter Reid's solid body modeller. Takes an IFF image as input
and treats it as a grid of heights. You must specify the .IFF
extension as the program takes point lists by default.

\subsection{SPLAT}

Takes one or more 2 grey-level IFF files and outputs them to a
file in laser printer compatible form. \hspace{0.2 in} This produces output on
the CLAN printer in the copier room ONLY.
Parameters: $<$iff file1$>$,$<$iff file2$>$,$<$iff file3$>$... / outputfile
Outputfile will acquire the extension .LAY

To output a binary image to the laser printer...

SPLAT it to a scratch file then EFTP it to b::lp2:
The laser despooler will then print it for you
on the laser printer in Sidney Michaelson's outer office.
The scale is a magnification factor. Start with 1 and
increase it if your output resembles a postage stamp.
The laser printer prints about 2000 dots across the page.
Images will be printed across the page in rows.

Example:

\small\tt \begin{verbatim}prompt   command                       comments

}        SPLAT thresh,mod,dith/junk    Produces file JUNK.LAY
}        EFTP
EFTP>    t junk.lay b::lp3:j.lay       The .LAY must be present
EFTP>    e
}
\end{verbatim}\rm  \normalsize 
\subsection{UNKNDISP}

Trivial utility for displaying images of unknown format prior to
converting them to IFF. You can try different image heights,
withs, bit order etc.

\subsection{UTILS (the IFF library)}

IFF:UTILS is a suite of routines for handling IFF files painlessly.
They may be called from IMP or PASCAL. INSTALL IFF:UTILS before using them.
then \%Include IFF:IFFINC.IMP or IFF:IFFINC.PAS in your IMP or Pascal program.

\subsubsection{Overview}
Values such as IFF NOT MAGIC, IFF READ etc. are consts predefined for you in
the include file.

All these functions return 0 if successful, non-0 if not.

The intended sequence of events is you do..

\small\tt \begin{verbatim}IFF READIN          to read the file and header in as one operation

IFF WRITEOUT        to write an array of pixels as an IFF file in one operation.

or if you require more control..

IFF OPEN FILE       to open the file and set thing up.

IFF READ HEADER     or  IFF WRITE HEADER

IFF SHOW HEADER     if you want to dump the header information

IFF READ IMAGE      or  IFF WRITE IMAGE

IFF CLOSE FILE      to tidy up afterwards
\end{verbatim}\rm  \normalsize 

\subsubsection{For IMP users - in more detail...}

In the include file IFF:IFFINC.IMP you will find..

\small\tt \begin{verbatim}%constinteger iff not magic=16_81, iff no file=16_82, iff wrong length=16_83,
              iff read=0, iff write=1

%recordformat iffhdr fm(%integer  hlen, datatype, ht, wid, 
signed, fov ht, fov wid, stereo, baseline, vergence, gaze, id, processed,
%integer fstop, focus,
%integer mapaddr, aspect, mapwid, maplen,
%record (context fm) %name context,
%string (255) title,
%string (8) date, time)
\end{verbatim}\rm  \normalsize 
This is a record format which contains the IFF header
in an easily accessible form. The only fields you need be concerned with are
HT (the image height) and WID (the image width) in pixels. The other fields
are explained in the full IFF spec in CS4:IFF.TXT if you are interested.
There are sensible defaults for everything else.


\small\tt \begin{verbatim}%externalintegerfn IFF READIN(%string (255) filename,
%record (iffhdr fm) %name iffh, %integername ad)
\end{verbatim}\rm  \normalsize 
FILENAME is the name of the file to be read in.
The extension .IFF will be assumed unless another extension is given.

If AD is 0, the routine will grab sufficient heap space for the image and return
the start address in AD. If AD is non-0, that address will be used and it is
the caller's responsibility to see that it represents a valid area of sufficient
size.

IFFH will be written with the IFF file header.

\small\tt \begin{verbatim}%externalintegerfn IFF WRITEOUT(%string (255) filename,
%record (iffhdr fm) %name iffh, %integer ad)
\end{verbatim}\rm  \normalsize 
FILENAME is the name of the file to be written out.
The extension .IFF will be appended unless another extension is given.

AD should be the address of the start of the image.
IFFH should be a valid header record. Defaults will be supplied as per
IFF WRITE HEADER.


\small\tt \begin{verbatim}%externalintegerfn IFF OPEN FILE(%string (255) filename, %c
%record (iffhdr fm) %name iffh, %integer readwrite)
\end{verbatim}\rm  \normalsize 
FILENAME is the name of the IFF file to be read or written as above.

if READWRITE = IFF READ

The file is opened for input.
Note that FILENAME is a "root" name. The routine will look for FILENAME.IFF
and will only read from FILENAME if FILENAME.IFF does not exist.
IFFH is a record of type IFFHDR FM (q.v.). \hspace{0.2 in} It will be ZEROED and a pointer
placed in IFFH\_CONTEXT. Do NOT alter this. E.G. don't do an "IFFH = 0" after
calling this.

The function will return 0 if successful, IFF NO FILE if it can't find the file
or IFF NOT MAGIC if the appropriate header bytes do not correspond to the IFF
'magic number'.

if READWRITE = IFF WRITE

Stream 1 is opened for output to FILENAME. Make sure stream 1 is not in
use elsewhere.


\small\tt \begin{verbatim}%externalroutine IFF CLOSE FILE(%record (iffhdr fm) iffh)
\end{verbatim}\rm  \normalsize 
This routine should be called to close access to the file when you are finished
with it. Failure to do so will result in heap space being lost (READ mode)
or stream 1 being left open (WRITE mode).


\small\tt \begin{verbatim}%externalintegerfn IFF READ HEADER(%record (iffhdr fm) %name iffh)
\end{verbatim}\rm  \normalsize 
The header of a previously opened IFF file will be read and the appropriate
fields filled in. If you supply a non-zero IFFH\_MAPADDR it will be taken as
the base address to which the embedded colour map (if present) will be written.
If MAPADDR is left zero, any map will be ignored.


\small\tt \begin{verbatim}%externalintegerfn IFF WRITE HEADER(%record (iffhdr fm) %name iffh)
\end{verbatim}\rm  \normalsize 
This writes the parameters supplied in IFFHDR as an IFF header to a previously
IFF OPENed IFF file.

DATE and TIME default to now.
The header length defaults to the minimum $>$= 128 16-bit words (256 bytes).
Note these values will be written back to IFFHDR.
If IFFH\_MAPADDR is non-zero it will be taken to be a colour map of length
IFFH\_MAPLEN and will be written.


\small\tt \begin{verbatim}%externalroutine IFF SHOW HEADER(%record (iffhdr fm) iffh, %integer detail)
\end{verbatim}\rm  \normalsize 
This displays the values of some of the more useful IFFHDR fields.


\small\tt \begin{verbatim}%externalintegerfn IFF READ IMAGE(%record (iffhdr fm) %name iffh, %c
%integer address)
\end{verbatim}\rm  \normalsize 
This reads an image from a previously IFF OPENED file which has had its
header read. The image will be dumped to an area of store starting at
ADDRESS and will be expanded if IFFHDR\_TYPE indicates it has been run-length
encoded.


\small\tt \begin{verbatim}%externalintegerfn IFF WRITE IMAGE(%record (iffhdr fm) %name iffh,
%integer address)
\end{verbatim}\rm  \normalsize 
writes an image to a file previously IFF OPENed for output and has had a
header written. The image will be read from an area of store starting at
ADDRESS and will be compressed if IFFHDR\_TYPE has the run-length encode bits
set.


\subsubsection{For Pascal users - in more detail}

Note that APM Pascal allows the following extensions (among others)..
Note also that the Pascal routines are updated on request and MAY lag behind
the IMP versions in some instances. See JHB if in doubt.

\small\tt \begin{verbatim}%include 'filename'     inserts the contents of 'filename' in your program.
                        This avoids you having to write out the declarations
                        below.

16_1234                 means hexadecimal 1234. Similarly 8_234, 10_1234 etc.
                        for base 8, 10 etc.   Default is of course 10.

string [n]              is a TYPE approximately equivalent to a
                        packed array [1.n] of char.

cliparam                is a buiilt-in variable of type string [255] and
                        contains the command-line parameters.

addr(n)                 returns the absolute address of n. This is used here
                        to pass the base address of your image array to the
                        external procedures.
\end{verbatim}\rm  \normalsize 
There is an example program in IFF:IFFDEMO.PAS.

In the include file IFF:IFFINC.PAS you will find..

\small\tt \begin{verbatim}const iff_not_magic=16_81;
      iff_no_file = 16_82;
      iff_wrong_length = 16_83;
      iff_read=0;
      iff_write=1;

type  iffhdr_fm = record
      hlen, datatype, ht, wid, signed, fov_ht, fov_wid, stereo, 
      baseline, vergence, gaze, id, processed: integer;
      fstop, focus:integer;
      mapaddr, aspect, mapwid, maplen, context:integer;
      title: string [255];
      date, time: string[8];
end;
\end{verbatim}\rm  \normalsize 
Iffhdr\_fm is an enumerated type which contains the IFF header
in an easily accessible form. The only fields you need be concerned with are
HT (the image height) and WID (the image width) in pixels. The other fields
are explained in the full IFF spec elsewhere in this file if you are interested.
There are sensible defaults for everything else.


\small\tt \begin{verbatim}function IFF_OPEN_FILE(
filename: string[255]; var iffh:iffhdr_fm; readwrite:integer):integer; extern;
\end{verbatim}\rm  \normalsize 
FILENAME is the name of the IFF file to be read or written.

if READWRITE = IFF\_READ

The file is opened for input.
Note that FILENAME is a root name. The routine will look for FILENAME.IFF
and will only read from FILENAME if FILENAME.IFF does not exist.
IFFH is a record of type IFFHDR\_ (q.v.). \hspace{0.2 in} It will be ZEROED and a pointer
placed in IFFH.CONTEXT. Do NOT alter this. E.G. don't do an "IFFH := 0" after
calling this.

The function will return 0 if successful, IFF\_NO\_FILE if it can't find the file
or IFF\_NOT\_MAGIC if the appropriate header bytes do not correspond to the IFF
'magic number'.

if READWRITE = IFF\_WRITE

(IMP) Stream 1 is opened for output to FILENAME. Make sure stream 1 is not in
use elsewhere. \hspace{0.2 in} In practice it is safest to close the IFF file you are reading
before opening one for writing.


\small\tt \begin{verbatim}procedure IFF_CLOSE_FILE(var iffh:iffhdr_fm); extern;
\end{verbatim}\rm  \normalsize 
This routine should be called to close access to the file when you are finished
with it. Failure to do so will result in heap space being lost (READ mode)
or stream 1 being left open (WRITE mode).


\small\tt \begin{verbatim}function IFF_READ_HEADER(var iffh:iffhdr_fm):integer; extern;
\end{verbatim}\rm  \normalsize 
The header of a previously opened IFF file will be read and the appropriate
fields filled in. If you supply a non-zero IFFH.MAPADDR it will be taken as
the base address to which the embedded colour map (if present) will be written.
If MAPADDR is left zero, any map will be ignored.


\small\tt \begin{verbatim}function IFF_WRITE_HEADER(var iffh:iffhdr_fm):integer; extern;
\end{verbatim}\rm  \normalsize 
This writes the parameters supplied in IFFHDR as an IFF header to a previously
IFF OPENed IFF file.

DATE and TIME default to now.
The header length defaults to the minimum $>$= 128 16-bit words (256 bytes).
Note these values will be written back to IFFHDR.
If IFFH.MAPADDR is non-zero it will be taken to be a colour map of length
IFFH.MAPLEN and will be written.


\small\tt \begin{verbatim}procedure IFF_SHOW_HEADER(iffh:iffhdr_fm; detail:integer); extern;
\end{verbatim}\rm  \normalsize 
This displays the values of some of the more useful IFFHDR fields.


\small\tt \begin{verbatim}function IFF_READ_IMAGE(var iffh: iffhdr_fm; address:integer):integer; extern;
\end{verbatim}\rm  \normalsize 
This reads an image from a previously IFF\_OPENED file which has had its
header read. The image will be dumped to an area of store starting at
ADDRESS and will be expanded if IFFHDR.TYPE indicates it has been run-length
encoded.


\small\tt \begin{verbatim}function IFF_WRITE_IMAGE(var iffh: iffhdr_fm; address:integer):integer; extern;
\end{verbatim}\rm  \normalsize 
writes an image to a file previously IFF OPENed for output and has had a
header written. The image will be read from an area of store starting at
ADDRESS and will be compressed if IFFHDR.TYPE has the run-length encode bits
set.



\subsection{UTILS.DOC}

This documentation file

\subsection{CAMERA:TRANS}

Monolithic program for grabbing images from the SEESCAN camera
via Brian Craigie's fast interface. It's menu driven and fairly
self-explanatory - beware of Brian's interface though - it's
a bit iffy sometimes.


\section{Image File Format for Alvey Vision Consortium 2}

\hspace*{0.2 in} Working Version 14.5.85 by C. R. Brown.
\\ \hspace*{0.2 in} Derived from 2nd Draft 12.9.84 by A Blake.
\\ \hspace*{0.2 in} Incorporates J.H. Butler extensions up to 30.3.87
\\ \hspace*{0.2 in} Incorporates C.N. Duncan extensions up to 10.2.87
\\ \hspace*{0.2 in} JHB extension 20.11.87 - transform parameters J9 \& J10

The following specifies a file format (called IFF) for images.
It is meant to be comprehensive without being unduly pedantic,
and to cater for projected needs of stereo image interpretation.
Images may be mono or stereo, produced by a camera or by an
image synthesizer or other process. The image consists of a
header followed by data. Here is the structure of the file as
a sequence of fields:


\small\tt \begin{verbatim}    Field            Allowed          Meaning                         See
no off.  name        values                                           note

 1    0  header_length 0..32000         Length of header in 16-bit words  1
 2    2  image_type    BYTE/WORD/       image type                      2,3
                       BOOLEAN
 3    4  height        0..32000         image height (pixels)
 4    6  width         0..32000         image width  (pixels)
 5    8  signed        TRUE/FALSE       signed/unsigned data
 6   10  fov_height    0..32000         field of view height (mrad)       4
 7   12  fov_width     0..32000         field of view width (mrad)        4
 8   14  stereo        TRUE/FALSE       stereo pair/mono image
 9   16  baseline      0..32000         optical centres separation (mm)   4
 10  18  vergence      -1571..1571      vergence angle (mrad)             4
 11  20  gaze          -1571..1571      gaze angle (mrad)                 4
 12  22  source_id     0..32000         i.d. of camera or synthesizer     5
 13  24  processed     TRUE/FALSE       true if image not directly from   5
                                        source - i.e. processed since.
 14  26  date          STRING           date of generation (dd/mm/yy)     6
 15  34  time          STRING           time of generation (hh:mm:ss)     6
 16  42  stop          0..32000         lens stop (f no. x 100)
 17  44  focus         0..32000         lens focal length (mm)
 18  46  magic         8516 hex         magic number                      7
 19  48  title         STRING           image title                       8
\end{verbatim}\rm  \normalsize (unspecified bytes, to fill remainder of header block)

[JHB extension: application-dependant fields start from 400]

[CND: application=1 (satellite images) working upwards...]

These fields are valid for a source id of 10287:

\small\tt \begin{verbatim}C1  400  satellite     0..32000         Satellite identifier             12
C2  402  instrument    0..32000         Instrument identifier            13
C3  304  channel       0..32000         Channel identifier               14
C4  408  data type     0..32000         level of data processing         15
C5  410  fp_year       0..32000         first pixel date (year)
C6  412  fp_month      0..32000         first pixel date (month)
C7  414  fp_day        0..32000         first pixel date (day)
C8  416  fp_hour       0..23            first pixel time (hour)
C9  418  fp_min        0..59            first pixel time (minute)
C10 420  fp_sec        0..59            first pixel time (second)
C11 422  fp_msec       0..999           first pixel time (millisecond)
C12 424  scan_dir      BOOLEAN          scan direction                   16
C13 426  proj          0..32000         mapping projection               17
\end{verbatim}\rm  \normalsize 
[JHB: application=2 (GALLERY program) working upwards]

\small\tt \begin{verbatim}C1  400  window x_l    0..32000         left margin of text window
C2  402  window x_r    0..32000         right margin of text window
C3  404  window y_t    0..32000         top edge of text window
                                        Text follows on after title, eot=ascii 0
\end{verbatim}\rm  \normalsize 
[JHB extensions, working downwards]

\small\tt \begin{verbatim}J10 492  Transform m   -32768..32767    When PROCESSED # 0 these fields give
J9  494  Transform c   -32768..32767    a linear transformation y = Mx + C
                                        where x is the pixel value in the file
                                        and y is the original data value.
                                        C is the offset
                                        M is the scale factor * 256      18
J8  496  application   0..32000         Application number of 
                                        application dependant fields
J7  498  image_sets    0..32000         No of image sets
J6  500  subheader     TRUE/FALSE       Image subheaders are being used  10
J5  502  x offset      0..32000         image x offset from origin       11
J4  504  y offset      0..32000         ditto y
J3  506  aspect        0..32000         aspect ratio: two bytes, 0..127   9
J2  508  map width     0..32000         colour map entry width in bits   18
J1  510  map len       0..32000         colour map length in 16-bit words
\end{verbatim}\rm  \normalsize 
[end]

\small\tt \begin{verbatim}20       data_left                      image - left half if stereo       3
21       data_right                     right image (stereo only)         3
\end{verbatim}\rm  \normalsize 
[JHB extension]

\small\tt \begin{verbatim}22     data_2 ...                       further images in the image set
\end{verbatim}\rm  \normalsize 
[end]

NOTES

\small\tt \begin{verbatim} 1  The header will usually be 256 words (512 bytes) long.
    [JHB] If a colour map is present, the header is 256 words (512 bytes)
    + colour map length long.  Header length includes colour map length.

 2  The header fields (except those marked 'STRING') consist of
    16-bit integers representing coded types or integer values.
    An integer value normally lies in the range -32000..32000 but
    may have the special value UNKNOWN (32767).
    Fields 1-4 must NOT be UNKNOWN. Coded values are:

       BYTE:           0    TRUE:           1
       16-bit WORD:    1    FALSE:          0
       BOOLEAN:        2
[JHB]  24-bit WORD:    3
[JHB]  32-bit WORD:    4
[JHB]  Reserved for 32-bit APM IMP format REAL:    5

    Other types (in addition to BYTE/WORD/BOOLEAN) may be defined
    for other formats.

    [JHB] The top two bits of the image type field indicate a data compression
    algorithm if one is used.

       NO COMPRESSION:           00
       RUN-LENGTH COMPRESSION A: C0

    Run-length encoding A (defined for BYTE images only just now) is...
    <char> {<repeat>}   repeated indefinitely.
    The repeat field is only used if the repeat count >= 4
    <char> = 0  encodes as 0, 0
    <char> = 10 encodes as 0, 1
    e.o.f.      encoded as 0, 3
    <repeat>    encoded as 0, <count>               where 4 <= <count> <= 127
                or         0, <count>>8> ! 128, <count>&255
                                                    where 0 <= <count> <= 32767

    Reason for twiddles is to make it insensitive to inserted newlines.
    Note if newlines are a problem, counts must be arranged to avoid 10 in the
    LSB.       Header is uncompressed.

    Examples (hope I've got this right):

    1 2 3 4 5 5 5 5   encodes as 1 2 3 4 5 0 4     short repeat count of 4
    0 1 2 3 4 5       encodes as 0 0 1 2 3 4 5     encode 0 as 0,0
    5 6 7 8 9 10      encodes as 5 6 7 8 9 0 1     encode 10 as 0,1
    5...(200 times)   encodes as 5 0 128 200       long repeat count of 200
    7...(515 times)   encodes as 7 0 130 3         long repeat count of 16_203
    0...(32767 times) encodes as 0 0 0 255 255     max possible repeat (of 0's)

 3  The data for an image consists simply of a sequence of bits,
    bytes or 16-bit words representing the values of pixels in raster scan
    order; that is, scanning from left to right then top to bottom.
    BOOLEAN images occupy one bit per pixel, packed into bytes,
    least significant bit first. WORD images occupy 2 bytes per
    pixel, stored as LS byte then MS byte.

 4  Viewing Geometry parameters are defined in the accompanying figures.

 5  If the image has been through a subsequent process since capture
    the original camera i.d. and date/time are retained, but the
    processed flag is set. An image synthesizer program also has a
    source i.d., each and every executable version of the
    synthesizer having a unique i.d..

 6  Date and time are stored as strings of 8 consecutive bytes
    DD/MM/YY and HH:MM:SS.  These strings are not null-terminated.

 7  The magic field should always have the value 8516 hex. Programs
    may use this field to determine (a) that the file they are
    reading is really in IFF format, and (b) whether the file needs
    byte reversing to suit the local processor. This is intended to
    apply only to the header; byte ordering for the images is
    defined above.

 8  The title field is a null terminated text title up to 80 characters long.

[JHB]
 9  The aspect ratio is a pair of bytes (0..127).  These give the width:height
    ratio of the pixels on the imaging device. (width = MSB).  0 = 1:1

10  Image subheaders
    Multiple images may be written to the file.  In the simplest case where all
    images have the same attributes, no subheader is required and the images are
    simply concatenated to a limit defined by IMAGE_SETS. (0 is equivalent to 1)
    If their attributes differ (e.g. they have different sizes) then
    subheaders will be required.  These are identical to the main header except
    that they may be any length.  Subheader fields will take precedence
    over header fields.  Fields not included in the subheaders take defaults
    from the header.   Note the first subheader will follow immediately after
    the header and will not be included in the header length.
    Images within the same image set all have the same attributes.

11  Image grey levels be assumed to match the map length if specified. Thus an
    image comprising two grey levels per byte could have pixel values 0 and 1
    and expect to be displayed correctly if the map length was 2.
\end{verbatim}\rm  \normalsize 
[CND]

The tables of values shown here are identical to those used by British Antarctic
Survey, the Meteorological Office and others. They will therefore offer a high
degree of compatibility for software transfer if they are adhered to.

\small\tt \begin{verbatim}12 The satellite ID is composed of a 'hundreds' figure indicating the
   satellite series  name and a 'tens and units' figure indicating the
   particular satellite within the series. (eg 109 for NOAA9)
   NOAA          1         6-10
   METEOSAT      2         1-2
   GOES (E)      3
   GOES (W)      4
   GMS           5         1-3
   METEOR        6
   LANDSAT       7         1-5
   SEASAT        8         1
   ERS           9         1
   SPOT         10         1
   NIMBUS       11         1-7
 
13 Instrument IDs refer to the separate instruments on board each satellite
   NOAA      AVHRR      1
             TOVS       2
   METEOSAT  IMAGING    1
   GOES (E)  IMAGING    1
             VAS        2
   GOES (W)  IMAGING    1
             VAS        2
   GMS       IMAGING    1
   METEOR    IMAGING    1
   LANDSAT   MSS        1
             TM         2
   SEASAT    SAR        1
             VIS/IR     2
             SMMR       3
   ERS       SAR/WAVE   1
             WIND AMI   2
             ATSR       3
   SPOT      IMAGERY    1
   NIMBUS    CSCZ       1
             SMMR       2

14 The channel IDs are the numbers usually used to refer to individual
   instrument channels (eg channels 1-5 on NOAA AVHRR, and 4-7 on LANDSAT MSS)

15 Data type refers to the level of processing applied to the data.
   Original instrument counts                            0
   Calibrated measurement (eg brightness temps)          1
   Corrected measurements (eg radiance corr for atten)   2
   Prime Geophysical products (eg surface temperature)   3
   Secondary Geophysical products (eg integ. rainfall)   4

16 Scan direction in which image was acquired. Only the two LSB are significant.
   bit 0  clear   S->N     set    N->S
   bit 1  clear   W->E     set    E->W

17 Image projections will take one of the following values:
   Original view from space         0
   Polar stereographic              1
   Mercator                         2
   Linear (lat/long)                3
   National Grid                    4

18 Transformation is for use where an image of integer values 0..255 or
   0..65535 was created from an array of (say) reals of value between ymin
   and ymax.  These fields enable the original data to be reconstructed in
   most cases.   M is scaled * 256 so scales of betwen "divide by +/- 256"
   to "multiply by +/- 128" can be accomodated.

   First: transform a real range ymin..ymax into an integer range xmin..xmax
   using x = M'y + C'  where..

         xmax - xmin                      xmin * ymax - xmax * ymin
   M' =  -----------                C' =  -------------------------
         ymax - ymin                             ymax - ymin

   Then the reverse transformation from integers xmin..xmax to reals ymin..ymax
   using y = Mx + C  is..

         ymax - ymin        and           ymin * xmax - ymax * xmin
   M  =  -----------                C  =  -------------------------
         xmax - xmin                             ymax - ymin

   i.e.  M = 1/M'  and   C = - C'
   It is this M and C which are stored in J9 and J10
\end{verbatim}\rm  \normalsize 
Subsequent changes to the header must be compatible with this
specification - i.e., extra fields may be added to the end of
the header but the existing fields should not change.


\section{UNIX-BASED SOFTWARE SUPPORT FOR NON-EXTENDED IFF HANDLING}

It is the policy of this site that all programs which deal with
images stored in files should accept and/or produce IFF files,
providing this is appropriate for the type of data being stored.
Software support for this is provided at several levels.

The file /usr/include/image/iff.h defines a C structure for the
IFF header and defines the coded values used therein.

The library file /usr/lib/libiff.a contains the routines
make\_header, read\_header, and write\_header which do most of the
work of creating, reading and writing iff headers. These are
documented in iff(3). To load them, use the flag -liff on your
cc command line.

The program /usr/bin/iffshow converts the header of an iff file into a
readable text form, or vice versa. This may be used simply to
display the header, or to produce a text file for manual editing
and subsequent conversion back to an iff header.
This is documented in iffshow(1).

The shell script /usr/bin/iffedit provides a convenient way to
manually edit an iff header. It invokes iffshow to convert the
header to text format, passes this to vi for editing, then
passes the result back to iffshow to re-write the modified
header. Usage is simply:

iffedit IFFfilename

\vspace{.75in} iff:utils.doc printed on 16/02/89 at 21.28

\newpage
\tableofcontents
\end{document}
