@DATABASE Devices Manual
@NODE MAIN " Appendix A  / EA IFF 85 - General IFF Format Specifications"
@INDEX Dev_Index/MAIN
@TOC Dev_A/MAIN

@{" A Quick Introduction to IFF " link 16-1}
@{" EA IFF 85: Standard for Interchange Format Files " link 16-2}

@ENDNODE


@NODE 16-1 "General IFF Format Specifications / A Quick Introduction to IFF "
Jerry Morrison, Electronic Arts
10-17-88

IFF is the Amiga-standard "Interchange File Format", designed to work
across many machines.

@{" Why IFF? " link 16-1-1}                             @{" How to read an IFF file " link 16-1-5}
@{" What is IFF? " link 16-1-2}                         @{" File extensibility " link 16-1-6}
@{" What is the Trick? " link 16-1-3}                   @{" Advanced Topics " link 16-1-7}
@{" What does an IFF file look like? " link 16-1-4}

@ENDNODE


@NODE 16-1-1 " A Quick Introduction to IFF / Why IFF?"
Did you ever have this happen to your picture file?

   You can't load it into another paint program.
   You need a converter to adopt to "ZooPaint" release 2.0 or a new
    hardware feature.
   You must "export" and "import" to use it in a page layout program.
   You can't move it to another brand of computer.

What about interchanging musical scores, digitized audio, and other data?
It seems the only thing that does interchange well is plain ASCII text
files.

It's inexcusable. And yet this is "normal" in MS-DOS.

@ENDNODE


@NODE 16-1-2 " A Quick Introduction to IFF / What is IFF?"
IFF, the "Interchange File Format" standard, encourages multimedia
interchange between different programs and different computers.  It
supports long-lived, extensible data.  It's great for composite files like
a page layout file that includes photos, an animation file that includes
music, and a library of sound effects.

IFF is a 2-level standard.  The first layer is the "wrapper" or "envelope"
structure for all IFF files.  Technically, it's the syntax.  The second
layer defines particular IFF file types such as @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1} (standard raster
pictures), ANIM (animation), @{"SMUS" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_SMUS/16-5-1} (simple musical score), and @{"8SVX" link ADCD_v1.2:Reference_Library/Devices/DEV_A_FS_8SVX/16-6-1} (8-bit
sampled audio voice).

IFF is also a design idea: programs should use interchange formats for
their everyday storage.

This way, users rarely need converters and import/export commands to
change software releases, application programs, or hardware.

@ENDNODE


@NODE 16-1-3 " A Quick Introduction to IFF / What is the trick? "
File compatibility is easy to achieve if programmers let go of one
notion - dumping internal data structures to disk.  A program's internal
data structures should really be suited to what the program does and how
it works.  What's "best" changes as the program evolves new functions and
methods.  But a disk format should be suited to storage and interchange.

Once we design internal formats and disk formats for their own separate
purposes, the rest is easy.  Reading and writing become behind-the-scenes
conversions.  But two conversions hidden in each program is much better
than a pile of conversion programs.

Does this seem strange?  It's what ASCII text programs do!  Text editors
use line tables, piece tables, gaps, and other structures for fast editing
and searching.  Text generators and consumers construct and parse files.
That's why the ASCII standard works so well.

Also, every file must be self-sufficient.  E.g., a picture file has to
include its size and number of bits/pixel.

@ENDNODE


@NODE 16-1-4 " A Quick Introduction to IFF / What does an IFF file look like?"
IFF is based on data blocks called "chunk"s. Here's an example color map
chunk:

                         +------------------+ in an ILBM file, CMAP means
          char typeID[4] | "CMAP"           | "color map"
                         |------------------+
  unsigned long dataSize |  48              | 48 data bytes
                         |------------------+
             char data[] |  0,0,0,255,      | 16 3-byte color values:
                         |  255,255,255...  | black, white, ....
                         +------------------+

                         +------------------+ in an ILBM file, CMAP means
                         | "CMAP"           | "color map"
                         |------------------+
                         |  48              | 48 data bytes
                         |------------------+
                         |  0,0,0,255,      | 16 3-byte color values:
                         |  255,255,255...  | black, white, ....
                         +------------------+

A chunk is made of a 4-character type identifier, a 32 bit data byte
count, and the data bytes. It's like a Macintosh "resource" with a 32-bit
size.

Fine points:

 o Every 16- and 32-bit number is stored in 68000 byte order - highest
    byte first.

   An Intel CPU must reverse the 2- or 4-byte sequence of each number.
   This applies to chunk dataSize fields and to numbers inside chunk
   data.  It does not affect character strings and byte data because you
   can't reverse a 1-byte sequence.  But it does affect the 32-bit math
   used in IFF's MakeID macro.  The standard does allow CPU specific byte
   ordering hidden within a chunk itself, but the practice is discouraged.

 o Every 16- and 32-bit number is stored on an even address.

 o Every odd-length chunk must be followed by a 0 pad byte.  This pad
    byte is not counted in dataSize.

 o An ID is made of 4 ASCII characters in the range " " (space, hex 20)
    through "~" (tilde, hex 7E).  Leading spaces are not permitted.

 o IDs are compared using a quick 32-bit equality test.  Case matters.

A chunk typically holds a C structure, Pascal record, or an array.  For
example, an @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1} picture has a @{"BMHD" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-1} bitmap header chunk (a structure)
and a @{"BODY" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-3-2} raster body chunk (an array).

To construct an IFF file, just put a file type ID (like @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}) into a
wrapper chunk called a "FORM" (Think "FILE").  Inside that wrapper place
chunks one after another (with pad bytes as needed).  The chunk size
always tells you how many more bytes you need to skip over to get to the
next chunk.

	          +------------------+
	          |                  |
	          |  "FORM"          |  FORM is a special chunk ID
	          |                  |
	          +------------------+
	          |   24070          |  24070 data bytes
	       -- +------------------+
	       |  |                  |
	       |  |  "ILBM"          |  FORM type is ILBM
	       |  |                  |
	       |  | +--------------+ |
	       |  | |  "BMHD"      | |  A BMHD bitmap header chunk
	       |  | |--------------| |  (20 data bytes)
	       |  | |   20         | |
	       |  | |--------------| |
	       |  | |  320, 200,   | |
	       |  | |  0 ....      | |
	       |  | +--------------+ |
	       |  |                  |
	       |  | +--------------+ |
	       |  | |  "CMAP"      | |  A CMAP color map chunk
	24070 <   | |--------------| |  (21 data bytes = 1 pad)
	bytes  |  | |   21         | |
	       |  | |--------------| |
	       |  | |  0, 0, 0,    | |
	       |  | |  255 ....    | |
	       |  | +--------------+ |
	       |  |   0              |  A pad byte
	       |  | +--------------+ |
	       |  | |  "BODY"      | |
	       |  | |--------------| |  A BODY raster body chunk
	       |  | |  24000       | |  (24000 data bytes)
	       |  | |--------------| |
	       |  | |  0, 0, 0.... | |
	       |  | +--------------+ |
	       -- +------------------+

A FORM always contains one 4-character FORM type ID (a file type, in this
case "@{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}") followed by any number of data chunk.  In this example, the
FORM type is "ILBM", which stands for "InterLeaved BitMap".  (@{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1} is an
IFF standard for bitplane raster pictures.)  This example has 3 chunks.
Note the pad byte after the odd length chunk.

Within FORMs @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}, @{"BMHD" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-1} identifies a bitmap header chunk, @{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2} a color
map, and @{"BODY" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-3-2} a raster body.  In general, the chunk IDs in a FORM are
local to the FORM type ID.  The  exceptions are the 4 global chunk IDs
"FORM", @{"LIST" link 16-1-7 49}, @{"CAT" link link 16-1-7 2} , and @{"PROP" link 16-1-7 49}.  (A FORM may contain other FORM
chunks.  E.g., an animation FORM might contain picture FORMs and sound
FORMs.)

@ENDNODE


@NODE 16-1-5 " A Quick Introduction to IFF / How to read an IFF file?"
Example code and modules are provided for reading IFF files using
iffparse.library. However, if you wish to read a non-complex FORM by hand,
the following logic can be used.

Once you have entered the @{"FORM" link 16-1-4 52} (for example, the FORM @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1} shown above),
stored the FORM length (24070 in the ILBM example) and are positioned on
the first @{"chunk" link 16-1-4}, you may:

Loop: (Until end-of-file or end-of-form)

        - Read the 4-character identifier of the chunk
        - Read the 32-bit (4 byte) chunklength
        - Decide if you want that chunk
              if yes, read chunklength bytes into destination
              structure or buffer
              if no, seek forward chunklength bytes
        - If chunklength is odd, seek one more byte.

Every IFF file is a @{"FORM" link 16-1-4 52}, @{"LIST" link 16-1-7 49}, or @{"CAT" link link 16-1-7 2} chunk.  You can recognize an
IFF file by those first 4 bytes.  ("FORM" is far and away the most common.
We'll get to LIST and CAT below.)  If the file contains a FORM, dispatch
on the FORM type ID to a chunk-reader loop like the one above.

@ENDNODE


@NODE 16-1-6 " A Quick Introduction to IFF / File extensibility"
IFF files are extensible and forward/backward compatible:

  o Chunk contents should be designed for compatibility across
     environments and for longevity.  Every chunk should have a path for
     future expansion; at minimum this will be an unused bit or two.

  o The standards team for a @{"FORM" link 16-1-4 52} type can extend one of the chunks that
     contains a structure by appending new, optional structure fields.

  o Anyone can define new @{"FORM" link 16-1-4 52} types as well as new chunk types within a
     FORM type.  Storing private chunks within a FORM is OK, but be sure
     to register your activities with Commodore Applications and Technical
     Support.

  o A chunk can be superseded by a new chunk type, e.g., to store more
     bits per RGB color register. New programs can output the old chunk
     (for backward compatibility) along with the new chunk.

  o If you must change data in an incompatible way, change the chunk ID or
     the @{"FORM" link 16-1-4 52} type ID.

@ENDNODE


@NODE 16-1-7 " A Quick Introduction to IFF/ Advanced Topics"
CAT, LIST, and PROP

Sometimes you want to put several "files" into one, such as a picture
library. This is what CAT is for.  It "concatenates" FORM and LIST chunks.

          +--------------------+
          |                    |
          |   "CAT "           |  concatenation
          |                    |
          +--------------------+
          |   48160            |  48160 data bytes
          +--------------------+
          |                    |
          |   "ILBM"           |  This concatenation contains FORMs ILBM
          |                    |
          |  +--------------+  |
          |  |  "FORM"      |  |  A FORM ILBM
          |  |--------------|  |
          |  |   24070      |  |
          |  |--------------|  |
          |  |  "ILBM"      |  |
          |  |--------------|  |
          |  |  ....        |  |
          |  +--------------+  |
          |                    |
          |  +--------------+  |
          |  |  "FORM"      |  |  Another FORM ILBM
          |  |--------------|  |
          |  |   24070      |  |
          |  |--------------|  |
          |  |  "ILBM"      |  |
          |  |--------------|  |
          |  |  ....        |  |
          |  +--------------+  |
          |                    |
          +--------------------+

This example CAT holds two ILBMs. It can be shown outline-style:

  CAT ILBM
  ..FORM ILBM   \
  ....BMHD      | a complete FORM ILBM picture
  ....CMAP      |
  ....BODY      /
  ..FORM ILBM
  ....BMHD
  ....CMAP
  ....BODY

Sometimes you want to share the same color map across many pictures. LIST
and PROP do this:

  LIST ILBM
  ..PROP ILBM   default properties for FORMs ILBM
  ....CMAP      an ILBM CMAP chunk (there could be a BMHD chunk here, too)
  ..FORM ILBM
  ....BMHD      (there could be a CMAP here to override the default)
  ....BODY
  ..FORM ILBM
  ....BMHD      (there could be a CMAP here to override the default)
	....BODY

A LIST holds PROPs and @{"FORM" link 16-1-4 52}s (and occasionally LISTs and CATs).  A PROP
@{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1} contains default data (in the above example, just one @{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2} chunk) for
all FORMs ILBM in the LIST.  Any FORM may override the PROP-defined
default with its own @{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}.  All PROPs must appear at the beginning of a
LIST.  Each FORM type standardizes (among other things) which of its
chunks are "property chunks" (may appear in PROPs) and which are "data
chunks" (may not appear in PROPs).

@ENDNODE

@NODE 16-2 " Appendix A / EA IFF 85: Standard for Interchange Format Files"
Document Date:	January 14, 1985  (Updated Oct, 1988 Commodore-Amiga, Inc.)
From:		Jerry Morrison, Electronic Arts
Status:		Released to the public domain, and in use

@{" Introduction " link 16-2-1}                 @{" LISTs, CATs and Shared Property " link 16-2-5}
@{" Background for Designers " link 16-2-2}     @{" Standard File Structure " link 16-2-6}
@{" Primitive Data Types " link 16-2-3}         @{" Standards Committee " link 16-2-7}
@{" Data Sections " link 16-2-4}                @{" Appendix A. Reference " link 16-2-8}

@ENDNODE


@NODE 16-2-1 "EA IFF 85: Standard for Interchange Format Files / Introduction"

@{" Standards are Good for Software Developers " link 16-2-1-1}
@{" Standards are Good for Software Users " link 16-2-1-2}
@{" Here is EA IFF 1985 " link 16-2-1-3}
@{" References " link 16-2-1-4}

@ENDNODE


@NODE 16-2-1-1 "A / Introduction / Standards are Good for Software Developers"
As home computer hardware evolves into better and better media machines,
the demand increases for higher quality, more detailed data.  Data
development gets more expensive, requires more expertise and better tools,
and has to be shared across projects.  Think about several ports of a
product on one CD-ROM with 500M Bytes of common data!

Development tools need standard interchange file formats.  Imagine
scanning in images of "player" shapes, transferring them to an image
enhancement package, moving them to a paint program for touch up, then
incorporating them into a game.  Or writing a theme song with a Macintosh
score editor and incorporating it into an Amiga game.  The data must at
times be transformed, clipped, filled out, and moved across machine kinds.
Media projects will depend on data transfer from graphic, music, sound
effect, animation, and script tools.

@ENDNODE


@NODE 16-2-1-2 "A / Introduction / Standards are Good for Software Users"
Customers should be able to move their own data between independently
developed software products.  And they should be able to buy data
libraries usable across many such products.  The types of data objects to
exchange are open-ended and include plain and formatted text, raster and
structured graphics, fonts, music, sound effects, musical instrument
descriptions, and animation.

The problem with expedient file formats - typically memory dumps is that
they're too provincial.  By designing data for one particular use (such as
a screen snapshot), they preclude future expansion (would you like a full
page picture?  a multi-page document?).  In neglecting the possibility
that other programs might read their data, they fail to save contextual
information (how many bit planes?  what resolution?).  Ignoring that other
programs might create such files, they're intolerant of extra data (a
different picture editor may want to save a texture palette with the
image), missing data (such as no color map), or minor variations (perhaps
a smaller image).  In practice, a filed representation should rarely
mirror an in-memory representation.  The former should be designed for
longevity; the latter to optimize the manipulations of a particular
program.  The same filed data will be read into different memory formats
by different programs.

The IFF philosophy: "A little behind-the-scenes conversion when programs
read and write files is far better than NxM explicit conversion utilities
for highly specialized formats".

So we need some standardization for data interchange among development
tools and products.  The more developers that adopt a standard, the better
for all of us and our customers.

@ENDNODE


@NODE 16-2-1-3 "A / Introduction / Here is EA IFF 1985 "
Here is our offering: Electronic Arts' IFF standard for Interchange File
Format.  The full name is "EA IFF 1985".  Alternatives and justifications
are included for certain choices.  Public domain subroutine packages and
utility programs are available to make it easy to write and use
IFF-compatible programs.

Part 1 introduces the standard.  Part 2 presents its requirements and
background.  Parts 3, 4, and 5 define the primitive data types, FORMs, and
LISTs, respectively, and how to define new high level types.  Part 6
specifies the top level file structure.  Section 7 lists names of the
group responsible for this standard.  Appendix A is included for quick
reference and Appendix B.

@ENDNODE


@NODE 16-2-1-4 "A / Introduction / References "
American National Standard Additional Control Codes for Use with ASCII, ANSI
standard 3.64-1979 for an 8-bit character set.  See also ISO standard 2022
and ISO/DIS standard 6429.2.

The C Programming Language, Brian W. Kernighan and Dennis M. Ritchie, Bell
Laboratories.  Prentice-Hall, Englewood Cliffs, NJ, 1978.

C, A Reference Manual, Samuel P. Harbison and Guy L. Steele Jr., Tartan
Laboratories.  Prentice-Hall, Englewood Cliffs, NJ, 1984.

Compiler Construction, An Advanced Course, edited by F. L. Bauer and J.
Eickel (Springer-Verlag, 1976).  This book is one of many sources for
information on recursive descent parsing.

DIF Technical Specification (c) 1981 by Software Arts, Inc.  DIF(tm) is
the format for spreadsheet data interchange developed by Software Arts,
Inc. DIF(tm) is a trademark of Software Arts, Inc.

"FTXT" IFF Formatted Text, from Electronic Arts.  IFF supplement document
for a text format.

"ILBM" IFF Interleaved Bitmap, from Electronic Arts.  IFF supplement
document for a raster image format.

M68000 16/32-Bit Microprocessor Programmer's Reference Manual (c) 1984,
1982, 1980, 1979 by Motorola, Inc.

PostScript Language Manual (c) 1984 Adobe Systems Incorporated.
PostScript(tm) is a trademark of Adobe Systems, Inc. Times and Helvetica
are registered trademarks of Allied Corporation.

Inside Macintosh (c) 1982, 1983, 1984, 1985 Apple Computer, Inc., a
programmer's reference manual. Apple is a trademark of Apple Computer,
Inc. MacPaint(tm) is a trademark of Apple Computer, Inc. Macintosh(tm) is
a trademark licensed to Apple Computer, Inc.

InterScript: A Proposal for a Standard for the Interchange of Editable
Documents (c) 1984 Xerox Corporation.  Introduction to InterScript (c)
1985 Xerox Corporation.

Amiga is a registered trademark of Commodore-Amiga, Inc.

Electronics Arts(tm) is a trademark of Electronic Arts.

@ENDNODE


@NODE 16-2-2 "A / EA IFF 85:Standard for Interchange Format Files / Design Background "
Part 2 is about the background, requirements, and goals for the standard.
It's geared for people who want to design new types of IFF objects. People
just interested in using the standard may wish to quickly scan this
section.

@{" What Do We Need? " link 16-2-2-1}   @{" Data Abstraction " link 16-2-2-4}
@{" Think Ahead " link 16-2-2-2}        @{" Previous Work " link 16-2-2-5}
@{" Scope " link 16-2-2-3}

@ENDNODE


@Node 16-2-2-1 "Background for Designers / What Do We Need? "
A standard should be long on prescription and short on overhead.  It
should give lots of rules for designing programs and data files for
synergy.  But neither the programs nor the files should cost too much more
than the expedient variety.  Although we are looking to a future with
CD-ROMs and perpendicular recording, the standard must work well on floppy
disks.

For program portability, simplicity, and efficiency, formats should be
designed with more than one implementation style in mind.  It ought to be
possible to read one of many objects in a file without scanning all the
preceding data.   (In practice, pure stream I/O is adequate although
random access makes it easier to write files.)  Some programs need to read
and play out their data in real time, so we need good compromises between
generality and efficiency.

As much as we need standards, they can't hold up product schedules.  So we
also need a kind of decentralized extensibility where any software
developer can define and refine new object types without some "standards
authority" in the loop.  Developers must be able to extend existing
formats in a forward- and backward-compatible way.  A central repository
for design information and example programs can help us take full
advantage of the standard.

For convenience, data formats should heed the restrictions of various
processors and environments.  For example, word-alignment greatly helps
68000 access at insignificant cost to 8088 programs.

Other goals include the ability to share common elements over a list of
objects and the ability to construct composite objects.

And finally, "Simple things should be simple and complex things should be
possible" - Alan Kay.

@ENDNODE


@Node 16-2-2-2 "Background for Designers / Think Ahead "
Let's think ahead and build programs that read and write files for each
other and for programs yet to be designed.  Build data formats to last for
future computers so long as the overhead is acceptable.  This extends the
usefulness and life of today's programs and data.

To maximize interconnectivity, the standard file structure and the
specific object formats must all be general and extensible.  Think ahead
when designing an object.  File formats should serve many purposes and
allow many programs to store and read back all the information they need;
even squeeze in custom data.  Then a programmer can store the available
data and is encouraged to include fixed contextual details.  Recipient
programs can read the needed parts, skip unrecognized stuff, default
missing data, and use the stored context to help transform the data as
needed.

@ENDNODE


@Node 16-2-2-3 "Background for Designers / Scope "
IFF addresses these needs by defining a standard file structure, some
initial data object types, ways to define new types, and rules for
accessing these files.  We can accomplish a great deal by writing programs
according to this standard, but do not expect direct compatibility with
existing software. We'll need conversion programs to bridge the gap from
the old world.

IFF is geared for computers that readily process information in 8-bit
bytes. It assumes a "physical layer" of data storage and transmission that
reliably maintains "files" as sequences of 8-bit bytes.  The standard
treats a "file" as a container of data bytes and is independent of how to
find a file and whether it has a byte count.

This standard does not by itself implement a clipboard for cutting and
pasting data between programs.  A clipboard needs software to mediate
access, and provide a notification mechanism so updates and requests for
data can be detected.

@ENDNODE


@Node 16-2-2-4 "Background for Designers / Data Abstraction "
The basic problem is how to represent information  in a way that's
program- independent, compiler- independent, machine-independent, and
device-independent.

The computer science approach is "data abstraction", also known as
"objects", "actors", and "abstract data types".  A data abstraction has a
"concrete representation" (its storage format), an "abstract
representation" (its capabilities and uses), and access procedures that
isolate all the calling software from the concrete representation.  Only
the access procedures touch the data storage.  Hiding mutable details
behind an interface is called "information hiding".  What is hidden are
the non-portable details of implementing the object, namely the selected
storage representation and algorithms for manipulating it.

The power of this approach is modularity.  By adjusting the access
procedures we can extend and restructure the data without impacting the
interface or its callers.  Conversely, we can extend and restructure the
interface and callers without making existing data obsolete.  It's great
for interchange!

But we seem to need the opposite: fixed file formats for all programs to
access.  Actually, we could file data abstractions ("filed objects") by
storing the data and access procedures together.  We'd have to encode the
access procedures in a standard machine-independent programming language 
la PostScript.  Even with this, the interface can't evolve freely since we
can't update all copies of the access procedures.  So we'll have to design
our abstract representations for limited evolution and occasional
revolution (conversion).

In any case, today's microcomputers can't practically store true data
abstractions.  They can do the next best thing: store arbitrary types of
data in "data chunks", each with a type identifier and a length count.
The type identifier is a reference by name to the access procedures (any
local implementation).  The length count enables storage-level object
operations like "copy" and "skip to next" independent of object type or
contents.

Chunk writing is straightforward.  Chunk reading requires a trivial parser
to scan each chunk and dispatch to the proper access/conversion procedure.
Reading chunks nested inside other chunks may require recursion, but no
look ahead or backup.

That's the main idea of IFF.  There are, of course, a few other
details....

@ENDNODE


@Node 16-2-2-5 "Background for Designers / Previous Work "
Where our needs are similar, we borrow from existing standards. Our basic
need to move data between independently developed programs is similar to
that addressed by the Apple Macintosh desk scrap or "clipboard" [Inside
Macintosh chapter "Scrap Manager"].  The Scrap Manager works closely with
the Resource Manager, a handy filer and swapper for data objects (text
strings, dialog window templates, pictures, fonts?) including types yet to
be designed [Inside Macintosh chapter "Resource Manager"].  The Resource
Manager is akin to Smalltalk's object swapper.

We will probably write a Macintosh desk accessory that converts IFF files
to and from the Macintosh clipboard for quick and easy interchange with
programs like MacPaint and Resource Mover.

Macintosh uses a simple and elegant scheme of four-character "identifiers"
to identify resource types, clipboard format types, file types, and file
creator programs.  Alternatives are unique ID numbers assigned by a
central authority or by hierarchical authorities, unique ID numbers
generated by algorithm, other fixed length character strings, and variable
length strings.  Character string identifiers double as readable signposts
in data files and programs. The choice of 4 characters is a good tradeoff
between storage space, fetch/compare/store time, and name space size.
We'll honor Apple's designers by adopting this scheme.

"PICT" is a good example of a standard structured graphics format
(including raster images) and its many uses [Inside Macintosh chapter
"QuickDraw"]. Macintosh provides QuickDraw routines in ROM to create,
manipulate, and display PICTs.  Any application can create a PICT by
simply asking QuickDraw to record a sequence of drawing commands.  Since
it's just as easy to ask QuickDraw to render a PICT to a screen or a
printer, it's very effective to pass them betweenprograms, say from an
illustrator to a word processor.  An important feature is the ability to
store "comments" in a PICT which QuickDraw will ignore.  (Actually, it
passes them to your optional custom "comment handler".)

PostScript, Adobe System's print file standard, is a more general way to
represent any print image (which is a specification for putting marks on
paper) [PostScript Language Manual].  In fact, PostScript is a
full-fledged programming language.  To interpret a PostScript program is
to render a document on a raster output device.  The language is defined
in layers: a lexical layer of identifiers, constants, and operators; a
layer of reverse polish semantics including scope rules and a way to
define new subroutines; and a printing-specific layer of built-in
identifiers and operators for rendering graphic images.  It is clearly a
powerful (Turing equivalent) image definition language.  PICT and a subset
of PostScript are candidates for structured graphics standards.

A PostScript document can be printed on any raster output device
(including a display) but cannot generally be edited.  That's because the
original flexibility and constraints have been discarded.  Besides, a
PostScript program may use arbitrary computation to supply parameters like
placement and size to each operator.  A QuickDraw PICT, in comparison, is
a more restricted format of graphic primitives parameterized by constants.
So a PICT can be edited at the level of the primitives, e.g., move or
thicken a line.  It cannot be edited at the higher level of, say, the bar
chart data which generated the picture.

PostScript has another limitation: not all kinds of data amount to marks
on paper.  A musical instrument description is one example.  PostScript is
just not geared for such uses.

"DIF" is another example of data being stored in a general format usable
by future programs [DIF Technical Specification].  DIF is a format for
spreadsheet data interchange.  DIF and PostScript are both expressed in
plain ASCII text files.  This is very handy for printing, debugging,
experimenting, and transmitting across modems.  It can have substantial
cost in compaction and read/write work, depending on use.  We won't store
IFF files this way but we could define an ASCII alternate representation
with a converter program.

InterScript is the Xerox standard for interchange of editable documents
[Introduction to InterScript].  It approaches a harder problem: How to
represent editable word processor documents that may contain formatted
text, pictures, cross-references like figure numbers, and even highly
specialized objects like mathematical equations?  InterScript aims to
define one standard representation for each kind of information.  Each
InterScript-compatible editor is supposed to preserve the objects it
doesn't understand and even maintain nested cross-references.  So a simple
word processor would let you edit the text of a fancy document without
discarding the equations or disrupting the equation numbers.

Our task is similarly to store high level information and preserve as much
content as practical while moving it between programs.  But we need to
span a larger universe of data types and cannot expect to centrally define
them all. Fortunately, we don't need to make programs preserve information
that they don't understand.  And for better or worse, we don't have to
tackle general- purpose cross-references yet.

@ENDNODE


@Node 16-2-3 " App.A EA IFF/ Primitive Data Types "
Atomic components such as integers and characters that are interpretable
directly by the CPU are specified in one format for all processors.  We
chose a format that's the same as used by the Motorola MC68000 processor
[M68000 16/32-Bit Microprocessor Programmer's Reference Manual].  The high
byte and high word of a number are stored first.

N.B.: Part 3 dictates the format for "primitive" data types where-and
only where-used in the overall file structure.  The number of such
occurrences of dictated formats will be small enough that the costs of
conversion, storage, and management of processor-specific files would far
exceed the costs of conversion during I/O by "foreign" programs.  A
particular data chunk may be specified with a different format for its
internal primitive types or with processor or environment specific
variants if necessary to optimize local usage.  Since that hurts data
interchange, it's not recommended.  (Cf. Designing New Data Sections, in
Part 4.)

@{" Alignment " link 16-2-3-1} @{" Characters " link 16-2-3-3} @{" Type IDs " link 16-2-3-5} @{" Strings " link 16-2-3-7}         @{" Links " link 16-2-3-9}
@{" Numbers " link 16-2-3-2}   @{" Dates " link 16-2-3-4}      @{" Chunks " link 16-2-3-6}   @{" Data Properties " link 16-2-3-8} @{" File References " link 16-2-3-10}

@ENDNODE


@Node 16-2-3-1 "Primitive Data Types / Alignment "
All data objects larger than a byte are aligned on even byte addresses
relative to the start of the file.  This may require padding.  Pad bytes
are to be written as zeros, but don't count on that when reading.

This means that every odd-length "chunk" must be padded so that the next
one will fall on an even boundary.  Also, designers of structures to be
stored in chunks should include pad fields where needed to align every
field larger than a byte.  For best efficiency, long word data should be
arranged on long word (4 byte) boundaries.  Zeros should be stored in all
the pad bytes.

Justification: Even-alignment causes a little extra work for files that
are used only on certain processors but allows 68000 programs to construct
and scan the data in memory and do block I/O.  Any 16-bit or greater CPU
will have faster access to aligned data.  You just add an occasional pad
field to data structures that you're going to block read/write or else
stream read/write an extra byte.  And the same source code works on all
processors.  Unspecified alignment, on the other hand, would force 68000
programs to (dis)assemble word and long word data one byte at a time.
Pretty cumbersome in a high level language.  And if you don't
conditionally compile that step out for other processors, you won't gain
anything.

@ENDNODE


@Node 16-2-3-2 "Primitive Data Types / Numbers "
Numeric types supported are two's complement binary integers in the format
used by the MC68000 processor - high byte first, high word first - the
reverse of 8088 and 6502 format.

	UBYTE	 8 bits unsigned
	WORD	16 bits signed
	UWORD	16 bits unsigned
	LONG	32 bits signed

