The Jitter File Format (JXF) stores matrix data in a binary (not human-readable) form.
When using Jitter you can create JXF files by sending the write message to a jit.matrix object. Conversely you can read JXF files from disk using the read message. This section will cover first the API functions that one can use from C to read and write JXF files. Then it will break down the file format at the bit level.
Most Jitter users do not need or want to know about the internal binary format of a JXF-file. Even users who want to read and write JXF-files from C do not need to know the internal details if they use the functions of the Jitter API for the binary interface. Not only is the API more convenient, but using the functions provided by Cycling '74 may protect your code from having to be altered in the future in the event of a specification change.
There are two primary functions one should use to read data from a JXF file. jit_bin_read_header() reads the version number and the size of the file from the header, and has the following signature:
jit_bin_read_matrix() imports matrix data from a file to a matrix, resizing the matrix if necessary, and has the following signature:
Here’s a chunk of code that shows how to read a matrix from disk:
Similarly there are two functions one should use when writing data to a JXF file. jit_bin_write_header() writes a header to a file, and has the following signature:
jit_bin_write_matrix() writes a matrix to a file, and has the following signature:
Here’s a section of code that shows how you might write a file with one matrix. Note that the initial filesize argument to jit_bin_write_header() is bogus, but that the header is written again at the end of the operation when the filesize can be determined from the file position after writing the matrix.
The internal format of JXF-files is based on the Interchange File Format (IFF) (http://en.wikipedia.org/wiki/Interchange_File_Format). An IFF file is built up from chunks. All data in IFF files is big-endian. Several convenience macros defined in jit.byteorder.h are available to help convert numbers to the proper format before and after they're written to and read from a JXF file: BE_I32() can be called on 32-bit integers, BE_F32() on 32-bit floats, and BE_F64() on 64-bit doubles.
Each chunk in an IFF file begins with a four character Type ID. This is followed by a 32-bit unsigned integer specifying the size of the chunk content in bytes. In a JXF file, the 32-bit integer part of the first chunk tells us the size of the file, and all the subsequent chunks, which begin immediately after the first chunk, contain matrices. In the future chunks may also be used to store other kinds of data.
Here is a tabular overview of an example minimal JXF file.
Container Chunk
groupID | JIT_BIN_CHUNK_CONTAINER ('FORM') |
File size | 32-bit int |
IFF Type | JIT_BIN_FORMAT ('JIT!') |
Format Chunk | |
chunkID | JIT_BIN_CHUNK_FORMAT_VERSION ('FVER') |
Chunk size | 12 bytes |
Version | JIT_BIN_VERSION_1 (0x3C93DC80) |
Matrix Chunk | |
chunk ID | JIT_BIN_CHUNK_MATRIX ('MTRX') |
chunk size | 32-bit int |
offset | 32-bit int |
type | 4-char |
planecount | 32-bit int |
dimcount | 32-bit int |
dim | Array of 32-bit ints that contain the dimensions |
data |
The data offset of the matrix chunk represents the offset, in bytes, from the beginning of the chunk to the beginning of the data portion of the chunk. The type is one of CHAR, LONG, FL32 and FL64. The dim array contains dimcount elements, each of which is a 32-bit int. The data portion consists of the cells of the matrix written out one at a time in row-major order. Planar data is multiplexed in each cell. For example, a 3-plane 2 by 2 matrix would be written out in the following order:
Plane | Dim 0 | Dim 1 |
0 | 0 | 0 |
1 | 0 | 0 |
2 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 0 |
2 | 1 | 0 |
0 | 0 | 1 |
1 | 0 | 1 |
2 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
2 | 1 | 1 |
The various chunks discussed above can be represented by the C structs listed below: