LIFF: Long Interchange File Format
LIFF will be a format that is essentially a clone of IFF and RIFF, with a
few exceptions:
It will support multiple modes of differing tag, chunk, and alignment size.
Tags will be catagorized into one of a number of groups: EIGHTCC; FOURCC;
TWOCC; ONECC.
Only EIGHTCC and FOURCC types are allowed in the main body.
TWOCC and ONECC will be usable within some chunks in a context dependent
manner (the main reason for this is to allow possible dense packing of small
data).
Tags are allowed to consist of a series of ascii characters (0x20..0x7E)
padded out to their length with spaces, eg: 'foo' is represented by the FOURCC
'foo ' and the EIGHTCC 'foo '. A FOURCC and EIGHTCC
are viewed as equivalent if the first 4 characters match and the last 4 characters
of the EIGHTCC is ' '.
Upper case tag names will be used for 'common' tag names. Lower case tags
will be used for context specific purposes (eg: various data chunks or other
chunks/lists related to a particular form type).
Chunks with the last byte < 0x20 or > 0xDF will be viewed as integers
(with those with a last byte in the range 0xE0 to 0xFF being viewed as negative)
and usable for context-specific uses, eg, indexing a string table or such,
but should not be used as numberic constant tags.
Tags with last bytes in the range of 0x7F to 0xDF are reserved and should
be rejected by parsers (eg: viewing the file as being syntactically invalid).
All multibyte integers within the general LIFF structure will be in little-endian
byte ordering.
The files will be organized as a tree of chunks, with the toplevel representing
the entire contents of the file (and generally referred to as the "form"
of the file).
struct Chunk64_s {
EIGHTCC ckId;
QWORD ckSize;
};
Will be a 64 bit chunk, with a 64 bit natural alignment.
struct Chunk32_s {
FOURCC ckId;
DWORD ckSize;
};
Will be a 32 bit chunk, with a 32 bit natural alignment.
struct Chunk16_s {
TWOCC ckId;
WORD ckSize;
};
Will be a 16 bit chunk, with a 16 bit natural alignment.
struct Chunk8_s {
ONECC ckId;
BYTE ckSize;
};
Will be a 8 bit chunk, with a 1 byte natural alignment.
Toplevel
The toplevel chunk will always be a 64 bit chunk, however, the contents are
allowed to be either 64 or 32 bits.
The first 64 bits of the body will by the form type, depending on the file
type.
'LIFF64 ': A 64 bit LIFF file.
'LIFF32 ': A 32 bit LIFF file.
The contents of the toplevel are constrained to being either a plain or string
indexed list (as a result, other uses of integer tags are disallowed).
LIST Chunks
A list chunk will be like the toplevel form in that the first 4 or 8 bytes
will define the list type (depending on the parent chunk type).
All lists will require that each chunk be aligned on a boundary of the list
size, eg, 8, 4, 2, or 1 bytes.
64bit List Chunks
'LIST ': This will be a 64 bit list;
'LIST32 ': This will be a 32 bit list;
'LIST16 ': This will be a 16 bit list;
'LIST08 ': This will be an 8 nit list.
32bit List Chunks
'LIST': This will be a 32 bit list;
'LI16': This will be a 16 bit list;
'LI08': This will be an 8 bit list.
The meaning of any integer tags will be left to the list type.
In the 8 and 16 bit types no meaning is given to the type code (eg: they
may be used as integer constants or whatever), but should be used to convey
the chunk type.
String Indexed LIST Chunks
These will be similar to list chunks, with an important difference being
that a strings table (or a reference to it) is required to be located before
any chunks with integer tags (them being effectively offsets into the strings
table).
An additional requirement is that byte 0 of the strings table allways be
0 (thus the string 0 will always be "").
The strings table may be ommited in the case where there are no tags with
integer values. A string table offset is still optionally allowed in this
case but is required to have a value of 0.
'STRINGS '/'STRS': This will be the strings table.
'OSTRINGS'/'OSTR': This will be a 64 or 32 bit offset to the start of the
strings chunk relative to the beginning of the list chunk.
64bit List Chunks
'SLIST ': This will be a 64 bit list;
'SLIST32 ': This will be a 32 bit list;
'SLIST16 ': This will be a 16 bit list;
'SLIST08 ': This will be an 8 nit list.
32bit List Chunks
'SLST': This will be a 32 bit list;
'SL16': This will be a 16 bit list;
'SL08': This will be an 8 bit list.
In the 8 and 16 bit variants, all values > 2 (unsigned) will be indices
into the strings table.
The strings table will have a chunk id of 1, and a strings reference will
have a value of 2. Tag 0 will be used for a junk chunk.
As a result, the first 3 bytes of the table will be 0 for these types.
JUNK Chunks
'JUNK '/'JUNK' will indicate a glob of undefined data used
as padding or as placeholders for deleted chunks.
It will not be acceptable to coalesce JUNK chunks without an understanding
of the form or list type (as an example, particular chunk indices may be
relevant to that form/list type or such).