/iffdigest

A lightweight C++ library for parsing the structure of a file structured using the EA-IFF-85 file format (such as an AIFF file or various legacy Amiga file formats) or the Microsoft RIFF format (such as WAV files, AVI files and SoundFonts), creating an in-memory map which may be used for retrieving parts of it.

Primary LanguageC++

iffdigest v0.3  A lightweight parser for in-memory EA-IFF-85/RIFF structures

Andrew C. Bulhak  13/2/2002


What is it?
-----------

iffdigest is a minimal, lightweight library for parsing the structure of a
file in the EA-IFF-85 file format (such as an AIFF file or various legacy 
Amiga file formats) or the related Microsoft RIFF format (such as WAV files,
AVI files and SoundFonts, among others).

 - iffdigest does not read files, but works on an in-memory image of the 
   file contents.  For small files, loading the entire file into memory will
   work.  Larger files may be accessed efficiently by using memory-mapped I/O
   (i.e., with the mmap() system call under all modern UNIX systems). The
   example program uses this method.

 - iffdigest is very lightweight; the source is contained in two files
   (the source file and a header file) which can be easily incorporated into
   larger projects which happen to need IFF/RIFF parsing.

 - The data structures created by iffdigest are also lightweight; they do not
   contain copies of the IFF file's data, but only pointers into the memory
   image of the file.  This saves on copying, and makes the format ideal for
   transitory, short-term data structures for use in constructing a 
   more specialised higher-level representation.

 - iffdigest is written in C++, and uses the Standard Template Library (STL) 
   for its internal data structures (as it's pretty much universally available,
   an uncommonly civilised way of doing things for C/C++).  Modern compilers
   (including GNU C++) should have no problems; though if you don't have 
   templates, I'm afraid there's not much that can be done.

 - iffdigest was developed on MacOS X (Darwin), but should compile on Linux 
   and other modern unices.   Byte-order handling should be determined at
   compile-time.  If it doesn't work, and you're on a big-endian system,
   define the C preprocessor symbol __BIG_ENDIAN__.

Using iffdigest

Look at ifflist.c and wavtest.c for an example.   The general procedure is:

 - Get your data somewhere where you can get a const char * to it (see the 
   note above about mmap())

 - Create an IFFDigest() object, initialised with a pointer to the data and
   the length of the buffer to look at (for checking).  This step will analyse
   the buffer and create a data structure, mapping out its chunks.

 - To determine whether the data parsed correctly, check the result of the 
   object's valid() method.  If it returns true, you're good to go.

 - The IFFDigest object contains a list of IFFChunk objects; each one of which
   contains a (possibly empty) list of sub-chunks and (if applicable) a 
   pointer and size to the chunk's data.  (Note that this points into the 
   buffer you fed into IFFDigest(), and is not copied; the structure is 
   very lightweight, and only points to the data in the buffer analysed.  
   Needless to say, do not delete or free this buffer until you're finished 
   with your IFFDigest.)

   - Each chunk has an ID field (returned by id() or id_str()). 
     For efficiency, IDs are stored in 32-bit integers, of type iff_ckid_t.
     The utility function iff_ckid() converts a string into an integer ID, and
     may be used for specifying chunk IDs as strings.

   - in the case of LIST chunks, the chunk's ID is not 'LIST', but the 
     list subtype.  (The reasoning being that adding an extra field would be 
     redundant, as the fact that the chunk has subchunks indicates that it is 
     a LIST.)

   - You can obtain STL iterators to an IFFDigest or IFFChunk's subchunk list
     with the ck_begin() and ck_end() methods.  See the STL documentation for
     more information on iterators.

   - To find the first chunk in IFDigest or IFChunk's subchunk list matching
     a chunk ID, use the ck_find() method; i.e., 

       IFFChunkIterator i_comt = digest.findChunk(iff_ckid("COMT"));
       if(i_comt != digest.ck_end()) {
         // here *i_comt is the IFFChunk pointing to the first COMT chunk
       }

       the findNextChunk(iter, id) method returns an iterator pointing to the 
       next chunk matching id after iter, or ck_end() if none.

   - IFFDigest and IFFChunk also have methods for returning various other 
     information.  See iffdigest.h for details.

Sample programs

iffdigest comes with two trivial sample programs to demonstrate usage:

  - ifflist lists the structure of an IFF or RIFF file, including 
    nested chunks in RIFF LIST structures, and shows the first 12 bytes
    of each chunk.

  - wavtest demonstrates how to use iffdigest to look for and read the
    contents of a specific chunk; given the name of a WAV file on the 
    command line, it uses the ck_find method to find the "fmt " chunk,
    and then extracts and prints information about the WAV file from 
    this chunk.  An error message is printed if the file does not have a
    "fmt " chunk.

Bugs

  - iffdigest's EA-IFF-85 support is rudimentary; no chunk-specific handling
    has been implemented for special chunk types.  However, it seems to work 
    acceptably on AIFF files.

History
  v0.1 - initial release; basic IFF parsing in place.
  v0.2 - ck_find()/ck_findNext() methods added; 
         wavtest example added 
  v0.3 - added the iff_[us]xx_[bl]e() utility functions for reading 
         integer values in a specific byte order.

Licence

iffdigest is distributed under the GNU General Public Licence.