arma:paa
Differences
This shows you the differences between two versions of the page.
arma:paa [2007/07/04 10:17] – created initial paa page snakeman | arma:paa [2007/07/06 01:40] (current) – deleted :) snakeman | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Introduction ====== | ||
- | Of the many image file formats 'out there', | ||
- | |||
- | ====== Main Format ====== | ||
- | |||
- | Overall structure of a Paa file is | ||
- | |||
- | < | ||
- | struct overall | ||
- | { | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | }; | ||
- | </ | ||
- | |||
- | Every PAA file starts with a **TypeOfPaa** | ||
- | < | ||
- | ushort TypeOfPaa; | ||
- | // 0xFF01 DXT1 compressed texture (may have 1 bit alpha map, check MSDN documentation for details) | ||
- | // 0x1555 Uncompressed RGBA 5:5:5:1 texture | ||
- | // 0x4444 Uncompressed RGBA 4:4:4:4 texture | ||
- | // 0x8080 Uncompressed Luminosity/ | ||
- | // 0xFF03 XBox & ArmA only. DXT3 compressed texture | ||
- | // 0xFF05 XBox & ArmA only. DXT5 compressed texture | ||
- | // 0x4747 Uncompressed Index Palette texture(P8) SPECIAL CASE see notes | ||
- | // added TypeOfPaa working in Oxygen 2 Full: | ||
- | // 0xFF02 DXT2 compressed texture | ||
- | // 0xFF04 DXT4 compressed texture | ||
- | // 0x8888 RGBA 8:8:8:8 texture | ||
- | </ | ||
- | |||
- | followed by **optional** header tags | ||
- | |||
- | < | ||
- | struct PAA_Tag { | ||
- | byte name[8]; // name of tag is actually reversed when written in file, | ||
- | // so OFFSTAGG would be written as GGATSFFO. See below for known tags. | ||
- | ULONG tag_size; | ||
- | byte data[tag_size]; | ||
- | } | ||
- | </ | ||
- | |||
- | followed by an EndofTags ushort of zero, indicating, no more tags! | ||
- | |||
- | **Special Case** | ||
- | |||
- | TypeOfPaa 0x4747 Uncompressed Index Palette texture | ||
- | |||
- | This is a corrupt entry in the sense that it does not have a TypeOfPaa! It is the lead in bytes to a standard AVCGTAGG. The next block of data is, the palette. Followed by ' | ||
- | |||
- | Indecipherable commentary from Feersum:\\ | ||
- | If format not 0x4747 then end of header tag data is marked by UWORD 0x0000, else this is a `size of palette` and next block it`s a palette(sizeof = `size of palette` * 2) | ||
- | |||
- | ====== HexDump ====== | ||
- | |||
- | {{http:// | ||
- | |||
- | ====== Known Header Tags ====== | ||
- | |||
- | There are several knowns header tags. | ||
- | |||
- | **OFFSTAGG** | ||
- | |||
- | < | ||
- | Sizeof Data (16 x ULONGS) | ||
- | Example: | ||
- | GGATSFFO = 6 entries | ||
- | 256 x 128 Size=16384 | ||
- | 128 x 64 Size=4096 | ||
- | 64 x 32 Size=1024 | ||
- | 32 x 16 Size=256 | ||
- | 16 x 8 Size=64 | ||
- | 8 x 4 Size=16 | ||
- | </ | ||
- | |||
- | MipMap data is presented in ' | ||
- | |||
- | **AVGCTAGG** | ||
- | |||
- | Average Colour | ||
- | < | ||
- | Sizeof Data (1 x ULONG) | ||
- | example: GGATCGVA = FF443D39 | ||
- | </ | ||
- | |||
- | This tag contains average color of texture, probably used in rendering 8:8 luminosity/ | ||
- | |||
- | **FLAGTAGG** | ||
- | |||
- | < | ||
- | Sizeof Data (1 x ULONG) | ||
- | example: GGATGALG = 0 // range, 0 to 2 | ||
- | </ | ||
- | |||
- | Marks if texture contains transparency. Value 1 means basic transparency, | ||
- | |||
- | **ArmA / Elite** | ||
- | |||
- | Purpose of these tags are not yet known. | ||
- | |||
- | **MAXCTAGG** | ||
- | |||
- | < | ||
- | Sizeof Data (1 x ULONG) | ||
- | example: GGATCXAM = FFFFFFFFF // no other value seen so far | ||
- | </ | ||
- | |||
- | Contains color of brightest pixel in texture? | ||
- | |||
- | **SWIZTAGG** | ||
- | |||
- | < | ||
- | Sizeof Data (1 x ULONG) | ||
- | example: GGATZIWS = ??????? | ||
- | </ | ||
- | |||
- | Swizzle is apparently used to modify texture components processing like swizzle modifiers in pixel shaders. For example ArmA sky texture has green channel stored in alpha channel and inversed to take advantage from feature that in DXT5 64 bits are used for alpha channel in each block and 64 bits for RBG, giving double the accuracy to green channel as opposed to storing texture just normally. Exact format of swizzle data is still unknown. | ||
- | |||
- | ====== Mipmap Data ====== | ||
- | |||
- | After end-of-header marker, actual mipmap data follows. Tag OFFSTAGG (if supplied) contains (up to) 16 offsets. Each offset points to the following struct type (relative to start of the file). | ||
- | |||
- | < | ||
- | struct Mipmap_Data { | ||
- | UWORD width; | ||
- | UWORD height; | ||
- | UCHAR size[3]; | ||
- | UCHAR data[size]; | ||
- | }; | ||
- | </ | ||
- | |||
- | If OFFSTAGG is not supplied, then the next mipmap block is indicated by the size of the previous one. Note that the size reflects the size of data in the file not the actual size if that data if is compressed. The size of output data for Dct1 format is (width*height / 2). Size of output data for Dct5 format is (width*height). Texture types 0x4444, | ||
- | |||
- | **Decompression Code** | ||
- | |||
- | < | ||
- | /* | ||
- | by Flea | ||
- | */ | ||
- | int LZSSDecode(unsigned char * in,unsigned char * out,int szin,int szout) | ||
- | { | ||
- | szin = szin > 0? szin: 0x7fffffff; | ||
- | int i, j, k, r = 0, pr, pi = 0,po = 0; | ||
- | unsigned int flags = 0; | ||
- | unsigned char buf[0x100F], | ||
- | for (i = 0; i < 0x100F; buf[i] = 0x20, i++); | ||
- | while (pi < szin && po < szout) | ||
- | { | ||
- | if (((flags >>= 1) & 256) == 0) | ||
- | { | ||
- | if(pi >= szin)break; | ||
- | c = in[pi++]; | ||
- | flags = c | 0xff00; | ||
- | } | ||
- | if (flags & 1) | ||
- | { | ||
- | if(pi >= szin || po >= szout)break; | ||
- | c = in[pi++]; | ||
- | out[po++] = c; | ||
- | buf[r++] = c; | ||
- | r &= 0xfff; | ||
- | } else | ||
- | { | ||
- | if(pi + 1 >= szin)break; | ||
- | i = in[pi++]; | ||
- | j = in[pi++]; | ||
- | i |= (j & 0xf0) << 4; | ||
- | j = (j & 0x0f) + 2; | ||
- | pr = r; | ||
- | | ||
- | { | ||
- | c = buf[(pr - i + k) & 0xfff]; | ||
- | if(po >= szout)break; | ||
- | out[po++] = c; | ||
- | buf[r++] = c; | ||
- | r &= 0xfff; | ||
- | } | ||
- | } | ||
- | } | ||
- | return pi; | ||
- | } | ||
- | </ | ||
- | |||
- | **End of Mipmap(s)** | ||
- | |||
- | After last mipmap, there are six (6) bytes set to 0x00 to mark end of texture data. And, | ||
- | |||
- | ====== Alpha Channel Interpolation ====== | ||
- | |||
- | These two images visualize difference between alpha channel interpolation (FLAGTAGG header tag value). | ||
- | |||
- | **FLAGTAGG = 1, interpolated alpha channel (default behaviour)** | ||
- | |||
- | {{http:// | ||
- | |||
- | **FLAGTAGG = 2, alpha channel interpolation disabled** | ||
- | |||
- | {{http:// | ||
- | |||
- | ====== Bibliography ====== | ||
- | |||
- | Feersum' | ||
- | MSDN documentation on DXT1 textures: [[http:// | ||
- | Squish Compression [[http:// |
arma/paa.1183544220.txt.gz · Last modified: 2007/07/10 09:52 (external edit)