The actual type definitions depend on the CPU and the compiler.  In this
document, we'll express data type definitions in the C programming
language. [See C, A Reference Manual.]  In 68000 Lattice C:

	typedef unsigned char	UBYTE;	/*  8 bits unsigned	*/
	typedef short		WORD;	/* 16 bits signed	*/
	typedef unsigned short	UWORD;	/* 16 bits unsigned	*/
	typedef long		LONG;	/* 32 bits signed	*/

@ENDNODE


@Node 16-2-3-3 "Primitive Data Types / Characters "
The following character set is assumed wherever characters are used, e.g.,
in text strings, IDs, and TEXT chunks (see below).  Characters are encoded
in 8-bit ASCII.  Characters in the range NUL (hex 0) through DEL (hex 7F)
are well defined by the 7-bit ASCII standard.  IFF uses the graphic group
" " (SP, hex 20) through "~" (hex 7E).

Most of the control character group hex 01 through hex 1F have no standard
meaning in IFF.  The control character LF (hex 0A) is defined as a
"newline" character.  It denotes an intentional line break, that is, a
paragraph or line terminator.  (There is no way to store an automatic line
break.  That is strictly a function of the margins in the environment the
text is placed.) The controlcharacter ESC (hex 1B) is a reserved escape
character under the rules of ANSI standard 3.64-1979 American National
Standard Additional Control Codes for Use with ASCII, ISO standard 2022,
and ISO/DIS standard 6429.2.

Characters in the range hex 7F through hex FF are not globally defined in
IFF. They are best left reserved for future standardization.  (Note that
the @{"FORM" link 16-1-4 52} type @{"FTXT" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_FTXT 16-4-1} (formatted text) defines the meaning of these
characters within FTXT forms.)  In particular, character values hex 7F
through hex 9F are control codes while characters hex A0 through hex FF
are extended graphic characters like , as per the ISO and ANSI standards
cited above.  [See the supplementary document "FTXT" IFF Formatted Text.]

@ENDNODE


@Node 16-2-3-4 "Primitive Data Types / Dates "
A "creation date" is defined as the date and time a stream of data bytes
was created.  (Some systems call this a "last modified date".)  Editing
some data changes its creation date.  Moving the data between volumes or
machines does not.

The IFF standard date format will be one of those used in MS-DOS,
Macintosh, or AmigaDOS (probably a 32-bit unsigned number of seconds since
a reference point).  Issue: Investigate these three.

@ENDNODE


@Node 16-2-3-5 "Primitive Data Types / Type IDs "
A "type ID", "property name", "FORM type", or any other IFF identifier is
a 32-bit value: the concatenation of four ASCII characters in the range
" " (SP, hex 20) through '~' (hex 7E).  Spaces (hex 20) should not precede
printing characters; trailing spaces are OK.  Control characters are
forbidden.

	typedef CHAR ID[4];

IDs are compared using a simple 32-bit case-dependent equality test.  @{"FORM" link 16-1-4 52}
type IDs are restricted.  Since they may be stored in filename extensions
lower case letters and punctuation marks are forbidden.  Trailing spaces
are OK.

Carefully choose those four characters when you pick a new ID.  Make them
mnemonic so programmers can look at an interchange format file and figure
out what kind of data it contains.  The name space makes it possible for
developers scattered around the globe to generate ID values with minimal
collisions so long as they choose specific names like "MUS4" instead of
general ones like "TYPE" and "FILE".

Commodore Applications and Technical Support has undertaken the task of
maintaining the registry of FORM type IDs and format descriptions.  See
the @{"IFF Registry" link ADCD_v1.2:Reference_Library/Devices/dev_A_3PF_Reg/MAIN} document for more information.

Sometimes it's necessary to make data format changes that aren't backward
compatible.  As much as we work for compatibility, unintended interactions
can develop.  Since IDs are used to denote data formats in IFF, new IDs
are chosen to denote revised formats.  Since programs won't read chunks
whose IDs they don't recognize (see @{"Chunks" link 16-1-4}, below), the new IDs keep old
programs from stumbling over new data.  The conventional way to chose a
"revision" ID is to increment the last character if it's a digit or else
change the last character to a digit.  E.g., first and second revisions of
the ID "XY" would be "XY1" and "XY2".  Revisions of "@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}" would be "CMA1"
and "CMA2".

@ENDNODE


@Node 16-2-3-6 "Primitive Data Types / Chunks "
Chunks are the building blocks in the IFF structure.  The form expressed
as a C typedef is:

    typedef struct {
	ID	ckID;			/* 4 character ID */
	LONG	ckSize;			/* sizeof(ckData) */
	UBYTE	ckData[/* ckSize */];
	} Chunk;


We can diagram an example chunk - a "@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}" chunk containing 12 data bytes
- like this:

                        +------------------+   -
        ckID:           | "CMAP"           |   |
                        |------------------+   |
        ckSize:         |  12              |   |
                    -   |------------------+   |
        ckData:     |   |  0, 0, 0, 32     |  20 bytes
                   12   |------------------+   |
                  bytes |  0, 0, 64, 0     |   |
                    |   |------------------+   |
                    |   |  0, 0, 64, 0     |   |
                    -   +------------------+   -


That's 4 bytes of ckID, 4 bytes of ckSize and 12 data bytes.  The total
space used is 20 bytes.

The ckID identifies the format and purpose of the chunk.  As a rule, a
program must recognize ckID to interpret ckData.  It should skip over all
unrecognized chunks.  The ckID also serves as a format version number as
long as we pick new IDs to identify new formats of ckData (see above).

The following ckIDs are universally reserved to identify chunks with
particular IFF meanings: @{"LIST" link 16-1-7 49}, @{"FORM" link 16-1-4 52}, @{"PROP" link 16-1-7 49}, @{"CAT " link 16-1-7 2}, and "    ".  The
special ID "    " (4 spaces) is a ckID for "filler" chunks, that is,
chunks that fill space but have no meaningful contents.  The IDs "LIS1"
through "LIS9", "FOR1" through "FOR9", and "CAT1" through "CAT9" are
reserved for future "version number" variations.  All IFF-compatible
software must account for these chunk IDs.

The ckSize is a logical block size - how many data bytes are in ckData.  If
ckData is an odd number of bytes long, a 0 pad byte follows which is not
included in ckSize.  (Cf. Alignment.)  A chunk's total physical size is
ckSize rounded up to an even number plus the size of the header.  So the
smallest chunk is 8 bytes long with ckSize = 0.  For the sake of following
chunks, programs must respect every chunk's ckSize as a virtual
end-of-file for reading its ckData even if that data is malformed, e.g.,
if nested contents are truncated.

We can describe the syntax of a chunk as a regular expression with "#"
representing the ckSize, the length of the following {braced} bytes.  The
"[0]" represents a sometimes needed pad byte.  (The regular expressions in
this document are collected in @{"Appendix A" link  16-2-8} along with an explanation of
notation.)

	Chunk	::= ID #{ UBYTE* } [0]

One chunk output technique is to stream write a chunk header, stream write
the chunk contents, then random access back to the header to fill in the
size. Another technique is to make a preliminary pass over the data to
compute the size, then write it out all at once.

@ENDNODE


@Node 16-2-3-7 "Primitive Data Types / Strings, String Chunks, and String Properties "
In a string of ASCII text, linefeed (0x0A) denotes a forced line break
(paragraph or line terminator).  Other control characters are not used.
(Cf. Characters.)  For maximum compatibility with line editors, two
linefeed characters are often used to indicate a paragraph boundary.

The ckID for a chunk that contains a string of plain, unformatted text is
"TEXT".  As a practical matter, a text string should probably not be
longer than 32767 bytes.  The standard allows up to 2^31 - 1 bytes.  The
ckID "TEXT" is globally reserved for this use.

When used as a data property (see below), a text string chunk may be 0 to
255 characters long.  Such a string is readily converted to a C string or
a Pascal STRING[255].  The ckID of a property must have a unique property
name, not "TEXT".

When used as a part of a chunk or data property, restricted C string
format is normally used.  That means 0 to 255 characters followed by a
NULL byte (ASCII value 0).

@ENDNODE


@Node 16-2-3-8 "Primitive Data Types / Data Properties (advanced topic) "
Data properties specify attributes for following (non-property) @{"chunk" link 16-2-3-6}.  A
data property essentially says "identifier = value", for example "XY =
(10, 200)", telling something about following chunks.  Properties may only
appear inside data sections ("@{"FORM" link 16-1-4 52}" chunks, cf. Data Sections) and
property sections ("@{"PROP" link 16-1-7 49}" chunks, cf. Group PROP).

The form of a data property is a type of @{"Chunk" link 16-1-4}.  The ckID is a property
name as well as a property type.  The ckSize should be small since data
properties are intended to be accumulated in RAM when reading a file.
(256 bytes is a reasonable upper bound.)  Syntactically:

	Property	::= Chunk

When designing a data object, use properties to describe context
information like the size of an image, even if they don't vary in your
program.  Other programs will need this information.

Think of property settings as assignments to variables in a programming
language.  Multiple assignments are redundant and local assignments
temporarily override global assignments.  The order of assignments doesn't
matter as long as they precede the affected @{"chunk" link 16-2-3-6}.  (Cf. @{"LIST" link 16-1-7 49}s, CATs, and
Shared Properties.)

Each object type (@{"FORM" link 16-1-4 52} type) is a local name space for property IDs.
Think of a "@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}" property in a "FORM @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}" as the qualified ID
"ILBM.@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}".  A "CMAP" inside some other type of @{"FORM" link 16-1-4 52} may not have the
same meaning.  Property IDs specified when an object type is designed (and
therefore known to all clients) are called "standard" while specialized
ones added later are "nonstandard".

@ENDNODE


@Node 16-2-3-9 "Primitive Data Types / Links "
Issue: A standard mechanism for "links" or "cross references" is very
desirable for things like combining images and sounds into animations.
Perhaps we'll define "link" @{"chunk" link 16-2-3-6} within @{"FORM" link 16-1-4 52}s that refer to other FORMs
or to specific chunks within the same and other FORMs.  This needs further
work. EA IFF 1985 has no standard link mechanism.

For now, it may suffice to read a list of, say, musical instruments, and
then just refer to them within a musical score by  sequence  number.

@ENDNODE


@Node 16-2-3-10 "Primitive Data Types / File References "
Issue: We may need a standard form for references to other files.  A "file
ref" could name a directory and a file in the same type of operating
system as the reference's originator.  Following the reference would
expect the file to be on some mounted volume, or perhaps the same
directory as the file that made the reference.  In a network environment,
a file reference could name a server, too.

Issue: How can we express operating-system independent file references?

Issue: What about a means to reference a portion of another file?  Would
this be a "file ref" plus a reference to a "link" within the target file?

@ENDNODE


@Node 16-2-4 " Appendix A / EA IFF/ Data Sections "
The first thing we need of a file is to check: Does it contain IFF data
and, if so, does it contain the kind of data we're looking for?  So we
come to the notion of a "data section".

A "data section" or IFF "@{"FORM" link 16-1-4 52}" is one self-contained "data object" that
might be stored in a file by itself.  It is one high level data object
such as a picture or a sound effect, and generally contains a grouping of
chunks.  The IFF structure "FORM" makes it self-identifying.  It could be
a composite object like a musical score with nested musical instrument
descriptions.

@{" Group FORM " link 16-2-4-1}
@{" Composite FORMs " link 16-2-4-2}
@{" Designing New Data Sections " link 16-2-4-3}

@ENDNODE


@Node 16-2-4-1 " Data Sections / Group FORM "
A data section is a @{"chunk" link 16-2-3-6} with ckID "@{"FORM" link 16-1-4 52}" and this arrangement:

    FORM       ::= "FORM" #{ FormType (LocalChunk | FORM | LIST | CAT)* }
    FormType   ::= ID
    LocalChunk ::= Property | Chunk

The ID "@{"FORM" link 16-1-4 52}" is a syntactic keyword like "struct" in C.  Think of a
"struct @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}" containing a field "@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}".  If you see "FORM" you will know
to expect a FORM type ID (the structure name, "@{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}" in this example) and
a particular contents arrangement or "syntax" (local @{"chunk" link 16-2-3-6}, FORMs, @{"LIST" link 16-1-7 49}s,
and @{"CAT " link link 16-1-7 2}).  A "FORM ILBM", in particular, might contain a local chunk
"CMAP", an "ILBM.CMAP" (to use a qualified name).

So the @{"chunk" link 16-2-3-6} ID "@{"FORM" link 16-1-4 52}" indicates a data section.  It implies that the
@{"chunk" link 16-2-3-6} contains an ID and some number of nested chunks.  In reading a FORM,
like any other chunk, programs must respect its ckSize as a virtual
end-of-file for reading its contents, even if they're truncated.

The @{"FORM" link 16-1-4 52} type is a restricted ID that may not contain lower case letters
or punctuation characters.  (Cf. Type IDs.  Cf. Single Purpose Files.)

The type-specific information in a @{"FORM" link 16-1-4 52} is composed of its "local @{"chunk" link 16-2-3-6}s":
data properties and other @{"chunk" link 16-2-3-6}s.  Each FORM type is a local name space
for local @{"chunk" link 16-2-3-6} IDs.  So "@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}" local @{"chunk" link 16-2-3-6}s in other FORM types may be
unrelated to "ILBM.CMA"".  More than that, each FORM type defines semantic
scope.  If you know what a FORM @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1} is, you will know what an ILBM.@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}
is.

Local @{"chunk" link 16-2-3-6}s defined when the @{"FORM" link 16-1-4 52} type is designed (and therefore known
to all clients of this type) are called "standard" while specialized ones
added later are "nonstandard".

Among the local @{"chunk" link 16-2-3-6}s, property chunks give settings for various details
like text font while the other chunks supply the essential information.
This distinction is not clear cut.  A property setting can be cancelled by
a later setting of the same property.  E.g., in the sequence:

	prop1 = x  (Data A)  prop1 = z  prop1 = y (Data B)

prop1 is = x for Data A, and y for Data B.  The setting prop1 = z has no
effect.

For clarity, the universally reserved @{"chunk" link 16-2-3-6} IDs "@{"LIST" link 16-1-7 49}", "@{"FORM" link 16-1-4 52}", "@{"PROP" link 16-1-7 49}",
"@{"CAT " link link 16-1-7 2}", "    ", "LIS1" through "LIS9", "FOR1" through "FOR9", and "CAT1"
through "CAT9" may not be FORM type IDs.

Part 5, below, talks about grouping @{"FORM" link 16-1-4 52}s into @{"LIST" link 16-1-7 49}s and @{"CAT " link link 16-1-7 2}s.  They let
you group a bunch of FORMs but don't impose any particular meaning or
constraints on the grouping.  Read on.

@ENDNODE


@Node 16-2-4-2 " Data Sections / Composite FORMs "
A @{"FORM" link 16-1-4 52} @{"chunk" link 16-2-3-6} inside a FORM is a full-fledged data section.  This means you
can build a composite object such as a multi-frame animation sequence by
nesting available picture FORMs and sound effect FORMs.  You can insert
additional @{"chunk" link 16-2-3-6}s with information like frame rate and frame count.

Using composite @{"FORM" link 16-1-4 52}s, you leverage on existing programs that create and
edit the component FORMs.  Those editors may even look into your composite
object to copy out its type of component.  Such editors are not allowed to
replace their component objects within your composite object.  That's
because the IFF standard lets you specify consistency requirements for the
composite FORM such as maintaining a count or a directory of the
components.  Only programs that are written to uphold the rules of your
FORM type may create or modify such FORMs.

Therefore, in designing a program that creates composite objects, you are
strongly requested to provide a facility for your users to import and
export the nested @{"FORM" link 16-1-4 52}s.  Import and export could move the data through a
clipboard or a file.

Here are several existing @{"FORM" link 16-1-4 52} types and rules for defining new ones:

@{" FTXT " link 16-2-4-2-1}    @{" ILBM " link 16-2-4-2-2}    @{" PICs " link 16-2-4-2-3}    @{" Other Macintosh Resource Types " link 16-2-4-2-4}

@ENDNODE


@Node 16-2-4-2-1 " Composite FORMs / FTXT "
An FTXT data section contains text with character formatting information
like fonts and faces.  It has no paragraph or document formatting
information like margins and page headers.  FORM FTXT is well matched to
the text representation in Amiga's Intuition environment.  See the
supplemental document "FTXT" IFF Formatted Text.

@ENDNODE


@Node 16-2-4-2-2 " Composite FORMs / ILBM "
"@{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}" is an InterLeaved BitMap image with color map; a
machine-independent format for raster images.  FORM ILBM is the standard
image file format for the Commodore-Amiga computer and is useful in other
environments, too.  See the supplemental document "ILBM" IFF Interleaved
Bitmap.

@ENDNODE


@Node 16-2-4-2-3 " Composite FORMs / PICS "
The data @{"chunk" link 16-2-3-6} inside a "PICS" data section has ID "PICT" and holds a
QuickDraw picture.  Issue: Allow more than one PICT in a PICS?  See Inside
Macintosh chapter "QuickDraw" for details on PICTs and how to create and
display them on the Macintosh computer.

The only standard property for PICS is "XY", an optional property that
indicates the position of the PICT relative to "the big picture".  The
contents of an XY is a QuickDraw Point.

Note: PICT may be limited to Macintosh use, in which case there"ll be
another format for structured graphics in other environments.

@ENDNODE


@Node 16-2-4-2-4 " Composite FORMs / Other Macintosh Resource Types "
Some other Macintosh resource types could be adopted for use within IFF
files; perhaps MWRT, ICN, ICN#, and STR#.

Issue: Consider the candidates and reserve some more IDs.

@ENDNODE


@Node 16-2-4-3 " Data Sections / Designing New Data Sections "
Supplemental documents will define additional object types.  A supplement
needs to specify the object's purpose, its @{"FORM" link 16-1-4 52} type ID, the IDs and
formats of standard local @{"chunk" link 16-2-3-6}s, and rules for generating and
interpreting the data. It's a good idea to supply typedefs and an example
source program that accesses the new object.  See "@{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}" IFF Interleaved
Bitmap for such an example.

Anyone can pick a new @{"FORM" link 16-1-4 52} type ID but should reserve it with Commodore
Applications and Technical Support (@{"CAT " link link 16-1-7 2}) at their earliest convenience.
While decentralized  format definitions and extensions are possible in
IFF, our preference is to get design consensus by committee, implement a
program to read and write it, perhaps tune the format before it becomes
locked in stone, and then publish the format with example code.  Some
organization should remain in charge of answering questions and
coordinating extensions to the format.

If it becomes necessary to incompatibly revise the design of some data
section, its @{"FORM" link 16-1-4 52} type ID will serve as a version number (Cf. Type IDs).
E.g., a revised "VDEO" data section could be called "VDE1".  But try to
get by with compatible revisions within the existing FORM type.

In a new @{"FORM" link 16-1-4 52} type, the rules for primitive data types and word-alignment
(Cf. Primitive Data Types) may be overridden for the contents of its local
@{"chunk" link 16-2-3-6}s - but not for the chunk structure itself - if your documentation
spells out the deviations.  If machine-specific type variants are needed,
e.g., to store vast numbers of integers in reverse bit order, then outline
the conversion algorithm and indicate the variant inside each file,
perhaps via different FORM types.  Needless to say, variations should be
minimized.

In designing a @{"FORM" link 16-1-4 52} type, encapsulate all the data that other programs
will need to interpret your files.  E.g., a raster graphics image should
specify the image size even if your program always uses 320 x 200 pixels x
3 bitplanes. Receiving programs are then empowered to append or clip the
image rectangle, to add or drop bitplanes, etc.  This enables a lot more
compatibility.

Separate the central data (like musical notes) from more specialized
information (like note beams) so simpler programs can extract the central
parts during read-in.  Leave room for expansion so other programs can
squeeze in new kinds of information (like lyrics).  And remember to keep
the property @{"chunk" link 16-2-3-6}s manageably short - let's say <= 256 bytes.

When designing a data object, try to strike a good tradeoff between a
super- general format and a highly-specialized one.  Fit the details to at
least one particular need, for example a raster image might as well store
pixels in the current machine's scan order.  But add the kind of
generality that makes the format usable with foreseeable hardware and
software.  E.g., use a whole byte for each red, green, and blue color
value even if this year's computer has only 4-bit video DACs.  Think ahead
and help other programs so long as the overhead is acceptable.  E.g., run
compress a raster by scan line rather than as a unit so future programs
can swap images by scan line to and from secondary storage.

Try to design a general purpose "least common multiple" format that
encompasses the needs of many programs without getting too complicated.
Be sure to leave provisions for future expansion.  Let's coalesce our uses
around a few such formats widely separated in the vast design space.  Two
factors make this flexibility and simplicity practical.  First, file
storage space is getting very plentiful, so compaction is not always a
priority.  Second, nearly any locally-performed data conversion work
during file reading and writing will be cheap compared to the I/O time.

It must be OK to copy a @{"LIST" link 16-1-7 49} or @{"FORM" link 16-1-4 52} or @{"CAT " link link 16-1-7 2} intact, e.g., to incorporate
it into a composite FORM.  So any kind of internal references within a
FORM must be relative references.  They could be relative to the start of
the containing FORM, relative from the referencing @{"chunk" link 16-2-3-6}, or a sequence
number into a collection.

With composite @{"FORM" link 16-1-4 52}s, you leverage on existing programs that create and
edit the components.  If you write a program that creates composite
objects, please provide a facility for users to import and export the
nested FORMs.

Finally, don't forget to specify all implied rules in detail.

@ENDNODE


@Node 16-2-5 " App.A EA IFF/ LISTs, CATs, and Shared Properties (Advanced topics) "
Data often needs to be grouped together, for example, consider a list of
icons. Sometimes a trick like arranging little images into a big raster
works, but generally they'll need to be structured as a first class group.
The objects "@{"LIST" link 16-1-7 49}" and "@{"CAT " link link 16-1-7 2}" are IFF-universal mechanisms for this
purpose.  Note: @{"LIST" link 16-1-7 49} and CAT are advanced topics the first time reader
will want to skip.

Property settings sometimes need to be shared over a list of similar
objects. E.g., a list of icons may share one color map.  @{"LIST" link 16-1-7 49} provides a
means called "@{"PROP" link 16-1-7 49}" to do this.  One purpose of a LIST is to define the
scope of a PROP. A "@{"CAT " link link 16-1-7 2}", on the other hand, is simply a concatenation of
objects.

Simpler programs may skip @{"LIST" link 16-1-7 49}s and @{"PROP" link 16-1-7 49}s altogether and just handle @{"FORM" link 16-1-4 52}s
and @{"CAT " link link 16-1-7 2}s.  All "fully-conforming" IFF programs also know about "CAT ",
"LIST", and "PROP".  Any program that reads a @{"FORM" link 16-1-4 52} inside a LIST must
process shared PROPs to correctly interpret that FORM.

@{" Group CAT " link 16-2-5-1}   @{" Group LIST " link 16-2-5-2}   @{" Group PROP " link 16-2-5-3}   @{" Properties for LIST " link 16-2-5-4}

@ENDNODE


@Node 16-2-5-1 " LISTs, CATs, and Shared Properties (Advanced topics) / Group CAT "
A @{"CAT " link link 16-1-7 2} is just an untyped group of data objects.

Structurally, a @{"CAT " link link 16-1-7 2} is a @{"chunk" link 16-2-3-6} with @{"chunk" link 16-2-3-6} ID "CAT " containing a "contents
type" ID followed by the nested objects.  The ckSize of each contained
chunk is essentially a relative pointer to the next one.

	CAT		::= "CAT " #{ ContentsType (FORM | LIST | CAT)* }
	ContentsType    ::= ID	- a hint or an "abstract data type" ID

In reading a @{"CAT " link link 16-1-7 2}, like any other @{"chunk" link 16-2-3-6}, programs must respect its ckSize
as a virtual end-of-file for reading the nested objects even if they're
malformed or truncated.

The "contents type" following the @{"CAT " link link 16-1-7 2}'s ckSize indicates what kind of
@{"FORM" link 16-1-4 52}s are inside.  So a CAT of @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}s would store "ILBM" there.  It's just
a hint. It may be used to store an "abstract data type".  A CAT could just
have blank contents ID ("    ") if it contains more than one kind of @{"FORM" link 16-1-4 52}.

@{"CAT " link link 16-1-7 2} defines only the format of the group.  The group's meaning is open to
interpretation.  This is like a list in LISP: the structure of cells is
predefined but the meaning of the contents as, say, an association list
depends on use.  If you need a group with an enforced meaning (an
"abstract datatype" or Smalltalk "subclass"), some consistency
constraints, or additional data @{"chunk" link 16-2-3-6}s, use a composite @{"FORM" link 16-1-4 52} instead (Cf.
Composite FORMs).

Since a @{"CAT " link link 16-1-7 2} just means a concatenation of objects, CATs are rarely nested.
Programs should really merge CATs rather than nest them.

@ENDNODE


@Node 16-2-5-2 " LISTs, CATs, and Shared Properties (Advanced topics) / Group LIST "
A @{"LIST" link 16-1-7 49} defines a group very much like @{"CAT " link link 16-1-7 2} but it also gives a scope for
@{"PROP" link 16-1-7 49}s (see below).  And unlike CATs, LISTs should not be merged without
understanding their contents.

Structurally, a @{"LIST" link 16-1-7 49} is a @{"chunk" link 16-2-3-6} with ckID "LIST" containing a "contents
type" ID, optional shared properties, and the nested contents (@{"FORM" link 16-1-4 52}s,
LISTs, and @{"CAT " link link 16-1-7 2}s), in that order.  The ckSize of each contained @{"chunk" link 16-2-3-6} is a
relative pointer to the next one.  A LIST is not an arbitrary linked
list - the cells are simply concatenated.

    LIST         ::= "LIST" #{ ContentsType PROP* (FORM | LIST | CAT)* }
    ContentsType ::= ID

@ENDNODE


@Node 16-2-5-3 " LISTs, CATs, and Shared Properties (Advanced topics) / Group PROP "
@{"PROP" link 16-1-7 49} @{"chunk" link 16-2-3-6}s may appear in @{"LIST" link 16-1-7 49}s (not in @{"FORM" link 16-1-4 52}s or CATs).  They supply
shared properties for the FORMs in that LIST.  This ability to elevate
some property settings to shared status for a list of forms is useful for
both indirection and compaction.  E.g., a list of images with the same
size and colors can share one "size" property and one "color map"
property.  Individual FORMs can override the shared settings.

The contents of a @{"PROP" link 16-1-7 49} is like a FORM with no data @{"chunk" link 16-2-3-6}s:

	PROP	::= "PROP" #{ FormType Property* }

It means, "Here are the shared properties for @{"FORM" link 16-1-4 52} type <FormType>".

A @{"LIST" link 16-1-7 49} may have at most one @{"PROP" link 16-1-7 49} of a @{"FORM" link 16-1-4 52} type, and all the @{"PROP" link 16-1-7 49}s must
appear before any of the FORMs or nested LISTs and @{"CAT " link link 16-1-7 2}s.  You can have
subsequences of FORMs sharing properties by making each subsequence a LIST.

Scoping: Think of property settings as variable bindings in nested blocks
of a programming language.  In C this would look like:

    #define Roman           0
    #define Helvetica       1

    void main()
            {
            int font=Roman; /* The global default */
                    {
                    printf("The font number is %d\n",font);
                    }
                    {
                    int font=Helvetica;     /* local setting */
                    printf("The font number is %d\n",font);
                    }
                    {
                    printf("The font number is %d\n",font);
                    }
            }


    /*
    * Sample output:       The font number is 0
    *                      The font number is 1
    *                      The font number is 0
    */




    An IFF file could contain:

    LIST {
            PROP TEXT {
                    FONT {TimesRoman}       /* shared setting       */
                    }

            FORM TEXT {
                    FONT {Helvetica}        /* local setting        */
                    CHRS {Hello }           /* uses font Helvetica  */
                    }

            FORM TEXT {
                    CHRS {there.}           /* uses font TimesRoman */
                    }
            }

The shared property assignments selectively override the reader's global
defaults, but only for @{"FORM" link 16-1-4 52}s within the group.  A FORM's own property
assignments selectively override the global and group-supplied values.  So
when reading an IFF file, keep property settings on a stack.  They are
designed to be small enough to hold in main memory.

Shared properties are semantically equivalent to copying those properties
into each of the nested @{"FORM" link 16-1-4 52}s right after their FORM type IDs.

@ENDNODE


@Node 16-2-5-4 " LISTs, CATs and Shared Properties (Advanced topics) / Properties for LIST "
Optional "properties for @{"LIST" link 16-1-7 49}" store the origin of the list's contents in
a PROP @{"chunk" link 16-2-3-6} for the pseudo @{"FORM" link 16-1-4 52} type "LIST".  They are the properties
originating program "OPGM", processor family "OCPU", computer type "OCMP",
computer serial number or network address "OSN ", and user name "UNAM". In
our imperfect world, these could be called upon to distinguish between
unintended variations of a data format or to work around bugs in
particular originating/receiving program pairs.  Issue: Specify the format
of these properties.

A creation date could also be stored in a property, but let's ask that
file creating, editing, and transporting programs maintain the correct
date in the local file system.  Programs that move files between machine
types are expected to copy across the creation dates.

@ENDNODE


@Node 16-2-6 " App.A EA IFF/ Standard File Structure "

@{" File Structure Overview " link 16-2-6-1}    @{" Rules for Reader Programs " link 16-2-6-4}
@{" Single Purpose Files " link 16-2-6-2}       @{" Rules for Writer Programs " link 16-2-6-5}
@{" Scrap Files " link 16-2-6-3}

@ENDNODE


@Node 16-2-6-1 " Standard File Structure / File Structure Overview "
An IFF file is just a single @{"chunk" link 16-2-3-6} of type @{"FORM" link 16-1-4 52}, @{"LIST" link 16-1-7 49}, or @{"CAT " link link 16-1-7 2}.  Therefore
an IFF file can be recognized by its first 4 bytes: "FORM", "LIST", or
"@{"CAT " link link 16-1-7 2}". Any file contents after the chunk's end are to be ignored.  (Some
file transfer programs add garbage to the end of transferred files.  This
specification protects against such common damage).

The simplest IFF file would be one that does no more than encapsulate some
binary data (perhaps even an old-fashioned single-purpose binary file).
Here is a binary dump of such a minimal IFF example:

	0000: 464F524D 0000001A 534E4150 43524143    FORM....SNAPCRAC
	0010: 0000000D 68656C6C 6F2C776F 726C6421    ....hello,world!
	0020: 0A00                                   ..

The first 4 bytes indicate this is a "@{"FORM" link 16-1-4 52}"; the most common IFF top level
structure.  The following 4 bytes indicate that the contents totals 26
bytes. The form type is listed as "SNAP".

Our form "SNAP" contains only one @{"chunk" link 16-2-3-6} at the moment; a chunk of type
"CRAC". From the size ($0000000D) the amount of data must be 13 bytes.  In
this case, the data happens to correspond to the ASCII string "hello,
world!<lf>". Since the number 13 is odd, a zero pad byte is added to the
file.  At any time new chunks could be added to form SNAP without
affecting any other aspect of the file (other than the form size).  It's
that simple.

Since an IFF file can be a group of objects, programs that read/write
single objects can communicate to an extent with programs that read/write
groups. You're encouraged to write programs that handle all the objects in
a @{"LIST" link 16-1-7 49} or @{"CAT " link link 16-1-7 2}.  A graphics editor, for example, could process a list of
pictures as a multiple page document, one page at a time.

Programs should enforce IFF's syntactic rules when reading and writing
files. Users should be told when a file is corrupt.  This ensures robust
data transfer.  For minor damage, you may wish to give the user the option
of using the suspect data, or cancelling.  Presumably a user could read in
a damaged file, then save whatever was salvaged to a valid file.  The
public domain IFF reader/writer subroutine package does some syntatic
checks for you.  A utility program"IFFCheck" is available that scans an
IFF file and checks it for conformance to IFF's syntactic rules.  IFFCheck
also prints an outline of the @{"chunk" link 16-2-3-6}s in the file, showing the ckID and
ckSize of each.  This is quite handy when building IFF programs.  Example
programs are also available to show details of reading and writing IFF
files.

A merge program "IFFJoin" will be available that logically appends IFF
files into a single @{"CAT " link link 16-1-7 2} group.  It "unwraps" each input file that is a CAT
so that the combined file isn't nested CATs.

If we need to revise the IFF standard, the three anchoring IDs will be
used as "version numbers".  That's why IDs "FOR1" through "FOR9", "LIS1"
through "LIS9", and "CAT1" through "CAT9" are reserved.

IFF formats are designed for reasonable performance with floppy disks.  We
achieve considerable simplicity in the formats and programs by relying on
the host file system rather than defining universal grouping structures
like directories for @{"LIST" link 16-1-7 49} contents.  On huge storage systems, IFF files
could be leaf nodes in a file structure like a B-tree.  Let's hope the
host file system implements that for us!

There are two kinds of IFF files: single purpose files and scrap files.
They differ in the interpretation of multiple data objects and in the
file's external type.

@ENDNODE


@Node 16-2-6-2 " Standard File Structure / Single Purpose Files "
A single purpose IFF file is for normal "document" and "archive" storage.
This is in contrast with "scrap files" (see below) and temporary backing
storage (non-interchange files).

The external file type (or filename extension, depending on the host file
system) indicates the file's contents.  It's generally the @{"FORM" link 16-1-4 52} type of
the data contained, hence the restrictions on FORM type IDs.

Programmers and users may pick an "intended use" type as the filename
extension to make it easy to filter for the relevant files in a filename
requester.  This is actually a "subclass" or "subtype" that conveniently
separates files of the same @{"FORM" link 16-1-4 52} type that have different uses.  Programs
cannot demand conformity to its expected subtypes without overly
restricting data interchange since they cannot know about the subtypes to
be used by future programs that users will want to exchange data with.

Issue: How to generate 3-letter MS-DOS extensions from 4-letter @{"FORM" link 16-1-4 52} type
IDs?

Most single purpose files will be a single @{"FORM" link 16-1-4 52} (perhaps a composite FORM
like a musical score containing nested FORMs like musical instrument
descriptions). If it's a @{"LIST" link 16-1-7 49} or a @{"CAT " link link 16-1-7 2}, programs should skip over
unrecognized objects to read the recognized ones or the first recognized
one.  Then a program that can read a single purpose file can read
something out of a "scrap file", too.

@ENDNODE


@Node 16-2-6-3 " Standard File Structure / Scrap Files (not currently used) "
A "scrap file" is for maximum interconnectivity in getting data between
programs; the core of a clipboard function.  Scrap files may have type
"IFF " or filename extension ".IFF".

A scrap file is typically a @{"CAT " link link 16-1-7 2} containing alternate representations of
the same basic information.  Include as many alternatives as you can
readily generate.  This redundancy improves interconnectivity in
situations where we can't make all programs read and write super-general
formats.  [Inside Macintosh chapter "Scrap Manager".]  E.g., a
graphically-annotated musical score might be supplemented by a stripped
down 4-voice melody and by a text (the lyrics).

The originating program should write the alternate representations in
order of "preference": most preferred (most comprehensive) type to least
preferred (least comprehensive) type.  A receiving program should either
use the first appearing type that it understands or search for its own
"preferred" type.

A scrap file should have at most one alternative of any type.  (A @{"LIST" link 16-1-7 49} of
same type objects is OK as one of the alternatives.)  But don't count on
this when reading; ignore extra sections of a type.  Then a program that
reads scrap files can read something out of single purpose files.

@ENDNODE


@Node 16-2-6-4 " Standard File Structure / Rules for Reader Programs "
Here are some notes on building programs that read IFF files.  For @{"LIST" link 16-1-7 49}
and @{"PROP" link 16-1-7 49} work, you should also read up on recursive descent parsers. [See,
for example, Compiler Construction, An Advanced Course.]

  o The standard is very flexible so many programs can exchange data.
     This implies a program has to scan the file and react to what's
     actually there in whatever order it appears.  An IFF reader program
     is a parser.

  o For interchange to really work, programs must be willing to do some
     conversion during read-in.  If the data isn't exactly what you expect,
     say, the raster is smaller than those created by your program, then
     adjust it.  Similarly, your program could crop a large picture, add
     or drop bitplanes, or create/discard a mask plane.  The program
     should give up gracefully on data that it can't convert.

  o If it doesn't start with "@{"FORM" link 16-1-4 52}", "@{"LIST" link 16-1-7 49}", or "@{"CAT " link link 16-1-7 2}", it's not an IFF-85
     file.

  o For any @{"chunk" link 16-2-3-6} you encounter, you must recognize its type ID to
     understand its contents.

  o For any @{"FORM" link 16-1-4 52} @{"chunk" link 16-2-3-6} you encounter, you must recognize its FORM type ID
     to understand the contained "local chunks".  Even if you don't
     recognize the FORM type, you can still scan it for nested FORMs,
     @{"LIST" link 16-1-7 49}s, and @{"CAT " link link 16-1-7 2}s of interest.

  o Don't forget to skip the implied pad byte after every odd-length @{"chunk" link 16-2-3-6},
     this is not  included in the chunk count!

  o @{"Chunk" link 16-2-3-6} types @{"LIST" link 16-1-7 49}, @{"FORM" link 16-1-4 52}, @{"PROP" link 16-1-7 49}, and @{"CAT " link link 16-1-7 2} are generic groups.  They always
     contain a subtype ID followed by chunks.

  o Readers ought to handle a @{"CAT " link link 16-1-7 2} of @{"FORM" link 16-1-4 52}s in a file.  You may treat the
     FORMs like document pages to sequence through, or just use the first
     FORM.

  o Many  IFF readers completely skip @{"LIST" link 16-1-7 49}s.  "Fully IFF-conforming"
     readers are those that handle LISTs, even if just to read the first
     @{"FORM" link 16-1-4 52} from a file.  If you do look into a LIST, you must process
     shared properties (in @{"PROP" link 16-1-7 49} @{"chunk" link 16-2-3-6}s) properly.  The idea is to get the
     correct data or none at all.

  o The nicest readers are willing to look into unrecognized @{"FORM" link 16-1-4 52}s for
     nested FORM types that they do recognize.  For example, a musical
     score may contain nested instrument descriptions and animation or
     desktop publishing files may contain still pictures.   This extra
     step is highly recommended.

Note to programmers: Processing PROP @{"chunk" link 16-2-3-6}s is not simple! You'll need
some background in interpreters with stack frames.  If this is foreign to
you, build programs that read/write only one @{"FORM" link 16-1-4 52} per file.  For the more
intrepid programmers, the next paragraph summarizes how to process @{"LIST" link 16-1-7 49}s
and @{"PROP" link 16-1-7 49}s.

Allocate a stack frame for every @{"LIST" link 16-1-7 49} and @{"FORM" link 16-1-4 52} you encounter and
initialize it by copying the stack frame of the parent LIST or FORM.  At
the top level, you'll need a stack frame initialized to your program's
global defaults. While reading each LIST or FORM, store all encountered
properties into the current stack frame.  In the example ShowILBM, each
stack frame has a place for a bitmap header property ILBM.@{"BMHD" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-1} and a color
map property ILBM.@{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}. When you finally get to the ILBM's @{"BODY" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-3-2} @{"chunk" link 16-2-3-6}, use
the property settings accumulated in the current stack frame.

An alternate implementation would just remember @{"PROP" link 16-1-7 49}s encountered,
forgetting each on reaching the end of its scope (the end of the
containing @{"LIST" link 16-1-7 49}).  When a @{"FORM" link 16-1-4 52} XXXX is encountered, scan the @{"chunk" link 16-2-3-6}s in all
remembered @{"PROP" link 16-1-7 49}s XXXX, in order, as if they appeared before the chunks
actually in the FORM XXXX.  This gets trickier if you read FORMs inside of
FORMs.

@ENDNODE


