DK Animation
- Company: Dorling Kindersley
- Extension:
.ani
This is an animation format used in several edutainment games from Dorling Kindersley Multimedia, particularly their encyclopedias. Some games, such as The Way Things Work and its version 2.0, use Apple QuickTime RLE instead.
The animation images are dirty rectangles that are placed on top of the display one at a time every frame. It is associated with a "base background" image, usually a DIB or a PNG-8 image, although some animations use a single-frame GIF image as the background. The animation as a whole also reuses the color palette used in the background. It also contains audio interleaved between the images, with the audio being split into equally sized chunks, although they are not in sync with each other.
All values are little endian, even for Mac versions of the games.
While most animations range between 2 and 5 fps and audio is usually at 22.050kHz, notwithstanding the computing power at the time the games were released, they can handle 60 fps of video and audio at 48kHz with no issue.
File header
Most of the fields in this header (30 bytes long) seem to be related to the WAV file header, but most of their values seem to be constant and fitting for a mono 8-bit unsigned PCM audio stream.
It's possible that other WAV data formats (32-bit float, signed 16-bit PCM) could be supported by setting the fields of this header to their corresponding values.
Offset | Type | Description |
---|---|---|
0x00 | unsigned short | Unknown; Always 1 |
0x02 | unsigned short | Total number of chunks |
0x04 | unsigned short | Unknown; Always 0 |
0x06 | unsigned short | Chunk rate; In chunks per second. Usually within a range between 1 and 8. |
0x08 | unsigned short | Image chunk offset multiplier; Usually 1 or 2. See § Storing chunks. |
0x0A | unsigned short | Audio sub chunk size?; Always 16 (PCM) |
0x0C | unsigned short | Unknown; Always 0 |
0x0E | unsigned short | Type format?; Always 1 (PCM integer) |
0x10 | unsigned short | Number of channels?; Always 1 |
0x12 | unsigned int | Audio sample rate; Usually 22050 |
0x16 | unsigned int | Number of bytes to read per second?; Usually 22050 as calculated by (Audio sample rate × Bits per sample × Number of channels) ÷ 8. |
0x1A | unsigned short | Number of bytes per block?; Always (BitsPerSample × Channels) ÷ 8, in this case 1 (8-bit mono) |
0x1C | unsigned short | Bits per sample?; Always 8 |
Chunk header
Chunks are placed one right next to each other, with no padding. The offsets in the chunk header (28 bytes long) refer to the start of each chunk.
Offset | Type | Description |
---|---|---|
0x00 | unsigned short | Unknown; Always 1 |
0x02 | unsigned int | Size of audio chunk; Always Audio sample rate ÷ Chunk rate |
0x06 | unsigned short[4] | Dirty rectangle bounds; Relative to parent popup window (or application window at root)'s top left corner. The order is as follows:
|
0x0E | unsigned int | Size of compressed image; Includes padding. |
0x12 | unsigned int | Size of uncompressed image; Includes padding. |
0x16 | char[6] | Magic; Always a non-null-terminated "funky!" .
|
Storing chunks
Right after the header, audio is stored first, and image data is stored afterwards, both with no padding at the beginning or end of a chunk. Images are stored as indexed-color RLE sequences of 1 byte per pixel:
- If the top bit is set to high, its lower 7 bits tell how many bytes should be copied as-is.
- If the top bit is set to low, it's a run value for the immediately following byte.
If the image's width is odd, it is padded to even width repeating the last pixel per row, ensuring RLE remains effective at the right edge. When decoding the image in order to draw it, this padding column is ignored. Chunks that don't have any image information will not draw anything, which allows for animations of lower frame rates than chunk rates.
This format does not store any color palettes. Instead, it is loaded from the palette of the "base background" image which is used for every frame image of the animation.
Audio and image data are not in sync between chunks: The image data will begin a few chunks after the audio data. The number of chunks is determined by the Chunk rate × Image chunk offset multiplier. Due to this offset, in most animations, the last chunks will not contain audio data, and instead end with chunks with only image data.