There are a few file format in Mario Kart Wii which stores images. These formats are different, but they all store image data in the same way. Image data can be stored in different formats, but they are always the same for all file formats. This page describes all these formats and also how image data is stored.
Rather than encoding each row of pixels one after the other, all of the image data formats store successive blocks (rectangles) of pixels. This means that, for example, in a 16 by 8 pixel image, with a block height and width of 4, 8 4x4 blocks would be encoded; 4 blocks for the top row, and 4 blocks for the bottom row, with the pixels in each block being encoded row by row.
The block geometry depends on the image format (see table below). In the graphic example on the right you can see the following characteristics:
- The image has a size of 14*9 pixels (red squares).
- The block size is 4*4 pixels.
- We have 12 blocks that covers 16*12 pixels (sometimes more pixels than needed, like here).
- The blocks are stored one by one in increasing order in the image file (see block numbering on the graphic). The block data is stored row by row from left to right, from top to bottom.
Each image always contains whole blocks, even if only a few pixels are needed and even for a 1x1 pixel image. This is also important for mipmaps, which become very small.
|ID||Name||Bits per pixel||Block width||Block height||Block size||Type|
|0x02||IA4||8||8||4||32 bytes||Gray + Alpha|
|0x03||IA8||16||4||4||32 bytes||Gray + Alpha|
|0x05||RGB5A3||16||4||4||32 bytes||Color + Alpha|
|0x06||RGBA32 (RGBA8)||32||4||4||64 bytes||Color + Alpha|
|0x08||C4 (CI4)||4||8||8||32 bytes||Palette (IA8, RGB565, RGB5A3)|
|0x09||C8 (CI8)||8||8||4||32 bytes||Palette (IA8, RGB565, RGB5A3)|
|0x0A||C14X2 (CI14x2)||16||4||4||32 bytes||Palette (IA8, RGB565, RGB5A3)|
|0x0E||CMPR||4||8||8||32 bytes||Color + 1 bit Alpha (compressed)|
The following explains the encoding of individual pixel data. See above for how the pixel data is ordered with respect to the image.
The I4 format is used for storing 4 bit intensity values (each pixel is composed of just one value). Conversion to RGBA is achieved by multiplying the 4 bit value by 0x11 and then setting each color component to this value. The alpha component is set to 0xff.
The I8 format is used for storing 8 bit intensity values (each pixel is composed of just one value). Conversion to RGBA is achieved by setting each color component to the 8 bit value. The alpha component is set to 0xff.
The IA4 format is used for storing 4 bit intensity values, along with a separate alpha channel. Conversion to RGBA is achieved by multiplying the lower 4 bits (second set of bits) of each value by 0x11, setting each color component to this value and then setting the alpha component to 0x11 multiplied by the upper 4 bits (first set) of the value.
The IA8 format is used for storing 8 bit intensity values, along with a separate alpha channel. Conversion to RGBA is achieved by setting each color component to the lower 8 bit value (second byte), and the alpha component to the upper 8 bit value (first byte).
The RGB565 format is used for storing 16 bit color values without alpha. Conversion to RGBA is achieved by setting the R component to 0x8 multiplied by the top 5 bits, G to 0x4 multiplied by the next 6 bits, and B to 0x8 multiplied by the last 5 bits. The alpha component would then be set to 0xff.
Colors in the RGB5A3 format can be encoded in one of two different ways. It is used for storing either 15 bit color values without alpha, or 12 bit color values with a 3 bit alpha channel. The top (first) bit is used to decide between the two; if the top bit is 0, the alpha channel is used.
Conversion to RGBA is achieved by checking the top bit, and if it is not set (0), setting A to 0x20 multiplied by the value of the next 3 bits, and then setting R, G and B in that order to the next three sets of 4 bits multiplied by 0x11 for each set. If the top bit is set, the conversion is done by setting R, G and B in that order to the next three sets of 5 bits multiplied by 0x8 for each set.
Top bit is 0: 0AAARRRRGGGGBBBB
Top bit is 1: 1RRRRRGGGGGBBBBB (Alpha set to 0xff)
The RGBA32 format (or RGBA8 as it is sometimes known) is used to store 24 bit depth True Color (1 byte per color), with an 8 bit alpha channel. Although the pixel data does follow the block order as seen in other formats, the data is separated into 2 groups. A and R are encoded in this order in the first group, and G and B in the second group.
So one block in this format (4x4 pixels), as 64 bytes, appears in this order:
ARARARARARARARAR (<- 16 bytes)
The C4 format (or CI4 as it is sometimes known) is a 4 bit palette format. Each value is a 4 bit palette index. The palette format determines how each pixel in the palette is read, and all palette formats are based on one of the other formats on this page, except that palettes don't use blocks (however, the ordering of the indexes in the image data still do use the block pattern).
The C8 format (or CI8 as it is sometimes known) is an 8 bit palette format. Each value is an 8 bit palette index. The palette format determines how each pixel in the palette is read, and all palette formats are based on one of the other formats on this page, except that palettes don't use blocks (however, the ordering of the indexes in the image data still do use the block pattern).
The C14X2 format (or CI14x2 as it is sometimes known) is a 14 bit palette format. Each value is a 14 bit palette index. The top 2 bits of each value are ignored. The palette format determines how each pixel in the palette is read, and all palette formats are based on one of the other formats on this page, except that palettes don't use blocks (however, the ordering of the indexes in the image data still do use the block pattern).
The CMPR format is a compressed image format that uses a DXT1 algorithm (also known as BC1, Block Compression 1). It's a lossy compression to achieve 4 bit per pixel data size, despite the possibility for 16 bit per pixel color. It also has the possibility for a 1 bit alpha channel.
Each CMPR block is divided into 4 sub-blocks with the size 4x4. These are each 8 bytes long. Each block has a 4 color palette. The first 4 bytes are two RGB565 values which form the first and second palette entries for this sub-block. If the first of these two UInt16s is numerically greater than the other, the remaining palette entries are formed by interpolating a third and then two thirds of the way between the first two palette entries. If the first is numerically less than the other, the third palette entry is formed by interpolating half way between the first two entries, and the last entry is transparent.
The remaining 4 bytes in the sub-block are a series of 2 bit indicies into this palette, which form a 4x4 pixel sub-block. The indices are stored row by row.
The image formats C4, C8 and C14X2 use palettes to store the pixel color data. Each pixel in the image data area is actually an index that points to the respective color to use, contained within the palette. The following palette formats are known. The bit representation is the same as described in the Image Formats section above.
|Value||Name||bytes per palette entry|
Mipmaps are smaller representations of the main image. A main image may have a series of mipmaps. Each mipmap have half height and half width (each rounded down) of the previous image. Any number of mipmaps are supported as long a mipmap have at least 1*1 pixels. Mipmaps are always stored in the same image format as the main image and use whole blocks to store the pixels.
During rendering, the mipmaps are used for textures that are distant. To render a given texture, the system generally computes how big it appears on screen, and then interpolates between the mipmap bigger and smaller than this size to produce texture information quickly. This behavior can be controlled by the materials sections within BRRES files.
If using images with different textures for mipmaps, object looks different in the near and far views. It is also possible to make objects invisible if they are near or far away.
In general, all formats support any resolutions. But due to how texture alignment works, height and width with a power of 2 should be used, to avoid flickering. Example resolutions: 64×64, 32×128, 16×8.
There are several file formats, that use these image formats:
- BREFT sub files (Images of some objects, with mipmap support)
- BRFNT files (font file with many images)
- BTI files (used in course.bti* files, with mipmap support)
- TEX0 files (BRRES sub file, with mipmap support)
- TPL files (may store multiple images)
- Wiimms SZS Tools: