-
Notifications
You must be signed in to change notification settings - Fork 1
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.
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;
};
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) |
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.
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.
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.
struct Bitmap {
uint16_t data[width * height]; // pixel data
}
Each value in data
is 16 bits and refers to a single pixel.
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.
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.
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:
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: