DK Animation

From MultimediaWiki
Jump to navigation Jump to search
  • 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:
  1. Left
  2. Top
  3. Right
  4. Bottom
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.