.tga File Extension (BIMAGE)
Despite the name, the ".tga" files used in Doom Eternal are not actually .tga (targa) images. They are actually "BIM" (or .bimage) files of various formats.
These files are stored in two parts. The file header is embedded in Doom Eternal's .resources files. The body of the file is embedded in Doom Eternal's .streamdb files.
File Signature
Doom Eternal ".tga" files can be identified by the first 3 bytes of the file header, which is always 0x42 0x49 0x4D or "BIM", short for "bimage" or "binary image".
"Header" Structure
The basic file header structure is a 63-byte HEADER struct, followed by a variable number of 36-byte MIPMAP structs.
struct FILE_HEADER
{
HEADER header;
MIPMAP mipmap[]; // Flexible array member, length varies with header.MipCount;
};
The HEADER struct is a 63-byte sequence described as follows:
typedef struct {
int Signature;
int TextureType; // enum textureType_t
int TextureMaterialKind; // enum textureMaterialKind_t
int PixelWidth; // image width in pixels
int PixelHeight; // image height in pixels
int Depth;
int MipCount; // "numLevels" in IDA
int64 MipLevel;
float unkFloat1; // usually 1.0, purpose unknown
char boolIsEnvironmentMap;
int TextureFormat; // enum textureFormat_t
int Always7; // unknown, but literally always 7
int _nullPadding;
int16 AtlasPadding;
char boolIsStreamed; // 1 if file is located in streamDB, 0 if not
char unkBool;
char boolNoMips;
char boolFFTBloom;
int StreamDBMipCount; // usually same number of mips stored in streamdb
} HEADER;
The MIPMAP struct is a 36-byte sequence described as follows.
typedef struct {
int64 MipLevel; // Starts at 0, increments each time it repeats
int MipPixelWidth; // Original PixelWidth reduced by 50% for each MipLevel
int MipPixelHeight; // Original PixelHeight reduced by 50% for each MipLevel
int UnknownFlagA;
int DecompressedSize; // Decompressed size in bytes
int FlagIsCompressed; // 1 if the texture is compressed, 0 if not
int CompressedSize; // Compressed size in bytes
int CumulativeSizeStreamDB;
} MIPMAP;
The MIPMAP structure is repeated n times, where n is equal to HEADER.MipCount above. For example, if HEADER.MipCount is 9, then the overall structure of the FILE_HEADER would look like this:
struct FILE_HEADER
{
HEADER header;
MIPMAP mipmap[9]; // mipmap repeats 9 times, because header.MipCount = 9
};