.werkkzeug 3 exported texture format
.introduction
.ktx is size-optimized format for textures made in .werkkzeug 3. This files cannot be loaded back into .werkkzeug, it intended to be used with "Texture Generation Library", which is non-free software.
File can contain one or more textures. Each texture in file must have unique name.
Format description
struct wz3ktx {
// Magic number, always 'TPWT'
uint32 magic;
// Format version
saint15 version;
// Number of textures
saint15 ntextures;
// Number of blocks
saint15 nblocks;
// Number of used opclasses
saint15 nclasses;
// Texture descriptors
struct wz3texdesc[ntextures] textures;
// OpclassID palette (see opclass list)
saint15 cids[nclasses];
// Operators (inputs)
struct wz3blockinput[nblocks] blockinputs;
// Parameters (blocks is sorted by opclass)
struct wz3blockpara[nblocks] parameters;
// String parameters
??
// Binary large objects
uint8[?] blobs;
}
struct wz3texdesc {
// Root block (index in wz3ktx->blocks table)
saint15 root;
// Name
asciiz name;
}
struct wz3blockinput {
// CID (index in wz3ktx->cids table). If high-order bit of pcid is set,
// "inputs" field does not exist, and previous operator is used as input.
uint8 pcid;
// Number of inputs (only presents if opclass is "Merge")
optional saint15 ninputs;
// Inputs (only presents if high-order bit of pcid is not set)
optional saint15[?] inputs;
}
struct wz3blockpara {
// Parameters (size and structure of this blob depends on CID)
uint8[?] parameters;
}
Smartass Data Types
Most of integers and floats in .ktx format are stored with distinct datatypes. I called it smartass. Using of this datatypes is way to conserve space.
- saint15 — smartass integer, 15 bit
- Variable stored in file may occupy 1 or 2 bytes. If high-order bit of the first byte is set, implementation must read the second byte and merge ones as following: value=(first-0x80)+second*128;. This datatype can be used to save numbers from 0 to 32767.
- safloatI — smartass float, variant I
- Variable stored in file occupies 2 bytes. It is signed little-endian word, and implementation must convert it to float as following: value=word/4096.
- safloatII — smartass float, variant II
- Variable stored in file occupies 2 bytes.
- safloatIII — smartass float, variant III
- Variable stored in file occupies 3 bytes.
- color — rgb color
- Variable stored in file occupies 3 bytes. First is red, second green, and third blue.
Operator classes
There follows structures of wz3blockpara for all known by ktx library opclasses.
// Flat parameters
struct op_flat_para {
unsigned char width;
unsigned char height;
uint32 color;
}
// Perlin parameters
struct op_perlin_para {
unsigned char width;
unsigned char height;
unsigned char freq;
unsigned char octaves;
safloatI fadeoff;
unsigned char seed;
unsigned char mode;
safloatII amplitude;
safloatII gamma;
uint32 color01;
uint32 color02;
}
// Color parameters
struct op_color_para {
unsigned char mode;
uint32 color;
}
// Merge parameters
struct op_merge_para {
unsigned char mode;
}
// Format parameters
struct op_format_para {
unsigned char _;
unsigned char _;
unsigned char _;
}
// GlowRectOld parameters
struct op_glowrect_para {
safloatI _;
safloatI _;
safloatI _;
safloatI _;
safloatI _;
safloatI _;
uint32 _;
safloatI _;
safloatII _;
unsigned char _;
unsigned char _;
}
// Dots parameters
struct op_dots_para {
uint32 color01;
uint32 color02;
sint16 count;
unsigned char seed;
}
// Blur parameters
struct op_blur_para {
unsigned char passes;
safloatII blurx;
safloatII blury;
safloatII amplify;
}
// Mask parameters
struct op_mask_para {
unsigned char mode;
}
// HSCB parameters
struct op_hscb_para {
safloatII hue;
safloatII saturation;
safloatII contrast;
safloatII brightness;
}
// Rotate parameters
struct op_rotate_para {
safloatI angle;
safloatII zoomx;
safloatII zoomy;
safloatI scrollx;
safloatI scrolly;
unsigned char borderclamp;
unsigned char newwidth;
unsigned char newheight;
}
// Distort parameters
struct op_distort_para {
safloatI strength;
unsigned char borderclamp;
}
// Normals parameters
struct op_normals_para {
safloatII strength;
unsigned char mode;
}
// Light parameters
struct op_light_para {
unsigned char _;
safloatII _;
safloatII _;
safloatII _;
safloatI _;
safloatI _;
uint32 _;
uint32 _;
safloatI _;
safloatII _;
safloatI _;
}
// Bump parameters
struct op_bump_para {
unsigned char _;
safloatII _;
safloatII _;
safloatII _;
safloatI _;
safloatI _;
uint32 _;
uint32 _;
safloatI _;
safloatII _;
safloatI _;
uint32 _;
safloatII _;
safloatI _;
}
// Text parameters (there are some doubts with this)
struct op_text_para {
safloatI posx;
safloatI posy;
safloatII size;
safloatII leading;
uint32 color;
unsigned char centerx;
unsigned char centery;
safloatII _;
safloatII _;
}
// Cell parameters
struct op_cell_para {
unsigned char width;
unsigned char height;
uint32 color01;
uint32 color02;
uint32 color03;
unsigned char max;
unsigned char seed;
safloatII amplify;
safloatII gamma;
unsigned char aspect;
safloatI _;
unsigned char flags;
safloatIII percentage;
}
// Gradient parameters
struct op_gradient_para {
unsigned char width;
unsigned char height;
uint32 color01;
uint32 color02;
safloatI position;
safloatI angle;
safloatI gwidth;
unsigned char mode;
}
// Range parameters
struct op_range_para {
unsigned char mode;
uint32 color01;
uint32 color02;
}
// RotateMul parameters
struct op_rotatemul_para {
safloatI angle;
safloatII zoomx;
safloatII zoomy;
safloatI scrollx;
safloatI scrolly;
unsigned char borderclamp;
uint32 preadjust;
unsigned char mode;
unsigned char count;
uint32 fadecolor;
}
// Twirl parameters
struct op_twirl_para {
safloatII strength;
safloatII gamma;
safloatI radiusx;
safloatI radiusy;
safloatI centerx;
safloatI centery;
unsigned char borderclamp;
}
// Sharpen parameters
struct op_sharpen_para {
unsigned char order;
safloatI blurx;
safloatI blury;
safloatI amplify;
}
// GlowRect parameters
struct op_glowrect_para {
safloatI centerx;
safloatI centery;
safloatI radiusx;
safloatI radiusy;
safloatI sizex;
safloatI sizey;
uint32 color;
safloatI blend;
safloatII power;
unsigned char wrapmode;
unsigned char powermode;
}
// Import parameters
struct op_import_para {
}
// ColorBalance parameters
struct op_cbalance_para {
safloatI[3] shadows;
safloatI[3] midtones;
safloatI[3] highlights;
}
// Unwrap parameters
struct op_unwrap_para {
unsigned char mode;
unsigned char borderclamp; // ?
}
// Bricks parameters
struct op_bricks_para {
unsigned char width;
unsigned char height;
uint32 color01;
uint32 color02;
uint32 jointscolor;
safloatIII jointsizex;
safloatIII jointsizey;
unsigned char _;
unsigned char _;
unsigned char _;
unsigned char _;
unsigned char _;
safloatIII _;
safloatIII _;
}
// Bulge parameters
struct op_bulge_para {
safloatII wrap;
}
FAQ
- Q: How to determine size of wz3ktxblock->inputs?
- A: Number of inputs depends on opclass ID. For example, Flat has only one input, and Mask has three inputs. Merge has variable number of inputs.
- Q: What does contain field wz3blockinput->inputs?
- A: It contains relative indices of blocks. For example, if this field contains 0, previous operator will be used as input. If this field contains 3, i-1-3th operator will be used as input. If high-order bit of pcid is set, inputs does not present in file, and previous operator will be used as input.