Image Formats

From Custom Mario Kart
Jump to: navigation, search

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.


Blocks

Block Example for Images

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.

Image Formats

Image Formats
ID Name Bits per pixel Block width Block height Block size Type
0x00 I4 4 8 8 32 bytes Gray
0x01 I8 8 8 4 32 bytes Gray
0x02 IA4 8 8 4 32 bytes Gray + Alpha
0x03 IA8 16 4 4 32 bytes Gray + Alpha
0x04 RGB565 16 4 4 32 bytes Color
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.

I4

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.

I8

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.

IA4

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.

IA8

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).

RGB565

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.

i.e.: RRRRRGGGGGGBBBBB

RGB5A3

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)

RGBA32 (RGBA8)

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)

ARARARARARARARAR

GBGBGBGBGBGBGBGB

GBGBGBGBGBGBGBGB

C4 (CI4)

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).

C8 (CI8)

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).

C14X2 (CI14x2)

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).

CMPR

The CMPR format is a compressed image format that uses a DXT1 algorithm. 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.

C# Example

public void GetDXT1Colors(UInt16 _Color0, UInt16 _Color0, Color Color0, Color Color1, out Color Color2, out Color Color3)
{
 // Compare the two colors
 if (_Color0 > _Color1)
 {
  // Alpha is 0xFF, calculate R, G and B
  Color2 = Color.FromArgb(0xFF, 2 * Color0.R / 3 + 1 * Color1.R, 2 * Color0.G / 3 + 1 * Color1.G, 2 * Color0.B / 3 + 1 * Color1.B);
  Color3 = Color.FromArgb(0xFF, 1 * Color0.R / 3 + 2 * Color1.R, 1 * Color0.G / 3 + 2 * Color1.G, 1 * Color0.B / 3 + 2 * Color1.B);
 }
 else
 {
  // Calculates R, G and B for the first color and the second color is transparent.
  Color2 = Color.FromArgb(0xFF, Color0.R / 2 + Color1.R / 2, Color0.G / 2 + Color1.G / 2, Color0.B / 2 + Color1 / 2);
  Color3 = Color.FromArgb(0x00, 0x00, 0x00, 0x00);
 }
}

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.

Palette Formats

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.

Palette Formats
Value Name bytes per palette entry
0x00 IA8 2
0x01 RGB565 2
0x02 RGB5A3 2

Mipmaps

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.

Resolutions

In General, all formats support any resolutions. But experience says that only height and width with a power of 2 should be used, to avoid flickering. Example resolutions: 64*64, 32*128, 16*8.

File Formats

There are several file formats, that use these image formats:

Tools

External Links