Four of the pixel formats do not hold colours in the pixels, so the file holds a table that says what the pixels mean. The table sits directly after the header, once for the whole texture, and is shared by every mipmap level. Formats without a table have nothing between the header and the first level.
| Format | Table | Size |
|---|---|---|
yiq, ayiq8422 | YIQ table | 80 bytes |
p8, ap88 | Palette | 1024 bytes |
| all others | none | 0 bytes |
YIQ table
A YIQ byte is YYYYIIQQ: a 4-bit index into a table of 16 brightnesses,
and two 2-bit indexes into tables of 4 colour shifts. The 80-byte table is made of
40 big-endian 16-bit numbers:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 32 | 16 × i16 | Y | The brightness for each 4-bit Y value, 0 to 255. Stored as 16-bit numbers although the range fits a byte. |
| 32 | 24 | 4 × 3 × i16 | I | For each 2-bit I value, the red, green and blue amounts added to Y. Signed. |
| 56 | 24 | 4 × 3 × i16 | Q | The same for each 2-bit Q value. Signed. |
The colour a byte b stands for is, for each of red, green and blue in
turn:
channel = clamp(Y[b >> 4] + I[(b >> 2) & 3][channel] + Q[b & 3][channel], 0, 255)
The clamp to 0 to 255 is how the explorer finishes the sum; the file does not say
what a card does with a sum outside the range. The structure is the one in Glide’s
GuNccTable (yRGB[16], iRGB[4][3],
qRGB[4][3]); Glide’s own structure has a further 12 packed 32-bit numbers
that the file does not hold and that the loader computes. “NCC”, narrow-channel
compression, is Glide’s name for the table.
Example
The table of a 256 × 256 yiq texture, which starts at offset 30 (hexadecimal), right after its 48-byte header. Then the first pixels, at offset 80 (also hexadecimal):
00000030 00 01 00 0f 00 18 00 31 00 43 00 52 00 63 00 7b Y[0] to Y[7]
00000040 00 84 00 9d 00 ad 00 bd 00 ce 00 df 00 ef 00 ff Y[8] to Y[15]
00000050 ff fc ff fc ff fc 00 05 00 05 00 05 ff fe ff fe I[0], I[1], I[2] begins
00000060 ff fe 00 00 00 00 00 00 ff fc ff fc ff fc ff fc I[2] ends, I[3], Q[0], Q[1] begins
00000070 ff fc ff fc 00 04 00 04 00 04 00 03 00 03 00 03 Q[1] ends, Q[2], Q[3]
00000080 2f 14 1c 24 ... pixels
Y is 1, 15, 24, 49, 67, 82, 99, 123, 132, 157, 173, 189, 206, 223, 239, 255. I is
(−4, −4, −4), (5, 5, 5), (−2, −2, −2) and (0, 0, 0). Q is (−4, −4, −4), (−4, −4, −4),
(4, 4, 4) and (3, 3, 3). The first pixel, 2F = 0010 1111, has
Y index 2, I index 3 and Q index 3, so each channel is 24 + 0 + 3 = 27: a dark grey.
Palette
The palette of p8 and ap88 is 256 entries of 4 bytes, the
colours a pixel’s index stands for:
| Offset in entry | Size | Name | Description |
|---|---|---|---|
| 0 | 1 | alpha | 0 in the files checked. A p8 pixel has no alpha; an ap88 pixel carries its own. |
| 1 | 1 | red | 0 to 255. |
| 2 | 1 | green | 0 to 255. |
| 3 | 1 | blue | 0 to 255. |
Taken as a big-endian 32-bit number an entry is 0xAARRGGBB, the
FxU32 of Glide’s GuTexPalette. The whole palette is 1024
bytes, always 256 entries even when the picture uses fewer. A pixel is an index from
0 to 255.
Example
The start of the palette of a lava texture, right after its 47-byte header:
0000002f 00 3a 19 19 00 5a 42 42 00 31 19 31 00 63 63 63 entries 0 to 3
Entry 0 is alpha 0, red 3A, green 19, blue 19 (a dark red), entry 1 is
5A 42 42, and so on. The first pixel of the level starts 1024 bytes after
the palette begins, at offset 42F.