From MultimediaWiki
Jump to navigation Jump to search

IFF (Interchange File Format) is a format developed by electronic arts in the 80's. It is the predominant format on the Amiga computer. It is a chunked format. It can be used to store any type of data, but it is predominantly used to store images, animations and audio.


  • xine has a demuxer/decoder for iff. Manfred Tremmel the author of the xine code has agreed to relicence his xine code as LGPL to allow easier use in ffmpeg. Thanks Manfred.
  • Werner Randelshofer the author of multishow has also granted permission for his iff code to be relicenced as LGPL. Thanks Werner.
  • Xanim also contains code to support iff, it may contain some formats not available in xine.
  • libiffanim supports lots of animation formats http://www-user.tu-chemnitz.de/~womar/projects/iffanim/
  • Virtualdub contains a demuxer/decoder also, look in the file InputFileANIM.cpp

Generic Chunk Format

typedef struct {
    char FOURCC[4];
    int32_t chunk_size;
    uint8_t data[size];
} IFF_chunk;

IFF chunks are always padded to an even number of bytes. The possible padding byte is not included in chunk_size.

Example of a chunked IFF file:


Table Of Chunks

Note: FOURCCs of less than four characters are padded with spaces.

Group Identifiers
FOURCC Standard Description
END unofficial END-of-FORM identifier (see Amiga RKM Devices Ed. 3 page 376)
TREE Storage of arbitrary data structures like trees and nested lists
Text, annotations, et cetera
FOURCC Standard Description
(c) EA85 Copyright
ANNO EA85 Annotation
AUTH EA85 Author
CHRS EA85 Character String
CSET Character Set
FTXT EA85 Formatted Text
FVER Amiga OS Version String
HLID private HotLink IDentification (Soft-Logik)
JUNK Ignore
NAME EA85 Title of image, music, ...
OCMP EA85, reserved Computer Property
OCPU EA85, reserved CPU Property
OPGM EA85, reserved Program Property
OSN EA85, reserved Serial Number Property
PTXT private, reserved
TEXT EA85 Unformatted ASCII Text
UNAM EA85, reserved Username Property
VERS File Version Number
Graphics Forms
FOURCC Standard Description
ACBM Amiga Contiguous Bitmap (AmigaBasic)
ACBM.ABIT Amiga Bitplanes
CHBM private Chunky Bitmap
DCCL private DCTV Paint Clip
DCPA private DCTV Paint Palette
DCTV private DCTV Raw Picture
DEEP Chunky Pixel Image Files (TV Paint)
DR2D 2D Object, Vector Graphics
DRAW reserved Jim Bayless, 12/90
DSDR private DrawStudio
GRYP proposal Byteplane Storage
ILBM EA85 Raster Bitmap Form
ILBM.* See ILBM Chunks below
OB3D proposal 3D Object
PBM 256-Color Chunky Pixel
PICS EA85, reserved Macintosh Picture
PICS.PICT EA85, reserved Macintosh Picture
PLBM EA85, reserved Obsolete
RGB4 private 4-bit RGB
RGB8 RGB Image, Turbo Silver (Impulse)
RGBN RGB Image, Turbo Silver (Impulse)
RGBX private, reserved
SC3D private 3D Scene, Sculpt-3D
TDDD 3D Rendering Data, Turbo Silver (Impulse)
YUVN YUV Image Data, MacroSystems
ILBM Chunks
FOURCC Standard Description
3DCM reserved by Haitex
3DPA reserved by Haitex
ASDG private ASDG Application
BHBA private Photon Paint (brushes)
BHCP private Photon Paint (screens)
BHSM private Photon Paint
BMHD EA85 ILBM Bitmap Header
BODY EA85 Image Data
CAMG Amiga Viewport Modes
CCRT Graphicraft Color Cycling
CLUT Color Lookup Table
CMAP EA85 8-bit RGB Color Map (packed array of ColorRegisters)
CMYK CMYK Color Map (Soft-Logik)
CNAM Color Naming Chunk, providex names for CMAP and/or CMYK (Soft-Logik)
CRNG Color Cycling
CTBL.DYCP Newtek Dynamic Ham Color
DCOL unofficial Direct Color
DCTV reserved
DEST Destination Image Info
DGVW private Newtek DigiView
DLTA Image Data
DPI Dots Per Inch
DPPV DPaint Perspective (EA)
DRNG DPaint IV Enhanced Color Cycling (EA)
EPSF Encapsulated Postscript
FAX3 private GPSoftware FAX
FAXX Fascimile Image
FAXX.GPHD Additional Header Info for FAXX forms
GRAB Hotspot Coordinates
MFAX private, reserved TKR GmbH & Co.
PCHG Line-by-line Palette Control Information
PRVW proposal Preview (thumbnail)
SHAM Sliced HAM Color
SPRT Sprite Identifier
TMAP reserved Transparency Map
VTAG proposal Viewmode Tags
XBMI Extended Bitmap Information (Soft-Logik)
XSSL Identifier for 3D X-Specs Image (Haitex)
Audio and Music
FOURCC Standard Description
8SVX EA85 8-bit Sound Sample
8SVX.ATAK Attack Envelope
8SVX.CHAN.PAN Stereo chunks
8SVX.SEQN.FADE Looping chunks
8SVX.RLSE Release Envelope
8SVX.VHDR Voice Header
AHIM private AHI Modes
AHIM.AUDN private Audio Driver Name
AHIM.AUDD private Audio Driver Data
AHIM.AUDM private Audio Mode
AIFF Audio 1-32 bit Samples
AIFF.COMM Channels, samples/frame, samplesize and samplerate
AIFF.INST Instrument, sustain and release
AIFF.SSND Sound Data
AIFF.COMT Extended Comment
ASIF Apple ][ gs Sampled Instrument Format
ASIF.INST Instrument
BANK private Soundquest Editor/Librarian MIDI Sysex Dump
CELP proposal Compressed ZyXEL Voice Data
CMUS proposal Common Musical Score
DS16 private KayPENTAX Computerized Speech Lab (CSL)
GSCR EA85 General Music Score
MIDI private Circum Design
MSCX private Music-X Format
SAMP Sampled Sound
SYTH private SoundQuest Master Librarian MIDI System Driver
TRKR proposal MOD Tracker Music
USCR EA85, reserved Uhuru Score
UVOX EA85, reserved Uhuru Mac Voice
FOURCC Standard Description
CPFM private Cloanto Personal Fontmaker
FNTR EA85, reserved Raster Font
FNTV EA85, reserved Vector Font
Animation and Movies
FOURCC Standard Description
AHAM private
ANBM Animated Bitmap (Framer, Deluxe Video)
ANIM Cel Animation
ANIM.brush Brushes
ANIM.op6 Stereo, 3D Animation
ANIM.op7 private, unregistered
DPAN Deluxe Paint Animation
FANT Fantavision Movie
FIGR private Deluxe Video
FILM private Store ILBM's with interleaved 8SVX audio
JMOV private, reserved Merging Technologies
ROXN private
VDEO private Deluxe Video
YAFA private, unregistered Wildfire Animation
Unclassified, unknown, et cetera
FOURCC Standard Description
ARC proposal Archive Format
ARES private, unregistered
ATXT reserved
AVCF private AmigaVision Flow format
BBSD private BBS Database, F. Patnaude, Jr., Phalanx Software
C100 private Cloanto Italiaformat
CLIP private CAT CLIP, holds various clipboard formats
DECK private Inovatronics CanDo
DOC private PageStream
DTYP DataTypes Identification
EXEC proposal Executable Code
FRED private ASDG Global Chunk
GMS Gesture and Motion Signal (see libGMS)
GUI proposal, private Graphical User Interface Storage
HEAD Flow Idea Processor, New Horizons Software
INFO proposal Contains data usually found in .info file
IOBJ private, reserved Seven Seas Software
IODK private, reserved Jean-Marc Porchet, Merging Technologies
ITRF private, reserved
MSMP reserved
MTRX Numerical Data Storage, MathVision - Seven Seas
NSEQ private Numerical Sequence, Stockhausen GmbH
PGTB Program Traceback (SAS Institute)
PMBC proposal, reserved Black Belt System, 1991-12-01
PREF private, reserved Commodore, User Preferences
PREF.AHI private AHI Global Preferences
PREF.AHIU private AHI Unit Preferences
PRSP DPaint IV Perspective Move
PTCH private Patch File, SAS Institute
SHAK private Shakespeare Format
SHO1 private, reserved Gary Bonham
SHOW private, reserved Gary Bonham
SPLT ASDG's File Splitting System
SSRE private, reserved Merging Technologies, 1992-05-04
SWRT private, unregistered
TCDE private, reserved Merging Technologies
TERM private, unregistered
TMUI Toolmaker IFF Project (Toolmaker v1.19)
WORD ProWrite Document, New Horizons
WOWO private, unregistered Wordworth

Chunks Internals

Described below is how the data part of specific chunks are to be interpreted.


ACBM is similar to ILBM except that the BODY chunk is replaced by an ABIT chunk.

An ABIT chunk conains non-interleaved, plane-by-plane planar image data. This format was conceived because it hugely sped up loading and saving screens from AmigaBasic.


AIFF provides a standard for storing sampled sounds.

  • COMM
typedef struct {
 int16_t  numChannels;          /* 1 = mono, 2 = stereo, 4 = four channels, et cetera */
 uint32_t numSampleFrames;      /* one Sample Frame consists of numChannels samples */
 int16_t  sampleSize;           /* 1 .. 32 bits */
 uint8_t  sampleRate[10];       /* 80-bit ANSI/IEEE Std 754-1985 Floating Point */
} COMM_data;
  • SSND
typedef struct {
 uint32_t offset;               /* offset into SoundData[]; used for block-aligned sound data; mostly 0 */
 uint32_t blockSize;            /* mostly 0; used in conjunction with offset for block-aligned data */
 uint8_t  SoundData[];
} SSND_data;

Sample points are signed and stored, left-shifted to a multiple of eight bits. The padding bits are zeroed. Multi-channel audio is interleaved sample by sample.

 1.. 8 bits --> 1 byte
 9..16 bits --> 2 bytes
17..24 bits --> 3 bytes
25..32 bits --> 4 bytes

Multi-channel audio conventions:

1 2 3 4 5 6
stereo left right
3 channels left right center
quad front left front right rear left rear right
4 channels left center right surround
6 channels left left center center right right center surround
  • MARK

Markers can be used e.g. for instrument loops.

typedef struct {
 uint16_t numMarkers;
 struct {
  uint16_t id;               /* any 16-bit value, but not the same as a previous marker */
  uint32_t position;         /* relative to the start of the sample; units = SampleFrames */
  char     markerName[];     /* Pascal-style string, i.e. length + length characters */
 } Markers[];
  • INST
  • MIDI
  • COMT



Gradually in- or decrease VHDR's volume. Multiple ATAK and RLSE chunks can be used to create a full ADSR (Attack, Decay, Sustain, Release) envelope.

typedef struct {
 uint16_t duration;        /* in milliseconds */
 int32_t  dest;            /* destination volume, 0 = off, 0x10000 = max */
} EGPoint;


Images are stored in planes. So, to get a pixels color value you need to combine the bits from each plane to create a color register index.

typedef struct {
 uint16_t w;                    /* raster width in pixels */
 uint16_t h;                    /* raster height in pixels */
 int16_t  x;                    /* x offset in pixels */
 int16_t  y;                    /* y offset in pixels */
 uint8_t  nplanes;              /* # source bitplanes */
 uint8_t  masking;              /* masking technique, 0 = mskNone, 1 = mskHasMask, 2 = mskHasTransparentColor, 3 = mskLasso */
 uint8_t  compression;          /* compression algoithm, 0 = cmpNone, 1 = cmpByteRun1 */
 uint8_t  pad1;                 /* UNUSED.  For consistency, put 0 here. */
 uint16_t transparentColor;     /* transparent "color number" */
 uint8_t  xaspect;              /* aspect ratio, a rational number x/y */
 uint8_t  yaspect;              /* aspect ratio, a rational number x/y */
 int16_t  pagewidth;            /* source "page" size in pixels */
 int16_t  pageheight;           /* source "page" size in pixels */
} BitMapHeader;



The BODY's content is a concatenation of scanlines. Each scanline consists of one row of data for each plane, starting at plane 0, followed by one row of masking data (if BMHD.maskinh = mskHasMask). If BMHD.compression = cmpNone, all h rows are exactly ceil(w/16) uint16_t's wide.


The BODY contains data samples grouped by octave, the highest octave first. Each sample is an 8-bit signed number.

ByteRun1 Algorithm

   0 <= x <= 127  x+1 literals
-127 <= x <= -1   -x+1 times next byte
-128              unused

Each row of each scanline is compressed separately.

Fibonacci Delta Compression

This is a lossy data compression. It resembles traditional delta encoding, but stores the delta value in 4-bits. Small delta's are encoded exact, large delta's are approximated.

The bitstream format:

uint8_t pad;
uint8_t initial_value;
uint8_t data[];            /* i.e. two codes/nibbles per byte */

Four bit LUT:

int8_t codeToDelta[16] = {
    -34, -21, -13, -8, -5, -3, -2, -1,
      0,   1,   2,  3,  5,  8, 13, 21


typedef int32_t viewportMode;


The optional CHAN chunk gives information about the sample type.

typedef int32_t sampletype;       /* 2 = left, play mono sample left
                                   * 4 = right, play mono sample right
                                   * 6 = stereo, the BODY contains two channels, left first */

The optional PAN chunk makes it possible to pan a mono sample.

typedef int32_t sposition;        /* 0 = right, 0x8000 = center, 0x10000 = left */


typedef struct {
 struct {
  uint8_t red;
  uint8_t green;
  uint8_t blue;
 } colormap[chunk_size / 3];
} ColorMap;


typedef struct {
 int16_t direction;     /* 0 = none, >0 = forwards, <0 = backwards */
 uint8_t start;         /* lower... */
 uint8_t end;           /* ...and upper color registers */
 int32_t seconds;       /* seconds between cycles */
 int32_t microseconds;  /* microseconds between cycles */
 int16_t pad;           /* 0 */
} CycleInfo;


typedef struct {
 int16_t pad1;        /* 0 */
 int16_t rate;        /* color cycle rate, 16384 = 60Hz */
 int16_t active;      /* 0 = off, >0 = on */
 uint8_t low;         /* lower... */
 uint8_t high;        /* ...and upper color registers */
} CRange;


typedef struct {
 uint8_t  depth;           /* # bitplanes in the original source */
 uint8_t  pad1;            /* 0 */
 uint16_t planePick;       /* how to scatter source bitplanes into destination */
 uint16_t planeOnOff;      /* default bitplane data for planePick */
 uint16_t planeMask;       /* which bitplanes to store into
} DestMerge;


Hotspot, relative to the upper left corner. Think mouse cursor or paint brush.

typedef struct {
 int16_t x;
 int16_t y;
} Point2D;


SEQN chunks define a sequence of segments within the voice waveform that should be played in order. This way, parts of the waveform can be played multiple times.

int number_of_segments = chunk_size / 8;

typedef struct {
 struct {
  uint32_t segment_start;         /* offsets must be 32-bits aligned and are relative to the start of the High Octave voice */
  uint32_t segment_end;
 } segments[number_of_segments];
} SEQN_data;

oneShotHiSamples should be set to 0 and repeatHiSamples should be equal to the waveform length (divided by two if CHAN defines it as stereo).

The FADE chunks defines when the sound has to slowly fade-out to silence.

typedef struct {
 uint32_t segment;                /* start fade-out at this segment */
} FADE_data;


typedef uint16_t SpritePrecedence; /* relative precedence; 0 is highest */


A Voice holds waveform data for one or more octaves. The one-shot part is played once and the repeat part is looped. The sum of oneShotHiSamples and repeatHiSamples is the full length of the highest octave waveform. Each following octave waveform is twice as long as the previous one.

typedef struct {
 uint32_t oneShotHiSamples;       /* length of highest octave one-short part */
 uint32_t repeatHiSamples;        /* length of highest octave repeat part */
 uint32_t samplesPerHiCycle;      /* frequency */
 uint16_t samplesPerSec;          /* samplerate */
 uint8_t  ctOctave;               /* number of octaves of waveforms */
 uint8_t  sCompression;           /* 0 = none, 1 = Fibonacci Delta Encoding */
 int32_t  volume;                 /* 0 = silent, 0x10000 = max */
} Voice8Header;