@Node 16-2-6-5 " Standard File Structure / Rules for Writer Programs "
Here are some notes on building programs that write IFF files, which is
much easier than reading them.

   o An IFF file is a single @{"FORM" link 16-1-4 52}, @{"LIST" link 16-1-7 49}, or @{"CAT " link link 16-1-7 2} @{"chunk" link 16-2-3-6}.

   o Any IFF-85 file must start with the 4 characters "@{"FORM" link 16-1-4 52}", "@{"LIST" link 16-1-7 49}", or
      "@{"CAT " link link 16-1-7 2}", followed by a LONG ckSize.  There should be no data after
      the @{"chunk" link 16-2-3-6} end.

   o @{"Chunk" link 16-2-3-6} types @{"LIST" link 16-1-7 49}, @{"FORM" link 16-1-4 52}, @{"PROP" link 16-1-7 49}, and @{"CAT " link link 16-1-7 2} are generic.  They always
      contain a subtype ID followed by chunks.  These three IDs are
      universally reserved, as are "LIS1" through "LIS9", "FOR1" through
      "FOR9", "CAT1" through "CAT9", and "    ".

   o Don't forget to write a 0 pad byte after each odd-length @{"chunk" link 16-2-3-6}.

   o Do not try to edit a file that you don't know how to create.  Programs
      may look into a file and copy out nested @{"FORM" link 16-1-4 52}s of types that they
      recognize, but they should not edit and replace the nested FORMs and
      not add or remove them.  Breaking these rules could make the
      containing structure inconsistent.  You may write a new file
      containing items you copied, or copied and modified, but don't copy
      structural parts you don't understand.

   o You must adhere to the syntax descriptions in Appendix A.  E.g., @{"PROP" link 16-1-7 49}s
      may only appear inside @{"LIST" link 16-1-7 49}s.

There are at least four common techniques for writing an IFF group:

  (1)  build the data in a file mapped into virtual memory.
  (2)  build the data in memory blocks and use block I/O.
  (3)  stream write the data piecemeal and (don't forget!) random
          access back to set the group (or @{"FORM" link 16-1-4 52})
          length count.
  (4)  make a preliminary pass to compute the length count then stream
          write the data.

Issue: The standard disallows "blind" @{"chunk" link 16-2-3-6} copying for consistency
reasons. Perhaps we can define a ckID convention for chunks that are OK to
replicate without knowledge of the contents.  Any such chunks would need
to be internally consistent, and not be bothered by changed external
references.

Issue: Stream-writing an IFF @{"FORM" link 16-1-4 52} can be inconvenient.  With random access
files one can write all the @{"chunk" link 16-2-3-6}s then go back to fix up the FORM size.
With stream access, the FORM size must be calculated before the file is
written. When compression is involved, this can be slow or inconvenient.
Perhaps we can define an "END " chunk.  The stream writer would use -1
($FFFFFFFF) as the FORM size.  The reader would follow each chunk, when
the reader reaches an "END ", it would terminate the last -1 sized chunk.
Certain new IFF FORMs could require that readers understand "END ".

@ENDNODE


@Node 16-2-7 " App.A EA IFF/ Standards Committee "
The following people contributed to the design of this IFF standard:

Bob "Kodiak" Burns, Commodore-Amiga
R. J. Mical, Commodore-Amiga
Jerry Morrison, Electronic Arts
Greg Riker, Electronic Arts
Steve Shaw, Electronic Arts
Barry Walsh, Commodore-Amiga
Oct, 1988 revision by Bryce Nesbitt, and Carolyn Scheppner, Commodore-Amiga

@ENDNODE


@Node 16-2-8 " App.A EA IFF/ Appendix A. Reference "

@{" Type Definitions " link 16-2-8-1}    @{" Syntax Definitions " link 16-2-8-2}    @{" Example Diagrams " link 16-2-8-3}

@ENDNODE


@Node 16-2-8-1 " Appendix A. Reference / Type Definitions "
The following C typedefs describe standard IFF structures.  Declarations
to use in practice will vary with the CPU and compiler.  For example,
68000 Lattice C produces efficient comparison code if we define ID as a
"LONG".  A macro "MakeID" builds these IDs at compile time.

    /* Standard IFF types, expressed in 68000 Lattice C.    */

    typedef unsigned char UBYTE;    /*  8 bits unsigned     */
    typedef short WORD;             /* 16 bits signed       */
    typedef unsigned short UWORD;   /* 16 bits unsigned     */
    typedef long LONG;              /* 32 bits signed       */

    typedef char ID[4];             /* 4 chars in " " through "~" */

    typedef struct {
      ID    ckID;
      LONG  ckSize;                 /* sizeof(ckData)       */
      UBYTE ckData[/* ckSize */];
      } Chunk;


    /* ID typedef and builder for 68000 Lattice C. */
    typedef LONG ID;                /* 4 chars in " " through "~"   */

    #define MakeID(a,b,c,d) ( (a)<<24 | (b)<<16 | (c)<<8 | (d) )

    /* Globally reserved IDs. */
    #define ID_FORM   MakeID('F','O','R','M')
    #define ID_LIST   MakeID('L','I','S','T')
    #define ID_PROP   MakeID('P','R','O','P')
    #define ID_CAT    MakeID('C','A','T',' ')
    #define ID_FILLER MakeID(' ',' ',' ',' ')

@ENDNODE


@Node 16-2-8-2 " Appendix A. Reference / Syntax Definitions "
Here's a collection of the syntax definitions in this document.

    Chunk        ::= ID #{ UBYTE* } [0]

    Property     ::= Chunk

    FORM         ::= 'FORM' #{ FormType (LocalChunk | FORM | LIST | CAT)* }
    FormType     ::= ID
    LocalChunk   ::= Property | Chunk

    CAT          ::= 'CAT ' #{ ContentsType (FORM | LIST | CAT)* }
    ContentsType ::= ID     - a hint or an "abstract data type" ID

    LIST         ::= 'LIST' #{ ContentsType PROP* (FORM | LIST | CAT)* }
    PROP         ::= 'PROP' #{ FormType Property* }

In this extended regular expression notation, the token '#' represents a
count of the following {braced} data bytes.  Literal items are shown in
"quotes", [square bracketed items] are optional, and "*" means 0 or more
instances.  A sometimes-needed pad byte is shown as "[0]".

@ENDNODE


@Node 16-2-8-3 " Appendix A. Reference / Example Diagrams "
Here's a box diagram for an example IFF file, a raster image FORM @{"ILBM" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-1}.
This @{"FORM" link 16-1-4 52} contains a bitmap header property @{"chunk" link 16-2-3-6} @{"BMHD" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-1}, a color map
property chunk @{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2}, and a raster data chunk @{"BODY" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-3-2}.  This particular raster
is 320 x 200 pixels x 3 bit planes uncompressed.  The "0" after the CMAP
chunk represents a zero pad byte; included since the CMAP chunk has an odd
length.  The text to the right of the diagram shows the outline that would
be printed by the IFFCheck utility program for this particular file.


	          +----------------------------+
	          |                            |
	          |  "FORM"            24070   |  FORM 24070 ILBM
	          |                            |
	       -  +----------------------------+
	       |  |                            |
	       |  |    "ILBM"                  |
	       |  |                            |
	       |  |  +----------------------+  |
	       |  |  |  "BMHD"         20   |  |  .BMHD 20
	       |  |  |----------------------|  |
	       |  |  |  320, 200, 0, 0, 3,  |  |
	       |  |  |  0, 0, 0, ....       |  |
	       |  |  +----------------------+  |
	       |  |                            |
	24070 <   |  +----------------------+  |
	 bytes |  |  |  "CMAP"         21   |  |  .CMAP 21
	       |  |  |----------------------|  |
	       |  |  |  0, 0, 0; 32, 0, 0;  |  |
	       |  |  |  64, 0, 0 ...        |  |
	       |  |  +----------------------+  |
	       |  |     0                      |
	       |  |  +----------------------+  |
	       |  |  |  "BODY"      24000   |  |
	       |  |  |----------------------|  |  .BODY 24000
	       |  |  |  0, 0, 0....         |  |
	       |  |  +----------------------+  |
	       |  |                            |
	       -- +----------------------------+


This second diagram shows a @{"LIST" link 16-1-7 49} of two FORMs ILBM sharing a common @{"BMHD" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-1}
property and a common @{"CMAP" link ADCD_v1.2:Reference_Library/Devices/dev_A_FS_ILBM/16-3-2-2} property.  Again, the text on the right is an
outline  la IFFCheck.


	        +------------------------------+
	        | "LIST"              48114    |
	        +------------------------------+
	        |                              |
	        |   "ILBM"                     |
	        |                              |
	        |  +------------------------+  |
	        |  |  "PROP"        62      |  | .PROP 62 ILBM
	        |  +------------------------+  |
	        |  |                        |  |
	        |  |  "ILBM"                |  |
	        |  | +--------------------+ |  |
	        |  | |  "BMHD"       20   | |  | ..BMHD 20
	        |  | |--------------------| |  |
	        |  | |  320, 200, 0, 0, 3,| |  |
	        |  | |  0, 0, 0, ....     | |  |
	        |  | +--------------------+ |  |
	        |  |                        |  |
	        |  | +--------------------+ |  |
	        |  | |  "CMAP"       21   | |  | ..CMAP 21
	        |  | |--------------------| |  |
	        |  | |  0, 0, 0; 32, 0, 0;| |  |
	        |  | |  64, 0, 0 ....     | |  |
	        |  | +--------------------+ |  |
	        |  |   0                    |  |
	        |  +------------------------+  |
	        |                              |
	        |                              |
	        |  +------------------------+  |
	        |  |  "FORM"        24012   |  | .FORM 24012 ILBM
	        |  +------------------------+  |
	        |  |                        |  |
	        |  |  "ILBM"                |  |
	        |  | +--------------------+ |  |
	        |  | |  "BODY"    24000   | |  | ..BODY 24000
	        |  | |--------------------| |  |
	        |  | |  0, 0, 0....       | |  |
	        |  | +--------------------+ |  |
	        |  +------------------------+  |
	        |                              |
	        |                              |
	        |  +------------------------+  |
	        |  |  "FORM"        24012   |  | .FORM 24012 ILBM
	        |  +------------------------+  |
	        |  |                        |  |
	        |  |  "ILBM"                |  |
	        |  | +--------------------+ |  |
	        |  | |  "BODY"    24000   | |  | ..BODY 24000
	        |  | |--------------------| |  |
	        |  | |  0, 0, 0....       | |  |
	        |  | +--------------------+ |  |
	        |  +------------------------+  |
	        |                              |
	        |                              |
	        +------------------------------+

@ENDNODE
