Abstract
RIFF File Format A RIFF file consists of a RIFF header followed by zero or more lists and chunks.
The RIFF header has the following form:
'RIFF' fileSize fileType (data)where 'RIFF' is the literal FOURCC code 'RIFF', fileSize is a 4-byte value giving the size of the data in the file, and fileType is a FOURCC that identifies the specific file type. The value of fileSize includes the size of the fileType FOURCC plus the size of the data that follows, but does not include the size of the 'RIFF' FOURCC or the size of fileSize. The file data consists of chunks and lists, in any order.
FOURCCs
A FOURCC (four-character code) is a 32-bit unsigned
integer created by concatenating four ASCII characters. For example, the
FOURCC 'abcd' is represented on a Little-Endian system as 0x64636261. FOURCCs
can contain space characters, so ' abc' is a valid FOURCC. The RIFF file
format uses FOURCC codes to identify stream types, data chunks, index
entries, and other information.
A chunk has the following form:
ckID ckSize ckDatawhere ckID is a FOURCC that identifies the data contained in the chunk, ckData is a 4-byte value giving the size of the data in ckData, and ckData is zero or more bytes of data. The data is always padded to nearest WORD boundary. ckSize gives the size of the valid data in the chunk; it does not include the padding, the size of ckID, or the size of ckSize.
A list has the following form:
'LIST' listSize listType listDatawhere 'LIST' is the literal FOURCC code 'LIST', listSize is a 4-byte value giving the size of the list, listType is a FOURCC code, and listData consists of chunks or lists, in any order. The value of listSize includes the size of listType plus the size of listData; it does not include the 'LIST' FOURCC or the size of listSize.
For more information see: http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/aboutriff.asp
Grammar for RIFF streams used by this parser
RIFFFile ::= 'RIFF' FormGroup
GroupChunk ::= FormGroup | ListGroup FormGroup ::= size GroupType [ ChunkID LocalChunk [pad] | 'LIST ' ListGroup [pad] } ListGroup ::= size GroupType [ ChunkID LocalChunk [pad] | 'LIST ' ListGroup [pad] }
LocalChunk ::= DataChunk | CollectionChunk | PropertyChunk DataChunk ::= size [ struct ] CollectionChunk ::= size [ struct ] PropertyChunk ::= size [ struct ]
size ::= ULONG GroupType ::= FourCC ChunkID ::= FourCC pad ::= (BYTE)0 struct ::= any C language struct built with primitive data types.
Examples
Traversing the raw structure of a RIFF file
To traverse the file structure you must first set up a RIFFVisitor object that does something useful at each call to the visit method. Then create an instance of a RIFFParser and invoke the #interpret method.
class RIFFRawTraversal
. {
. static class Visitor
. implements RIFFVisitor
. {
. ...implement the visitor interface here...
. }
.
. public static void main(String[] args)
. {
. try {
. Visitor visitor = new Visitor();
. FileInputStream stream = new FileInputStream(args[0]);
. RIFFParser p = new RIFFParser();
. p.interpret(stream,visitor);
. stream.close();
. }
. catch (IOException e) { System.out.println(e); }
. catch (InterpreterException e) { System.out.println(e); }
. catch (AbortedException e) { System.out.println(e); }
. }
. }
Traversing the RIFF file and interpreting its content.
Since RIFF files are not completely self describing (there is no information that helps differentiate between data chunks, property chunks and collection chunks) a reader must set up the interpreter with some contextual information before starting the interpreter.
Once at least one chunk has been declared, the interpreter will only call the
visitor for occurences of the declared group chunks and data chunks. The
property chunks and the collection chunks can be obtained from the current
group chunk by calling #getProperty or #getCollection.
Note: All
information the visitor can obtain during interpretation is only valid during
the actual #visit... call. Dont try to get information about properties or
collections for chunks that the visitor is not visiting right now.
class InterpretingAnILBMFile
. {
. static class Visitor
. implements RIFFVisitor
. {
. ...
. }
.
. public static void main(String[] args)
. {
. try {
. Visitor visitor = new Visitor();
. FileInputStream stream = new FileInputStream(args[0]);
. RIFFParser p = new RIFFParser();
. p.declareGroupChunk('FORM','ILBM');
. p.declarePropertyChunk('ILBM','BMHD');
. p.declarePropertyChunk('ILBM','CMAP');
. p.declareCollectionChunk('ILBM','CRNG');
. p.declareDataChunk('ILBM','BODY');
. p.interpret(stream,visitor);
. stream.close();
. }
. catch (IOException e) { System.out.println(e); }
. catch (InterpreterException e) { System.out.println(e); }
. catch (AbortedException e) { System.out.println(e); }
. }
. }
- Author:
- Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Switzerland
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intID for JUNK chunks.static final intID for ListGroupExpression.static final intID for NULL chunks.static final intID for NULL chunks.static final intID for FormGroupExpression. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoiddeclareCollectionChunk(int type, int id) Declares a collection chunk.voiddeclareDataChunk(int type, int id) Declares a data chunk.voiddeclareGroupChunk(int type, int id) Declares a FORM group chunk.voiddeclarePropertyChunk(int type, int id) Declares a property chunk.voidWhether the parse should stop at all chunks.voiddeclareStopChunkType(int type) Declares a stop chunk.longstatic StringidToString(int anInt) Convert an integer IFF identifier to String.protected booleanisCollectionChunk(RIFFChunk chunk) Checks wether the ID of the chunk has been declared as a collection chunk.protected booleanisDataChunk(RIFFChunk chunk) Checks whether the ID of the chunk has been declared as a data chunk.protected booleanisGroupChunk(RIFFChunk chunk) Checks whether the ID of the chunk has been declared as a group chunk.static booleanisGroupID(int id) Checks whether the argument represents a valid RIFF GroupID.static booleanisGroupType(int id) Checks whether the argument represents a valid RIFF Group Type.static booleanisID(int id) Checks whether the argument represents a valid RIFF ID.static booleanisLocalChunkID(int id) Returns whether the argument is a valid Local Chunk ID.protected booleanisPropertyChunk(RIFFChunk chunk) Checks wether the ID of the chunk has been declared as a property chunk.booleanlongparse(InputStream in, RIFFVisitor v) Interprets the RIFFFile expression located at the current position of the indicated InputStream.longparse(ImageInputStream in, RIFFVisitor v) voidsetReadData(boolean readData) voidsetStreamOffset(long offset) static intstringToID(String aString) Converts the first four letters of the String into an IFF Identifier.
-
Field Details
-
RIFF_ID
public static final int RIFF_IDID for FormGroupExpression. -
LIST_ID
public static final int LIST_IDID for ListGroupExpression. -
NULL_ID
public static final int NULL_IDID for NULL chunks. -
NULL_NUL_ID
public static final int NULL_NUL_IDID for NULL chunks. -
JUNK_ID
public static final int JUNK_IDID for JUNK chunks.
-
-
Constructor Details
-
RIFFParser
public RIFFParser()Constructs a new RIFF parser.
-
-
Method Details
-
getStreamOffset
public long getStreamOffset() -
setStreamOffset
public void setStreamOffset(long offset) -
parse
Interprets the RIFFFile expression located at the current position of the indicated InputStream. Lets the visitor traverse the RIFF parse tree during interpretation.Pre condition
- Data-, property- and collection chunks must have been declared prior to this call.
- When the client never declared chunks, then all local chunks will be interpreted as data chunks.
- The stream must be positioned at the beginning of the RIFFFileExpression.
Post condition
- When no exception was thrown then the stream is positioned after the RIFFFile expression.
Obligation The visitor may throw an ParseException or an AbortException during tree traversal.
- Throws:
ParseException- Is thrown when an interpretation error occured. The stream is positioned where the error occured.AbortException- Is thrown when the visitor decided to abort the interpretation.IOException
-
parse
public long parse(ImageInputStream in, RIFFVisitor v) throws ParseException, AbortException, IOException - Throws:
ParseExceptionAbortExceptionIOException
-
isDataChunk
Checks whether the ID of the chunk has been declared as a data chunk.Pre condition
- Data chunks must have been declared before the interpretation has been started.
- This method will always return true when neither data chunks, property chunks nor collection chunks have been declared,
- Parameters:
chunk- Chunk to be verified.- Returns:
- True when the parameter is a data chunk.
-
isGroupChunk
Checks whether the ID of the chunk has been declared as a group chunk.Pre condition
- Group chunks must have been declared before the interpretation has been started. (Otherwise the response is always true).
- Parameters:
chunk- Chunk to be verified.- Returns:
- True when the visitor is interested in this is a group chunk.
-
isPropertyChunk
Checks wether the ID of the chunk has been declared as a property chunk.Pre condition
- Property chunks must have been declared before the interpretation has been started.
- This method will always return false when neither data chunks, property chunks nor collection chunks have been declared,
-
isCollectionChunk
Checks wether the ID of the chunk has been declared as a collection chunk.Pre condition
- Collection chunks must have been declared before the interpretation has been started.
- This method will always return true when neither data chunks, property chunks nor collection chunks have been declared,
- Parameters:
chunk- Chunk to be verified.- Returns:
- True when the parameter is a collection chunk.
-
declareDataChunk
public void declareDataChunk(int type, int id) Declares a data chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an RIFFFileExpression.
Post condition
- Data chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isLocalChunkID.
-
declareGroupChunk
public void declareGroupChunk(int type, int id) Declares a FORM group chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an RIFFFileExpression.
Post condition
- Group chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isContentsType.
-
declarePropertyChunk
public void declarePropertyChunk(int type, int id) Declares a property chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an RIFFFileExpression.
Post condition
- Group chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isLocalChunkID.
-
declareCollectionChunk
public void declareCollectionChunk(int type, int id) Declares a collection chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an RIFFFileExpression.
Post condition
- Collection chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.id- ID of the chunk. Must be formulated as a ChunkID conforming to the method #isLocalChunkID.
-
declareStopChunkType
public void declareStopChunkType(int type) Declares a stop chunk.Pre condition
- The chunk must not have already been declared as of a different type.
- Declarations may not be done during interpretation of an RIFFFileExpression.
Post condition
- Stop chunk declared
- Parameters:
type- Type of the chunk. Must be formulated as a TypeID conforming to the method #isFormType.
-
declareStopChunks
public void declareStopChunks()Whether the parse should stop at all chunks.The parser does not read the data body of stop chunks.
By declaring stop chunks, and not declaring any data, group or property chunks, the file structure of a RIFF file can be quickly scanned through.
-
isGroupID
public static boolean isGroupID(int id) Checks whether the argument represents a valid RIFF GroupID.Validation
- Group ID must be one of RIFF_ID, LIST_ID.
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the chunk ID is a valid Group ID.
-
isGroupType
public static boolean isGroupType(int id) Checks whether the argument represents a valid RIFF Group Type.Validation
- Must be a valid ID.
- Must not be a group * ID.
- Must not be a NULL_ID.
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the chunk ID is a valid Group ID.
-
isID
public static boolean isID(int id) Checks whether the argument represents a valid RIFF ID.Validation
- Every byte of an ID must be in the range of 0x20..0x7e
- The id may not have leading spaces (unless the id is a NULL_ID).
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the ID is a valid IFF chunk ID.
-
isLocalChunkID
public static boolean isLocalChunkID(int id) Returns whether the argument is a valid Local Chunk ID.Validation
- Must be valid ID.
- Local Chunk IDs may not collide with GroupIDs.
- Must not be a NULL_ID.
- Parameters:
id- Chunk ID to be checked.- Returns:
- True when the chunk ID is a Local Chunk ID.
-
idToString
Convert an integer IFF identifier to String.- Parameters:
anInt- ID to be converted.- Returns:
- String representation of the ID.
-
stringToID
Converts the first four letters of the String into an IFF Identifier.- Parameters:
aString- String to be converted.- Returns:
- ID representation of the String.
-
isReadData
public boolean isReadData() -
setReadData
public void setReadData(boolean readData)
-