public class RIFFParser
extends java.lang.Object
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); } . } . }
RIFFVisitor
Modifier and Type | Field and Description |
---|---|
static int |
JUNK_ID
ID for JUNK chunks.
|
static int |
LIST_ID
ID for ListGroupExpression.
|
static int |
NULL_ID
ID for NULL chunks.
|
static int |
NULL_NUL_ID
ID for NULL chunks.
|
static int |
RIFF_ID
ID for FormGroupExpression.
|
Constructor and Description |
---|
RIFFParser()
Constructs a new RIFF parser.
|
Modifier and Type | Method and Description |
---|---|
void |
declareCollectionChunk(int type,
int id)
Declares a collection chunk.
|
void |
declareDataChunk(int type,
int id)
Declares a data chunk.
|
void |
declareGroupChunk(int type,
int id)
Declares a FORM group chunk.
|
void |
declarePropertyChunk(int type,
int id)
Declares a property chunk.
|
void |
declareStopChunks()
Whether the parse should stop at all chunks.
|
void |
declareStopChunkType(int type)
Declares a stop chunk.
|
long |
getStreamOffset() |
static java.lang.String |
idToString(int anInt)
Convert an integer IFF identifier to String.
|
protected boolean |
isCollectionChunk(RIFFChunk chunk)
Checks wether the ID of the chunk has been declared as a
collection chunk.
|
protected boolean |
isDataChunk(RIFFChunk chunk)
Checks whether the ID of the chunk has been declared as a
data chunk.
|
protected boolean |
isGroupChunk(RIFFChunk chunk)
Checks whether the ID of the chunk has been declared as
a group chunk.
|
static boolean |
isGroupID(int id)
Checks wether the argument represents a valid RIFF GroupID.
|
static boolean |
isGroupType(int id)
Checks wether the argument represents a valid RIFF Group Type.
|
static boolean |
isID(int id)
Checks if the argument represents a valid RIFF ID.
|
static boolean |
isLocalChunkID(int id)
Returns whether the argument is a valid Local Chunk ID.
|
protected boolean |
isPropertyChunk(RIFFChunk chunk)
Checks wether the ID of the chunk has been declared as a
property chunk.
|
long |
parse(javax.imageio.stream.ImageInputStream in,
RIFFVisitor v) |
long |
parse(java.io.InputStream in,
RIFFVisitor v)
Interprets the RIFFFile expression located at the
current position of the indicated InputStream.
|
void |
setStreamOffset(long offset) |
static int |
stringToID(java.lang.String aString)
Converts the first four letters of the
String into an IFF Identifier.
|
public static final int RIFF_ID
public static final int LIST_ID
public static final int NULL_ID
public static final int NULL_NUL_ID
public static final int JUNK_ID
public long getStreamOffset()
public void setStreamOffset(long offset)
public long parse(java.io.InputStream in, RIFFVisitor v) throws ParseException, AbortException, java.io.IOException
Pre condition
Post condition
Obligation The visitor may throw an ParseException or an AbortException during tree traversal.
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.java.io.IOException
public long parse(javax.imageio.stream.ImageInputStream in, RIFFVisitor v) throws ParseException, AbortException, java.io.IOException
ParseException
AbortException
java.io.IOException
protected boolean isDataChunk(RIFFChunk chunk)
Pre condition
chunk
- Chunk to be verified.protected boolean isGroupChunk(RIFFChunk chunk)
Pre condition
chunk
- Chunk to be verified.protected boolean isPropertyChunk(RIFFChunk chunk)
Pre condition
protected boolean isCollectionChunk(RIFFChunk chunk)
Pre condition
chunk
- Chunk to be verified.public void declareDataChunk(int type, int id)
Pre condition
Post condition
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.public void declareGroupChunk(int type, int id)
Pre condition
Post condition
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.public void declarePropertyChunk(int type, int id)
Pre condition
Post condition
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.public void declareCollectionChunk(int type, int id)
Pre condition
Post condition
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.public void declareStopChunkType(int type)
Pre condition
Post condition
type
- Type of the chunk. Must be formulated as a TypeID conforming
to the method #isFormType.public void declareStopChunks()
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.
public static boolean isGroupID(int id)
Validation
id
- Chunk ID to be checked.public static boolean isGroupType(int id)
Validation
id
- Chunk ID to be checked.public static boolean isID(int id)
Validation
id
- Chunk ID to be checked.public static boolean isLocalChunkID(int id)
Validation
id
- Chunk ID to be checked.public static java.lang.String idToString(int anInt)
anInt
- ID to be converted.public static int stringToID(java.lang.String aString)
aString
- String to be converted.