Origin Xan Codec
While not all of the details have been reverse engineered, the Xan codec is known to use the same byte unpacking algorithm as used in the custom video codec developed for Wing Commander III. Further, it uses Huffman coding and bit packing, though using a slightly different algorithm than its predecessor codec, and it appears to have been designed to easily accommodate a number of video output and scaling modes.
Trivia: All Xan-encoded AVI files contain very interesting comment string inside. 'Xxan video stream, Blue Mu Productions.' What could possible that Blue Mu be? A subdivision of Origin or real codec authors?
This codec is similar to Wing Commander III MVE Video Codec and employs the same packing algorithm. The main difference is that this codec stores information in YUV colorspace.
- Y component is stored at 6 bits
- U and V components are 5 bits in Wing Commander 4 videos, and 8 bits in Crusader: No Regret.
header: bytes 0-3 - frame type (0 or 1) bytes 4-7 - offset to chroma data bytes 8-11 - offset to luma refinements (or 0 if not present)
type 0: bytes 12-? - luma Huffman-coded data for frame type 0 or type 1: bytes 12-15 - offset to second luma refinements (or 0 if not present) bytes 16-? - luma Huffman-coded data for frame type 1
chroma data: bytes 0-1 - chroma mode: 0 = data is YUV420 (4 luma pixels to 2 chroma pixels), 1 = data is YUV410 bytes 2-3 - chroma value table size (entries) bytes 4-x - chroma value lookup table (16 bits per entry, as U,V values) bytes x+1-? - packed chroma table entry numbers
Luma data is packed with left-to-right Huffman codes, chroma data is packed with the same
wc3_unpack as the Wing Commander III MVE Video Codec.
Huffman codes for luma
Huffman tree is stored in this form:
1 byte - number of symbols (usually 32) 1 byte - EOF symbol (usually 32) [symbols*2] bytes - tree description
Tree description consists of tree nodes pointing to other nodes or symbols (if node value is equal or less than EOF symbol).
Decoding is done by reading bits in MSB order and traversing the tree (root node is the last node of the tree).
Intra frame (type 0)
Only every second pixel value is coded, the other half is interpolated as an average of their right and left neighbours. Coded values are 5-bit delta coded and expanded to 6-bit range.
The top row uses deltas between current and left neighbour, the rest of lines use top neighbour for prediction.
After interpolation, an optional delta enhancement block may exist be present to refine interpolated pixels (called luma refinements above). The block is half-size, as it only adjusts the interpolated pixels. The values in this block are multiplied by 2 before adding to the interpolated values, which are then clamped via (val & 0x3f).
For details please refer to ffmpeg's
Chroma values use the 16-bit symbol lookup table prior to the packed data for storing possible chroma values.
- The table entries are either 5-bit precision for WCIV (xxxUUUUU VVVVVxxx), or 8-bit precision (UUUUUUUU VVVVVVVV) for Crusader.
- After the table is a packed list of 8-bit values, each representing a 1-indexed table offset (0 means do not change the previous frame's chroma). The unpacking algorithm for this data is the same as the Wing Commander III MVE Video Codec.
Inter frame (type 1)
Frame type 1 luma employs the same principle of coding as frame type 0, but the previous frame's luma values are used for prediction.
Type 1 frames also optionally include a second luma refinement block (offset is 0 if this block is not present). The values in this block are simply added to the values in the first block, also multiplied by 2. Note: this second block is not supported by the ffmpeg implementation, which causes it to often look blockier than the original game.