\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... {} repeated indefinitely. The repeat field is only used if the repeat count >= 4 = 0 encodes as 0, 0 = 10 encodes as 0, 1 e.o.f. encoded as 0, 3 encoded as 0, where 4 <= <= 127 or 0, >8> ! 128, &255 where 0 <= <= 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}