mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
* patterns/texheaders: Added pattern for Arma 3 texHeaders.bin * magic/arma3: Added texHeaders.bin magic * patterns/texheaders: Added test file * patterns/paa: Small improvements Added extra data description, and better indication of internally compressed data mipmap data. * patterns/a3: Moved Arma 3 patterns into common folder * patterns/a3: Added pattern for MLOD P3D * patterns/a3: Added pattern for RAP * magic/arma3: Added P3D and RAP to magic file * patterns/a3: Added test files for P3D and RAP * patterns/a3: Small correction to type names in TexHeaders format
142 lines
3.4 KiB
Rust
142 lines
3.4 KiB
Rust
#pragma author MrClock
|
|
#pragma description Arma 3 PAA image format
|
|
|
|
#pragma endian little
|
|
|
|
#pragma MIME image/x.a3-paa
|
|
|
|
fn get_data_description() {
|
|
return "PAA texture files are the proprietary image format used for textures in Arma 3.\nSimilar to most other formats used in game engines, the PAA stores not only a single resolution, but a series of precomputed mipmaps.\nPAA supports multiple pixel encoding formats, such as DXT1, DXT5, RGBA5551, grayscale, and others. Mipmap data in DXT encoded files is optionally compressed with the LZO1X algorithm. All other types are unconditionally LZSS compressed.";
|
|
};
|
|
|
|
import type.color;
|
|
import std.mem;
|
|
import std.sys;
|
|
|
|
struct Color<auto alpha> {
|
|
u8 b;
|
|
u8 g;
|
|
u8 r;
|
|
if (alpha) u8 a;
|
|
} [[sealed, format("type::impl::format_color"), color(std::format("{0:02X}{1:02X}{2:02X}", r, g, b))]];
|
|
|
|
using BGR8 = Color<false>;
|
|
using BGRA8 = Color<true>;
|
|
|
|
enum PixelFormat: u16 {
|
|
DXT1 = 0xFF01,
|
|
DXT2 = 0xFF02,
|
|
DXT3 = 0xFF03,
|
|
DXT4 = 0xFF04,
|
|
DXT5 = 0xFF05,
|
|
RGBA4 = 0x4444,
|
|
RGBA5 = 0x1555,
|
|
RGBA8 = 0x8888,
|
|
GRAY = 0x8080
|
|
};
|
|
|
|
enum AlphaMode: u32 {
|
|
NONE = 0,
|
|
INTERPOLATED = 1,
|
|
BINARY = 2
|
|
};
|
|
|
|
enum Swizzle: u8 {
|
|
ALPHA = 0,
|
|
RED = 1,
|
|
GREEN = 2,
|
|
BLUE = 3,
|
|
INVERTED_ALPHA = 4,
|
|
INVERTED_RED = 5,
|
|
INVERTED_GREEN = 6,
|
|
INVERTED_BLUE = 7,
|
|
BLANK_WHITE = 8,
|
|
BLANK_BLACK = 9
|
|
};
|
|
|
|
enum Compression: u8 {
|
|
NONE = 0,
|
|
LZO1X = 1,
|
|
LZSS = 2
|
|
};
|
|
|
|
struct Tagg {
|
|
char signature[8];
|
|
u32 length;
|
|
|
|
match (signature) {
|
|
("GGATCGVA"): BGRA8 color;
|
|
("GGATCXAM"): BGRA8 color;
|
|
("GGATGALF"): AlphaMode alpha;
|
|
("GGATSFFO"): u32 offsets[16];
|
|
("GGATZIWS"): Swizzle copies[4];
|
|
(_): u8 data[length];
|
|
}
|
|
} [[format("format_tagg_name")]];
|
|
|
|
struct Palette {
|
|
u16 length;
|
|
BGR8 colors[length];
|
|
};
|
|
|
|
struct Mipmap {
|
|
u16 width_and_lzo [[format("format_width_lzo")]];
|
|
u16 height;
|
|
|
|
u16 width = width_and_lzo;
|
|
Compression compression = Compression::NONE;
|
|
if ((u32(parent.format) & 0xFF00) == 0xFF00) {
|
|
width = width_and_lzo & 0x7FFF;
|
|
compression = width_and_lzo & 0x8000 ? Compression::LZO1X : Compression::NONE;
|
|
} else {
|
|
compression = Compression::LZSS;
|
|
}
|
|
|
|
if (width == 0 && height == 0) {
|
|
break;
|
|
}
|
|
|
|
u24 size;
|
|
match (compression) {
|
|
(Compression::NONE): u8 encoded_data[size];
|
|
(Compression::LZO1X): u8 lzo_compressed_data[size];
|
|
(Compression::LZSS): u8 lzss_compressed_data[size];
|
|
}
|
|
} [[format("format_resolution")]];
|
|
|
|
struct PAA {
|
|
PixelFormat format;
|
|
Tagg taggs[while(std::mem::read_string($, 4) == "GGAT")];
|
|
Palette palette;
|
|
Mipmap mipmaps[while(true)];
|
|
u16 EOF;
|
|
|
|
std::assert_warn(EOF == 0, "Invalid EOF sentinel");
|
|
};
|
|
|
|
fn format_resolution(ref auto mip) {
|
|
return std::format("{0:d} x {1:d}", mip.width, mip.height);
|
|
};
|
|
|
|
fn format_width_lzo(u16 value) {
|
|
u16 width = value & 0x7FFF;
|
|
if (value & 0x8000) {
|
|
return std::format("{0:d} (+LZO flag)", width);
|
|
} else {
|
|
return std::format("{0:d}", width);
|
|
}
|
|
};
|
|
|
|
fn format_tagg_name(Tagg data) {
|
|
match (data.signature) {
|
|
("GGATCGVA"): return "Average color";
|
|
("GGATCXAM"): return "Max color";
|
|
("GGATGALF"): return "Alpha flag";
|
|
("GGATZIWS"): return "Swizzle";
|
|
("GGATSFFO"): return "Mipmap offsets";
|
|
(_): return "Unknown";
|
|
}
|
|
};
|
|
|
|
PAA file @ 0x0000;
|