Changes
From Final Fantasy Inside
no edit summary
== TEX Texture Data Format for PC by [[User:Mirex|Mirex]] (Edits by Aali) ==
FF7 PC texture consists of header, an optional palette and bitmap data. Usually data are stored like palletized picture, with bitmap pixels referencing to palette. Color 0 (in palette its usually black) is usually used as transparent color.
''Pixel values of 0 may or may not be transparent, depending on the color key status, more on that later. This also applies to non-paletted formats.''
When bit depth is 16 then data are stored as packed RGB in style RGB555, which means 5 bits per color in one 2 byte entry. I'm not sure if it is used in FF7 at all, its probably used in FF8.
''The tex format is actually very flexible and can take almost any non-paletted format as long as you describe it properly in the header.''
<table CELLSPACING="0" style="margin-bottom: 0px;">
<tr celspan<tr><th style="border: 1px solid rgb(0, 0, 0)black; vertical-align: middle; width: 51px; height: 26px; background-color: rgb(230, 230, 230);">
Offset </th>
<th style="border: 1px solid rgb(0, 0, 0)black; vertical-align: middle; width: 126px; height: 26px; background-color: rgb(230, 230, 230);">
Size </th>
<th style="border: 1px solid rgb(0, 0, 0)black; vertical-align: middle; width: 222px; height: 26px; background-color: rgb(230, 230, 230);">
Description </th>
</tr>
<tr celspan><td style="border-style: solid none solid solid; border-color: black; border-width: 1px; vertical-align: top;"></td><td colspan="32" style="border-style: solid solid solid none; border-color: rgb(0, 0, 0)black; border-width: 1px; width: 348px; height: 25px;"> <center> Header </center> </td>
</tr>
<tr>
<td style="border: 1px solid rgb(0, 0, 0); width: 51px; height: 25pxred;">
0x00 </td>
<td style="border: 1px solid rgbred;">4 bytes (0long) </td><td style="border: 1px solid red;">Version, 0must be 1, 0or FF7 won't load the file </td></tr> <tr><td style="border: 1px solid red;">0x04 </td><td style="border: 1px solid red;">4 bytes (long)</td><td style="border: 1px solid red; width">Unknown </td></tr> <tr><td style="border: 126px1px solid red; height">0x08 </td><td style="border: 25px1px solid red;">56 4 bytes (long) </td><td style="border: 1px solid red;">Color key flag </td></tr> <tr><td style="border: 1px solid rgbred;">0x0C </td><td style="border: 1px solid red;">4 bytes (0, 0, 0long)</td><td style="border: 1px solid red; width">Unknown </td></tr> <tr><td style="border: 222px1px solid red; height">0x10 </td><td style="border: 25px1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">
Unknown </td>
</tr>
<tr>
<td style="border: 1px solid red;">
0x14 </td>
<td style="border: 1px solid red;">
4 bytes (long) </td>
<td style="border: 1px solid red;">
Minimum bits per color (D3D driver uses these to determine which texture format to convert to on load) </td>
</tr>
<tr>
<td style="border: 1px solid rgbred;">0x18 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Maximum bits per color </td></tr> <tr><td style="border: 1px solid red;">0x1C </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Minimum alpha bits </td></tr> <tr><td style="border: 1px solid red;">0x20 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Maximum alpha bits </td></tr> <tr><td style="border: 1px solid red;">0x24 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Minimum bits per pixel </td></tr> <tr><td style="border: 1px solid red;">0x28 </td><td style="border: 1px solid red;">4 bytes (0, 0, 0long)</td><td style="border: 1px solid red; width">Maximum bits per pixel </td></tr> <tr><td style="border: 1px solid red;">0x2C </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Unknown </td></tr> <tr><td style="border: 1px solid red;">0x30 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Number of palettes </td></tr> <tr><td style="border: 1px solid red;">0x34 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 51px1px solid red; height">Number of colors per palette </td></tr> <tr><td style="border: 25px1px solid red;">
0x38 </td>
<td style="border: 1px solid rgb(0, 0, 0); width: 126px; height: 25pxred;">
4 bytes (long) </td>
<td style="border: 1px solid rgb(0, 0, 0); width: 222px; height: 25pxred;">bit Bit depth - can be 4, 8, 16 </td>
</tr>
<tr>
<td style="border: 1px solid rgb(0, 0, 0); width: 51px; height: 25pxblack;">0x3c 0x3C </td><td style="border: 1px solid rgb(0, 0, 0); width: 126px; height: 25pxblack;">
4 bytes (long) </td>
<td style="border: 1px solid rgb(0, 0, 0); width: 222px; height: 25pxblack;">
Image Width </td>
</tr>
<tr>
<td style="border: 1px solid rgb(0, 0, 0); width: 51px; height: 25pxblack;">
0x40 </td>
<td style="border: 1px solid rgb(0, 0, 0); width: 126px; height: 25pxblack;">
4 bytes (long) </td>
<td style="border: 1px solid rgb(0, 0, 0); width: 222px; height: 25pxblack;">
Image Height </td>
</tr>
<tr>
<td style="border: 1px solid rgb(0, 0, 0); width: 51px; height: 25pxred;">
0x44 </td>
<td style="border: 1px solid rgbred;">4 bytes (0, 0, 0long)</td><td style="border: 1px solid red; ">Pitch or bytes per row, usually ignored and assumed to be bytes per pixel * width</td></tr> <tr><td style="border: 126px1px solid red; height">0x48 </td><td style="border: 25px1px solid red;">20 4 bytes (long) </td><td style="border: 1px solid rgb(0, 0, 0); width: 222px; height: 25pxred;">
Unknown </td>
</tr>
<tr>
<td style="border: 1px solid rgbred;">0x4C </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Palette flag (this indicates the presence of a palette) </td></tr> <tr><td style="border: 1px solid red;">0x50 </td><td style="border: 1px solid red;">4 bytes (0, 0long) </td><td style="border: 1px solid red;">Bits per index, always 0for non-paletted images </td></tr> <tr><td style="border: 1px solid red;">0x54 </td><td style="border: 1px solid red;">4 bytes (long); width</td><td style="border: 51px1px solid red; height">Indexed-to-8bit flag, never used in FF7 </td></tr> <tr><td style="border: 25px1px solid red;">
0x58 </td>
<td style="border: 1px solid rgbred;">4 bytes (long) </td><td style="border: 1px solid red;">Palette size, always palettes * colors per palette </td></tr> <tr><td style="border: 1px solid red;">0x5C </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Number of colors per palette (again, may be 0sometimes, 0the other value will be used anyway) </td></tr> <tr><td style="border: 1px solid red;">0x60 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Runtime data, ignored on load </td></tr> <tr><td style="border: 1px solid red;">0x64 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Bits per pixel </td></tr> <tr><td style="border: 1px solid red;">0x68 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Bytes per pixel, always use this to determine how much data to read, if this is 1 you read 1 byte per pixel, regardless of bit depth </td></tr> <tr><td style="border-style: solid none solid solid; border-color: black; border-width: 1px; vertical-align: top;"></td><td colspan="2" style="border-style: solid solid solid none; border-color: black; border-width: 1px;">Pixel format (all 0for paletted images)</td></tr> <tr><td style="border: 1px solid red;">0x6C </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red; width">Number of red bits </td></tr> <tr><td style="border: 126px1px solid red; height">0x70 </td><td style="border: 25px1px solid red;">
4 bytes (long) </td>
<td style="border: 1px solid rgb(0, 0, 0); width: 222px; height: 25pxred;">Number of Palette Entries green bits </td>
</tr>
<tr>
<td style="border: 1px solid rgbred;">0x74 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Number of blue bits </td></tr> <tr><td style="border: 1px solid red;">0x78 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Number of alpha bits </td></tr> <tr><td style="border: 1px solid red;">0x7C </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Red bitmask </td></tr> <tr><td style="border: 1px solid red;">0x80 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Green bitmask </td></tr> <tr><td style="border: 1px solid red;">0x84 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Blue bitmask </td></tr> <tr><td style="border: 1px solid red;">0x88 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Alpha bitmask </td></tr> <tr><td style="border: 1px solid red;">0x8C </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Red shift </td></tr> <tr><td style="border: 1px solid red;">0x90 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Green shift </td></tr> <tr><td style="border: 1px solid red;">0x94 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Blue shift </td></tr> <tr><td style="border: 1px solid red;">0x98 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Alpha shift </td></tr> <tr><td style="border: 1px solid red;">0x9C </td><td style="border: 1px solid red;">4 bytes (0long) </td><td style="border: 1px solid red;">Always 8 - Number of red bits (Not sure what the point of these fields is, 0, 0they're always ignored anyway) </td></tr> <tr><td style="border: 1px solid red;">0xA0 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">8 - Number of green bits </td></tr> <tr><td style="border: 1px solid red;">0xA4 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">8 - Number of blue bits </td></tr> <tr><td style="border: 1px solid red;">0xA8 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">8 - Number of alpha bits </td></tr> <tr><td style="border: 1px solid red;">0xAC </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Red max </td></tr> <tr><td style="border: 1px solid red;">0xB0 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Green max </td></tr> <tr><td style="border: 1px solid red;">0xB4 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Blue max </td></tr> <tr><td style="border: 1px solid red;">0xB8 </td><td style="border: 1px solid red;">4 bytes (long)</td><td style="border: 1px solid red;">Alpha max </td></tr> <tr><td style="border-style: solid none solid solid; border-color: black; border-width: 51px1px; vertical-align: top;"></td><td colspan="2" style="border-style: solid solid solid none; border-color: black; border-width: 1px;">End of pixel format </td></tr> <tr><td style="border: 1px solid red;">0xBC </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Color key array flag (this indicates the presence of a color key array) </td></tr> <tr><td style="border: 1px solid red;">0xC0 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Runtime data </td></tr> <tr><td style="border: 1px solid red;">0xC4 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red; height">Reference alpha (more on this later) </td></tr> <tr><td style="border: 25px1px solid red;">0x5c 0xC8 </td><td style="border: 1px solid rgbred;">4 bytes (0, 0, 0long) </td><td style="border: 1px solid red;">Unknown </td></tr> <tr><td style="border: 1px solid red;">0xCC </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Unknown </td></tr> <tr><td style="border: 1px solid red;">0xD0 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Palette index (runtime data) </td></tr> <tr><td style="border: 1px solid red;">0xD4 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Runtime data </td></tr> <tr><td style="border: 1px solid red;">0xD8 </td><td style="border: 1px solid red;">4 bytes (long) </td><td style="border: 1px solid red;">Runtime data </td></tr> <tr><td style="border: 1px solid red;">0xDC </td><td style="border: 1px solid red;">4 bytes (long)</td><td style="border: 1px solid red; width">Unknown </td></tr> <tr><td style="border: 126px1px solid red; height">0xE0 </td><td style="border: 25px1px solid red;">144 4 bytes (long) </td><td style="border: 1px solid rgbred;">Unknown </td></tr> <tr><td style="border: 1px solid red;">0xE4 </td><td style="border: 1px solid red;">4 bytes (0, 0, 0long)</td><td style="border: 1px solid red; width">Unknown </td></tr> <tr><td style="border: 1px solid red;">0xE4 </td><td style="border: 222px1px solid red; height">4 bytes (long) </td><td style="border: 25px1px solid red;">
Unknown </td>
</tr>
<tr>
<td style="border: 1px solid rgb(0, 0, 0); vertical-align: top; width: 51px; height: 96pxred;">0xec 0xE8 </td><td style="border: 1px solid rgb(0, 0, 0); vertical-align: top; width: 126px; height: 96pxred;">Palette Entries * 4 bytes (long) </td><td style="border: 1px solid rgb(0, 0, 0); vertical-align: top; width: 222px; height: 96pxred;">Every 4 bytes from palette represent one color, BGRA -Blue Green Red Alpha, but I'm not sure about the alpha byte. I'm using only the BGR part Unknown </td>
</tr>
<tr>
<td style="border-style: solid none solid solid; border-color: rgb(0, 0, 0)red; border-width: 1px; vertical-align: top; width: 51px; height: 25px;"></td><td colspan="2" style="border-style: solid solid solid none; border-color: rgb(0, 0, 0)red; border-width: 1px; width: 348px; height: 25px;">Pixel data are present after the Palette data (ignore this section if palette flag is 0) </td>
</tr>
<tr>
<td style="border: 1px solid rgb(0red; vertical-align: top;">0xEC </td><td style="border: 1px solid red; vertical-align: top;">Palette size * 4 </td><td style="border: 1px solid red; vertical-align: top;">The raw palette data, 0, 0)always in 32-bit BGRA format</td></tr> <tr><td style="border-style: solid none solid solid; border-color: black; border-width: 1px; vertical-align: top; "></td><td colspan="2" style="border-style: solid solid solid none; border-color: black; border-width: 51px1px; height">Pixel data </td></tr> <tr><td style="border: 140px1px solid black; vertical-align: top;">
Varies </td>
<td colspan="2" style="border: 1px solid rgb(0black; vertical-align: top;">Read width * height * "bytes per pixel" bytes of data. If there's a palette, 0every pixel is an index into that palette, 0)otherwise use the pixel format specification.</td></tr> <tr><td style="border-style: solid none solid solid; border-color: black; border-width: 1px; vertical-align: top; width"></td><td colspan="2" style="border-style: solid solid solid none; border-color: 126pxblack; heightborder-width: 140px1px;">(sizex * sizey) if bit depth is 4 or 8, (sizex * sizey * 2) if bit depth is 16 Color key array </td></tr> <tr><td style="border: 1px solid rgb(0, 0, 0)black; vertical-align: top; width">Varies </td><td colspan="2" style="border: 222px1px solid black; heightvertical-align: 140pxtop;">Thebitmap: If bit depth is 4 or 8, every byte Number of bitmap data is referenceto palette colorpalettes * 1 bytes. If bit depth is 16, bitmap is composed from 16bit(2byte, short) values, which are RGB555 colors. </td>
</tr>
</table>
''Color keying: If the color key flag is zero, no color keying is performed and the color key array is ignored. Otherwise, the current palette index is used to retrieve a single byte from the color key array, this is the new color key flag, zero means don't do color keying.
If there is no color key array (and the color key flag is not zero), you should always color key.''
''Reference alpha: Only applies to paletted images, if the alpha value sampled from the palette is 0xFE, this value should be replaced with the reference alpha.''