The 3DO file format currently defines chunks for images, cels, and simple flip-book type animations. It also defines several informational chunks for things like copyright notices.
The one nonatomic chunk type is a wrapper type. An entire file (a concatenation of atomic chunks) can be "wrapped" in a single wrapper chunk. Wrapping is optional. Applications should be designed to handle either wrapped or unwrapped files.
The 3DO Company plans to define additional chunk types in the future, including chunks for digital audio and for 3D objects. The 3DO Company intends to coordinate the process of defining new chunk types, and to maintain the central registry of chunk names and definitions. Developers are encouraged to define new chunk types and refine existing chunk types, since the entire development community benefits from having a common file format.
chunk_ID
and the chunk_size
Wrapper Chunks
Wrapper chunks are the only chunks that can contain other chunks. A wrapper chunk must always be the first chunk in a file and must contain all other chunks in the file. The chunk_size
of a wrapper chunk is therefore equal to the file size. A file need not be wrapped.
wrap_chunk
at the beginning of the file. On the Macintosh, you should give the file type `3DO ` to both wrapped and unwrapped 3DO files.
Table 1: RGB chunky files (numplanes = 1) -------------------------------------------------------- File type |Discussion -------------------------------------------------------- 555 RGB |1 pixel is packed right-justified into 2 chunky |bytes. The value of the hvformat flag |determines the meaning of the |most-significant bit. -------------------------------------------------------- 24- bit |1 pixel is packed into 3 bytes. RGB chunky| | -------------------------------------------------------- 8-bit RGB |1 pixel is packed into 1 byte. The encoding chunky |is 332 RGB (or YUV); 3 bits of Red (or Y), 3 |bits of green (or U), and 2 bits of Blue (or |V). For display each component is expanded |into 5 bit quantities forming a 555 RGB (or |YUV) value. Red and Green are left-shifted |two bits, and Blue is left-shifted 3 bits. |The lower bits are 0-filled if hvformat = 0 |and copied from the high bits if hvformat = |1.Having hvformat = 1 allows you to represent |both pure white and pure black when going |from 332 to 555 mode. --------------------------------------------------------
For planar RGB files (numplanes =3), 1 component is stored right-justified in 1byte. For coded or color index images the data is packed as follows:
Table 2: Packed data for coded images -------------------------------------------------------- Bits Per Pixel |Pixels Per Byte -------------------------------------------------------- 8 |1 -------------------------------------------------------- 6 |1 (right justified) -------------------------------------------------------- 4 |2 -------------------------------------------------------- 2 |4 -------------------------------------------------------- 1 |8 --------------------------------------------------------
A coded (color-indexed) image requires a PLUT (pixel lookup table) chunk containing at least 2**(bits per pixel) entries.
{image control chunk} {PDAT chunk containing the pixel values}
Example 1: The 3DO format stores three separate backgrounds which share all image attributes (stored in the image control chunk):
Example 2: 3DO format stores an animation using 10 cels, all the same size, and depth, half of which use one color table (PLUT) and the other half use another color table:
{image control chunk} {PDAT chunk} {PDAT chunk} {PDAT chunk}
{ANIM Control Chunk}
{CEL Control Chunk}
{PLUT Chunk}
{PDAT} {PDAT} {PDAT} {PDAT} {PDAT}
{PLUT Chunk}
{PDAT} {PDAT} {PDAT} {PDAT} {PDAT}
NULL
the data chunk is undefined. For example a chunk of type cel data requires a cel control chunk and can optionally have a PLUT chunk.
{file} ::= {chunk} | {file}{chunk}c
{chunk} ::= {chunk_header}{chunk_body}
{chunk_header} ::= {chunk_ID} {chunk_size}
{chunk_ID} ::= `3DO ` | /* Optional wrapper chunk */
`IMAG'| /* Image Control chunk */
`CCB ` | /* CEL Control chunk */
`PDAT' | /* Pixel Data chunk */
`PLUT' | /* PLUT (Pixel Lookup Table) chunk*/
`ANIM' | /* Animation Info*
`VDL ` | /* VDL (Video Display List) chunk */
`CPYR' | /* Copyright Notice */
`DESC' | /* Text description of image */
`KWRD' | /* Text Keywords for image*/
`CRDT' /* Text credits associated with image */
{chunk_size} ::=
/* Unsigned 32 bit integer*/
/* Includes size of chunk_body plus size*/
/* of chunk_header. chunk_size is 8 plus*/
/* size of the chunk_body.*/
/* Chunks must be Quad byte alligned.*/
/* Chunks are padded with zeros to fill */
/* the quadword alignment.*/
/* chunk_size does NOT include pad bytes*/
wrapped_file} ::= {wrap_chunk} {file}{
{wrap_chunk} ::= {wrap_chunk_ID}{chunk_size}
{wrap_chunk_ID) ::= `3DO `
/* uppercase characters followed by one space */
Integer types have the following definition:
Fixed point types have the following definition:
typedef signed char Int8;
typedef unsigned char UInt8;
typedef short Int16;
typedef unsigned short UInt16;
typedef long int32;
typedef unsigned long UInt32;
The following type describes a color in RGB 555 format
typedef Int32 Int1616;
typedef UInt32 UInt1616;
typedef Int32 Int1220;
typedef UInt32 UInt1220;
The following types are also used by chunk definitions
typedef struct RGB555 {
unsigned alpha : 1;
unsigned red : 5;
unsigned green : 5;
unsigned blue : 5;
} RGB555;
typedef unsigned char ubyte;
typedef unsigned long ulong;
typedef Int32 Color;
typedef Int32 Coord;
typedef Int32 CLUTEntry;
typedef Int32 RGB888;
The image control chunk has the following definition.
typedef struct WrapperChunk /*Optional. Must be first if present*/
{
Int32 chunk_ID; /*`3DO ` Identifies wrapper chunk*/
Int32 chunk_size; /*size of chunk including chunk_header */
ubyte data[1]; /*contains collection of atomic chunks*/
} WrapperChunk;
The pixel chunk has the following definition:
typedef struct ImageCC
{
Int32 chunk_ID; /*`IMAG' Identifies image control chunk */
Int32 chunk_size; /*size of chunk including chunk_header (24)*/
Int32 w; /*width in pixels*/
Int32 h; /*height in pixels */
Int32 bytesperrow; /*may include pad bytes at end for alignment*/
ubyte bitsperpixel; /* 8,16,24 */
ubyte numcomponents;
/* 3 => RGB (or YUV) , 1 => color index */
/* 3 => RGB (8 16 or 24 bits per pixel) */
/* 8 bit is 332 RGB (or YUV) */
/* 16 bit is 555 RGB (or YUV) */
/* 24 bit is 888 RGB (or YUV) */
/* 1 => coded meaning color index; */
/* Coded images require a Palette Chunk */
ubyte numplanes;
/*1 => chunky; 3=> planar */
/*although the hardware does not support planar*/
/*modes it is useful for some compression methods*/
/*to separate the image into RGB planes or into*/
/*YCrCb planes num components must be greater than*/
/*1 for planar to have any effect*/
ubyte colorspace; /*0 => RGB, 1 => YCrCb */
ubyte comptype;
/*compression type; 0 => uncompressed 1=Cel bit packed */
/*other compression types will be defined later */
ubyte hvformat; /*0 => 0555; 1=> 0554h; 2=> 0554v; 3=> v554h */
ubyte pixelorder;
/*0 => (0,0), (1,0), (2,0) (x,y) is (row,column) */
/*1 => (0,0), (0,1), (1,0), (1,1) Sherrie LRform */
/*2 => (0,1), (0,0), (1,1), (1,0) UGO LRform */
ubyte version;
/*image control chunk version identifier. 0 for now*/
} ImageCC;
typedef struct PixelChunk
Int32 chunk_ID; /*`PDAT' Identifies pixel data */
Int32 chunk_size;
/*size of chunk including chunk_header */
ubyte pixels[1];
/*data. Semantics depend on previous chunks*/
} PixelChunk;
An animation chunk describes the sequencing and timing the hardware should apply to a series of cels to create a flip-book animation. The
typedef struct CCC
{
Int32 chunk_ID; /*`CCB ` Identifies pixel data */
Int32 chunk_size; /*size including chunk_header */
ulong ccbversion; /*version number of struct. 0 now*/
ulong ccb_Flags; /*32 bits of CCB flags */
struct CCB *ccb_NextPtr;
CelData *ccb_CelData;
void *ccb_PLUTPtr;
Coord ccb_X;
Coord ccb_Y;
long ccb_hdx;
long ccb_hdy;
long ccb_vdx;
long ccb_vdy;
long ccb_ddx;
long ccb_ddy;
ulong ccb_PPMPC;
ulong ccb_PRE0; /* Cel Preamble Word 0 */
ulong ccb_PRE1; /* Cel Preamble Word 1 */
long ccb_Width;
long ccb_Height;
} CCC;
LoopRec
structure is used by the AnimChunk
structure.
typedef struct LoopRec
{
Int32 loopStart; /* start frame for loop in animation*/
Int32 loopEnd; /* end frame for loop in animation*/
Int32 repeatCount; /* repeats of looped portion*/
Int32 repeatDelay;
/* number of 1/60s of a sec to delay each time thru loop */
} LoopRec;
typedef struct AnimChunk
The PLUT (pixel lookup table) associates an entry in a color indexed (coded) cel or image with a 555 RGB color value. The resulting 555 color is indexed once again through separate R, G, and B color lookup tables (CLUTs,) which take a 5- bit index and yield an 8-bit color value. For more information, see the 3DO Portfolio Graphics Programmer's Guide.
{
Int32 chunk_ID; /* `ANIM' Identifies ANIM chunk */
Int32 chunk_size; /* size including chunk_header */
Int32 version; /* current version = 0 */
Int32 animType; /* 0 = multi-CCB ; 1 = single CCB */
Int32 numFrames; /* number of frames for animation */
Int32 frameRate;
/* number of 1/60s of a sec to display each frame */
Int32 startFrame; /* first frame. Can be non zero */
Int32 numLoops;
/*number of loops in loop array. Loops execute serially */
LoopRec loop[1]; /* array of loop info. see numLoops */
} AnimChunk;
A PLUT chunk has the following definition:
typedef struct PLUTChunk
To construct a custom color lookup table, define a number of A_CLUT structures that are then pointed to by the CLUTCHUNK structure:
{
Int32 chunk_ID; /* `PLUT' Identifies pixel data */
Int32 chunk_size; /* size of chunk including chunk_header */
Int32 numentries; /* number of entries in PLUT Table */
RGB555 PLUT[1]; /* PLUT entries */
} PLUTChunk;
typedef unsigned long vdlentry;
There are several different text chunks:
/* contains RGB8 triple and control bits */
typedef struct A_VDL
{
Int32 palettePtr;
Int32 dmaControl;
vdlentry vdls[33]; /* VDL entries */
Int32 filler; /* 144 length for complex VDLs.*/
} A_VDL;
typedef struct VDLCHUNK /* use for standard 33 entry vdl */
{
Int32 chunk_ID; /* `VDL ` Identifies VDL chunk */
Int32 chunk_size; /* size including chunk_header */
Int32 vdlcount; /* number of vdls following */
A_VDL vdl[1]; /* VDL control words and entries */
} VdlChunk;
typedef struct Cpyr
{
Int32 chunk_ID; /*`CPYR' Identifies pixel data */
Int32 chunk_size; /*size including chunk_header */
char copyright[1]; /*C String ASCII Copyright Notice*/
} Cpyr;
typedef struct Desc
{
Int32 chunk_ID; /* `DESC' Identifies pixel data */
Int32 chunk_size; /* size including chunk_header */
char descrip[1];
/* C String ASCII image description*/
} Desc;
typedef struct Kwrd
{
Int32 chunk_ID; /* `KWRD' Identifies pixel data */
Int32 chunk_size; /* size including chunk_header */
char keywords[1]; /* ASCII keywords, separated by `;' */
} Kwrd;
typedef struct Crdt
{
Int32 chunk_ID; /* `CRDT' Identifies pixel data */
Int32 chunk_size; /* size including chunk_header */
char credits[1]; /* C String ASCII credits for image */
} Crdt;