Skip to content
Jocelyn Beedie edited this page Oct 3, 2021 · 4 revisions

BITMAP

The BITMAP files contain texture information.

The names of the files in the archives are based on their original file name, and does not always describe the file format that the image is in inside the archive. Because of this, the files with the extension ".TGA" are not actual TGA files.

Header

The bitmap image starts with an 18 byte header. The header has the following format:

struct Bitmap {
    // width of the image
    uint32_t width;
    // height of the image
    uint32_t height;
    // If 0, the buffer size is width * height * (bytes per pixel).
    // No files in rotfd or jimmy use any value other than 0.
    uint32_t buffer_size;
    // Image format
    uint8_t data_format;
    // Unsure, probably related to texture wrapping and mipmaps (usually either 0, 1, 2, or 7)
    uint8_t flags;
    // Palette format (Only used for certain data formats)
    uint8_t palette_format;
    // Determines what kind of opacity this texture will need.
    // 0 = fully opaque
    // 1 = sharp transparency (always either 'on' or 'off'),
    // 2 = gradual transparency (fading; e.g. for certain particles or decals)
    uint8_t opacity_level;
    // Mipmap level, 0 = no mipmaps
    uint8_t mip_level;
    // Unsure, but most likely related to texture filtering (usually either 1, 4, or 5)
    uint8_t filter;
    // Actual Bitmap data, depends on data_format, width, and height
    BitmapData data;
    // Palette data, depends on data_format
    char palette[];
    // Mipmaps, depends on data_format, width, and height.
    // each mipmap has half the width and height of the previous mipmap.
    BitmapData data[mip_level];
    // unknown value.
    // Always 0.
    uint32_t unk;
    // if unk != 0:
    bool unk2;
};

BITMAP formats

There are several known formats for textures, based on the data_format value defined in the header.

format bits per pixel pixel layout color format
1 4bpp 8x8 pixels per block C4 (4 bit palette index; 16 colors)
2 8bpp 8x4 pixels per block C8 (8 bit palette index; 256 colors)
7 16bpp - unknown
8 16bpp 4x4 pixels per block RGB565 (5 bits red, 6 bits green, 5 bits blue)
10 16bpp 4x4 pixels per block RGB5A3 (more on this later)
11 16pbb - unknown
12 32bpp 4x4 pixels per block RGBA8888 (8 bits for all channels, has alpha channel)
13 24bpp linear RGB8888 (8 bits for all channels, no alpha channel)

Palette formats

If the texture has format 1 or 2, then the texture uses a palette. The color information for the palette used is stored as the palette_format value in the header. A texture with format 1 has 16 colors in the palette, while a texture with format 2 has 256 colors in the palette.

format color format
1 RGB5A3 (2 bytes per color)
2 RGB565 (2 bytes per color)
3 RGBA8888 (4 bytes per color)

Note that palette format 3 is not well understood since only one texture with that palette format has been found so far.

Bitmap 1 format

struct BitmapData {
    uint8_t data[width * height / 2]; // pixel data
}

Each byte in data contains indices for two pixels.

Notice that the palette is always 64 bytes. This is enough for 16 RGBA8888 colors. However, if the palette uses 16-bit colors, the last 32 bytes will be uninitialized.

Bitmap 2 format

struct BitmapData {
    uint8_t data[width * height]; // pixel data
}

Each byte in data is an index into the palette.

Notice that the palette is always 1024 bytes. This is enough for 256 RGBA8888 colors. However, if the palette uses 16-bit colors, the last 512 bytes will be uninitialized.

Bitmap 8 and 10 format

struct Bitmap {
    uint16_t data[width * height]; // pixel data
}

Each value in data is 16 bits and refers to a single pixel.

Bitmap 12 format

struct Bitmap {
    char data[width * height * 4]; // pixel data
}

Each value in data is 32 bits and refers to a single color component. The pixels are laid out in 64 byte 4x4 pixel blocks as so:

 A0,  R0,  A1,  R1,  A2,  R2,  A3,  R3,  A4,  R4,  A5,  R5,  A6,  R6,  A7,  R7,
 A8,  R8,  A9,  R9, A10, R10, A11, R11, A12, R12, A13, R13, A614 R14, A15, R15,
 G0,  B0,  G1,  B1,  G2,  B2,  G3,  B3,  G4,  B4,  G5,  B5,  G6,  B6,  G7,  B7,
 G8,  B8,  G9,  B9, G10, B10, G11, B11, G12, B12, G13, B13, G614 B14, G15, B15,

where A0,R0,G0,B0 are the ARGB components of the firsts pixel.

Bitmap 13 format

struct Bitmap {
    uint8_t data[3][width * height]; // pixel data
}

Each value in data is 24 bits and refers to a single pixel. The color components are laid out in B, G, R order.

Pixel blocks

For most texture formats, the texture is broken up into rectangular blocks of pixels. For example, for a texture with format 2, each 'block' represents an 8x4 pixel area of the bitmap. These blocks are read sequentially, and are laid out from left to right, then top to bottom of the texture.

Here is a graphical overview of the block layout:

Visual explanation of the bitmap block order

The one exception

There is one exception to Bitmap format 13 being 3 bytes per pixel, and that is when the filter flag is set to 5. For some reason, these bitmaps are formatted the same as bitmap 12 (which is 4 bytes per pixel), but only enough space is allocated for 3 bytes per pixel. This results in the data for last quarter of the texture being chopped off. If the game attempts to read this texture, it will inadvertently read in uninitialized memory as part of the texture. This can be seen in the main menu in Revenge of the Flying Dutchman on Gamecube:

Glitched texture

Clone this wiki locally