This shows you the differences between two versions of the page.
documentation:file_formats:media:container:3do [2022/11/07 14:49] – created trapexit | documentation:file_formats:media:container:3do [Unknown date] (current) – external edit (Unknown date) 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | Original documentation: | ||
+ | |||
+ | ====== 3DO File Format ====== | ||
+ | |||
+ | ---- | ||
+ | |||
+ | %%The 3DO file format is a simple tagged format designed to be:%% | ||
+ | |||
+ | * A target file format supporting the hardware features of the 3DO platform. | ||
+ | * A common format for all available tools, allowing you to mix and match various tools on various platforms without running into file format incompatibilities. | ||
+ | |||
+ | %%Each 3DO file consists of chunks. All chunks types (except one) are atomic, that is, they do not contain other chunks. Some chunks are, however, dependent on other chunks. This is explained in detail below.%% | ||
+ | |||
+ | 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 " | ||
+ | |||
+ | 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. | ||
+ | |||
+ | ===== File Format Description ===== | ||
+ | |||
+ | %%A file consists of one or more chunks. Each chunk contains:%% | ||
+ | |||
+ | * The chunk header, which consists of a%% %%'' | ||
+ | * The chunk body, containing the data. | ||
+ | |||
+ | %%This section briefly discusses some special chunk types. The type definitions for all chunk types are listed in the next section. This%% | ||
+ | |||
+ | ==== 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%%'' | ||
+ | |||
+ | * Unwrapped files are convenient because they can be concatenated to form new legal unwrapped files. | ||
+ | * Wrapped files are convenient because they provide an easy way to check if a file is actually a 3DO file by looking for the%% %%'' | ||
+ | |||
+ | ==== Packing of Data for Image Files ==== | ||
+ | |||
+ | %%The native format for the target hardware is 555 chunky RGB. For all chunky files, numcomponents is 3 and numplanes is 1. The table below illustrates what happens with chunky files:%% | ||
+ | |||
+ | <code -> | ||
+ | Table 1: RGB chunky files (numplanes = 1) | ||
+ | -------------------------------------------------------- | ||
+ | File type |Discussion | ||
+ | -------------------------------------------------------- | ||
+ | 555 RGB |1 pixel is packed right-justified into 2 | ||
+ | chunky | ||
+ | |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 | ||
+ | |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: | ||
+ | |||
+ | <code -> | ||
+ | Table 2: | ||
+ | -------------------------------------------------------- | ||
+ | Bits Per Pixel |Pixels Per Byte | ||
+ | -------------------------------------------------------- | ||
+ | 8 | ||
+ | -------------------------------------------------------- | ||
+ | 6 |1 (right justified) | ||
+ | -------------------------------------------------------- | ||
+ | 4 | ||
+ | -------------------------------------------------------- | ||
+ | 2 | ||
+ | -------------------------------------------------------- | ||
+ | 1 | ||
+ | -------------------------------------------------------- | ||
+ | </ | ||
+ | |||
+ | A coded (color-indexed) image requires a PLUT (pixel lookup table) chunk containing at least 2**(bits per pixel) entries. | ||
+ | |||
+ | ==== PLUT and Color Lookup Table Chunks ==== | ||
+ | |||
+ | %%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, | ||
+ | |||
+ | ===== Using Multiple Chunks ===== | ||
+ | |||
+ | %%Information from more than one chunk may be needed to completely define an object. For example, a simple background image is defined by an image control chunk and a PDAT chunk.%% | ||
+ | |||
+ | '' | ||
+ | |||
+ | %%The order of chunks in a file is important because several consecutive data chunks can share one preceding control chunk as follows:%% | ||
+ | |||
+ | * Each chunk type has a%% %%//current value//. | ||
+ | * When a file is read and a chunk is encountered, | ||
+ | * The current value for all chunk types is initialized to NULL at the beginning of a file. | ||
+ | * When a data chunk is encountered, | ||
+ | |||
+ | %%Here are two examples of how multiple chunks are used in defining one object:%% | ||
+ | |||
+ | Example 1: The 3DO format stores three separate backgrounds which share all image attributes (stored in the image control chunk): | ||
+ | |||
+ | <code -> | ||
+ | {image control chunk} {PDAT chunk} {PDAT chunk} {PDAT 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:%% | ||
+ | |||
+ | <code -> | ||
+ | {ANIM Control Chunk} | ||
+ | {CEL Control Chunk} | ||
+ | {PLUT Chunk} | ||
+ | {PDAT} {PDAT} {PDAT} {PDAT} {PDAT} | ||
+ | {PLUT Chunk} | ||
+ | {PDAT} {PDAT} {PDAT} {PDAT} {PDAT} | ||
+ | </ | ||
+ | |||
+ | ==== Required and Optional Chunks ==== | ||
+ | |||
+ | %%Data chunks have required chunks and optional chunks. If any required chunk has a current value of%%'' | ||
+ | |||
+ | ===== 3DO File Format BNF ===== | ||
+ | |||
+ | %%This section contains the BNF for the 3DO file format. If you're not familiar with that notation, you can also extract the information from the definition above and the chunk definitions below.%% | ||
+ | |||
+ | <code -> | ||
+ | {file} | ||
+ | {chunk} | ||
+ | {chunk_header} | ||
+ | {chunk_ID} | ||
+ | | ||
+ | `CCB ` | /* CEL Control chunk */ | ||
+ | | ||
+ | | ||
+ | | ||
+ | `VDL ` | /* VDL (Video Display List) chunk */ | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | {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} | ||
+ | {wrap_chunk_ID) | ||
+ | </ | ||
+ | |||
+ | ==== Storing Multibyte Numbers ==== | ||
+ | |||
+ | %%The 3DO File Format uses big-endian format for storing multibyte numbers, which means that the most-significant byte is stored at the lowest address. This is the native byte order for the 68000 processor in the Macintosh and for the processor in the 3DO system.%% | ||
+ | |||
+ | ===== Chunk Definitions ===== | ||
+ | |||
+ | %%This section lists type definitions are used in chunk data structures.%% | ||
+ | |||
+ | Integer types have the following definition: | ||
+ | |||
+ | <code -> | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | </ | ||
+ | |||
+ | Fixed point types have the following definition: | ||
+ | |||
+ | <code -> | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | </ | ||
+ | |||
+ | The following type describes a color in RGB 555 format | ||
+ | |||
+ | <code -> | ||
+ | typedef struct RGB555 { | ||
+ | unsigned | ||
+ | unsigned | ||
+ | unsigned | ||
+ | unsigned | ||
+ | } RGB555; | ||
+ | </ | ||
+ | |||
+ | The following types are also used by chunk definitions | ||
+ | |||
+ | <code -> | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | typedef | ||
+ | </ | ||
+ | |||
+ | ==== Chunk Structure Definitions ==== | ||
+ | |||
+ | %%The wrapper chunk (see %%Wrapper Chunks %%above) has the following definition: | ||
+ | |||
+ | <code -> | ||
+ | typedef struct WrapperChunk | ||
+ | { | ||
+ | Int32 chunk_ID; | ||
+ | Int32 chunk_size; | ||
+ | ubyte data[1]; | ||
+ | } WrapperChunk; | ||
+ | </ | ||
+ | |||
+ | %%The image control chunk has the following definition.%% | ||
+ | |||
+ | <code -> | ||
+ | typedef struct ImageCC | ||
+ | { | ||
+ | /* `IMAG' Identifies image control chunk */ | ||
+ | Int32 chunk_ID; | ||
+ | /* size of chunk including chunk_header (24) */ | ||
+ | Int32 chunk_size; | ||
+ | /* width in pixels */ | ||
+ | Int32 w; | ||
+ | /* height in pixels */ | ||
+ | Int32 h; | ||
+ | /* may include pad bytes at end for alignment */ | ||
+ | Int32 bytesperrow; | ||
+ | |||
+ | /* 8,16,24 */ | ||
+ | ubyte bitsperpixel; | ||
+ | /* 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 numcomponents; | ||
+ | |||
+ | /* 1 => chunky; | ||
+ | /* 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 numplanes; | ||
+ | |||
+ | /* 0 => RGB, 1 => YCrCb */ | ||
+ | ubyte colorspace; | ||
+ | |||
+ | /* compression type; 0 => uncompressed 1=Cel bit packed */ | ||
+ | /* other compression types will be defined later */ | ||
+ | ubyte comptype; | ||
+ | |||
+ | /* 0 => 0555; 1=> 0554h; 2=> 0554v; 3=> v554h */ | ||
+ | ubyte hvformat; | ||
+ | |||
+ | /* 0 => (0,0), (1, | ||
+ | /* 1 => (0,0), (0,1), (1,0), (1,1) Sherrie LRform | ||
+ | /* 2 => (0,1), (0,0), (1,1), (1,0) UGO LRform */ | ||
+ | ubyte pixelorder; | ||
+ | |||
+ | /* image control chunk version identifier. 0 for now */ | ||
+ | ubyte version; | ||
+ | } ImageCC; | ||
+ | </ | ||
+ | |||
+ | %%The pixel chunk has the following definition: | ||
+ | |||
+ | <code -> | ||
+ | typedef struct PixelChunk | ||
+ | { | ||
+ | /* `PDAT' Identifies pixel data */ | ||
+ | Int32 chunk_ID; | ||
+ | /* size of chunk including chunk_header */ | ||
+ | Int32 chunk_size; | ||
+ | /* data. Semantics depend on previous chunks */ | ||
+ | ubyte pixels[1]; | ||
+ | } PixelChunk; | ||
+ | </ | ||
+ | |||
+ | ==== Cel Control Chunk ==== | ||
+ | |||
+ | %%A Cel Control Chunk structure contains an actual CCB (cel control block) data structure, as required by the 3DO hardware. See the %%//3DO Portfolio Graphics Programmer' | ||
+ | |||
+ | <code -> | ||
+ | typedef struct CCC | ||
+ | { | ||
+ | /* `CCB ` Identifies pixel data */ | ||
+ | Int32 chunk_ID; | ||
+ | /* size including chunk_header */ | ||
+ | Int32 chunk_size; | ||
+ | /* version number of struct. 0 now*/ | ||
+ | ulong ccbversion; | ||
+ | /* 32 bits of CCB flags */ | ||
+ | ulong ccb_Flags; | ||
+ | struct CCB *ccb_NextPtr; | ||
+ | CelData | ||
+ | void *ccb_PLUTPtr; | ||
+ | Coord | ||
+ | Coord | ||
+ | long ccb_hdx; | ||
+ | long ccb_hdy; | ||
+ | long ccb_vdx; | ||
+ | long ccb_vdy; | ||
+ | long ccb_ddx; | ||
+ | long ccb_ddy; | ||
+ | ulong ccb_PPMPC; | ||
+ | /* Cel Preamble Word 0 */ | ||
+ | ulong ccb_PRE0; | ||
+ | /* Cel Preamble Word 1 */ | ||
+ | ulong ccb_PRE1; | ||
+ | long ccb_Width; | ||
+ | long ccb_Height; | ||
+ | } CCC; | ||
+ | </ | ||
+ | |||
+ | %%An animation chunk describes the sequencing and timing the hardware should apply to a series of cels to create a flip-book animation. The %%'' | ||
+ | |||
+ | <code -> | ||
+ | typedef struct LoopRec | ||
+ | { | ||
+ | Int32 loopStart; | ||
+ | Int32 loopEnd; | ||
+ | Int32 repeatCount; | ||
+ | Int32 repeatDelay; | ||
+ | } LoopRec; | ||
+ | </ | ||
+ | |||
+ | <code -> | ||
+ | typedef struct AnimChunk | ||
+ | { | ||
+ | Int32 | ||
+ | Int32 | ||
+ | Int32 | ||
+ | Int32 | ||
+ | Int32 | ||
+ | Int32 | ||
+ | Int32 | ||
+ | Int32 | ||
+ | LoopRec loop[1]; | ||
+ | } 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, | ||
+ | |||
+ | A PLUT chunk has the following definition: | ||
+ | |||
+ | <code -> | ||
+ | typedef struct PLUTChunk | ||
+ | { | ||
+ | Int32 chunk_ID; | ||
+ | Int32 chunk_size; | ||
+ | Int32 numentries; | ||
+ | RGB555 PLUT[1]; | ||
+ | } PLUTChunk; | ||
+ | </ | ||
+ | |||
+ | %%To construct a custom color lookup table, define a number of A_CLUT structures that are then pointed to by the CLUTCHUNK structure: | ||
+ | |||
+ | <code -> | ||
+ | typedef unsigned long vdlentry; | ||
+ | </ | ||
+ | |||
+ | <code -> | ||
+ | /* contains RGB8 triple and control bits */ | ||
+ | typedef struct A_VDL | ||
+ | { | ||
+ | Int32 palettePtr; | ||
+ | Int32 dmaControl; | ||
+ | vdlentry vdls[33]; | ||
+ | Int32 filler; | ||
+ | } A_VDL; | ||
+ | |||
+ | typedef struct VDLCHUNK | ||
+ | { | ||
+ | Int32 chunk_ID; | ||
+ | Int32 chunk_size; | ||
+ | Int32 vdlcount; | ||
+ | A_VDL vdl[1]; | ||
+ | } VdlChunk; | ||
+ | </ | ||
+ | |||
+ | %%There are several different text chunks:%% | ||
+ | |||
+ | * CPYR-C String ASCII Copyright Notice | ||
+ | * DESC-C String ASCII image description | ||
+ | * KWRD-ASCII keywords, separated by `;' | ||
+ | * KRDT-C String ASCII credits for image | ||
+ | |||
+ | %%They have the following definition: | ||
+ | |||
+ | <code -> | ||
+ | typedef struct Cpyr | ||
+ | { | ||
+ | Int32 chunk_ID; | ||
+ | Int32 chunk_size; | ||
+ | char copyright[1]; | ||
+ | } Cpyr; | ||
+ | </ | ||
+ | |||
+ | <code -> | ||
+ | typedef struct Desc | ||
+ | { | ||
+ | Int32 chunk_ID; | ||
+ | Int32 chunk_size; | ||
+ | char descrip[1]; | ||
+ | } Desc; | ||
+ | </ | ||
+ | |||
+ | <code -> | ||
+ | typedef struct Kwrd | ||
+ | { | ||
+ | Int32 chunk_ID; | ||
+ | Int32 chunk_size; | ||
+ | char keywords[1]; | ||
+ | } Kwrd; | ||
+ | </ | ||
+ | |||
+ | <code -> | ||
+ | typedef struct Crdt | ||
+ | { | ||
+ | Int32 chunk_ID; | ||
+ | Int32 chunk_size; | ||
+ | char credits[1]; | ||
+ | } Crdt; | ||
+ | </ | ||
+ | |||