Image graphics directory

From Worms Knowledge Base

Jump to: navigation, search
(Up to File formats)

Worms World Party Aqua stores several images belonging to one user interface element (like the state images of one button) in an IGD file.

File format

Type Size Name Description
uint32 4 Unknown
uint32 4 Unknown
uint32[2] 8 Negative Center XY center coordinate of all image, in pixels and negated.
uint32[2] 8 Center XY center coordinate of all images, in pixels.
uint32[2] 8 Dimensions XY size of all images, in pixels.
uint32 4 Palette Size Number of colors in the following palette. This palette is used by all images stored in this file.
uint32[PaletteSize] 4 × PaletteSize Palette Colors Each is an RGBA value.
uint32 4 Image Count Number of Image structures following.
Image[ImageCount] - Images See below on how the structure is defined.

Each Image structure is defined as follows:

Type Size Name Description
uint32 4 Unknown
uint32 4 Index 0-based index of the image in this file.
uint32 4 Unknown
uint32 4 Unknown
uint32[2] 8 Dimensions XY size of this image. Always the same as defined above.
uint32[2] 8 Center XY center coordinate of this image. Similar to the one defined above.
uint32 4 Uncompressed Size Uncompressed size of image data.
uint32 4 Compressed Size Compressed size of image data following.
uint8[CompressedSize] CompressedSize Compressed Data See below on how to decompress it.

Data compression

Each input byte is either a byte of decompressed data or a marker for a following command (0xFF). A command consists of 4 bytes which specify the range of bytes to copy from already decompressed data. Two check bytes follow which must be 0x0080, or the decompression failed.

The following C# algorithm can be used to decompress the data of each image:

static byte[] IgdDecompress(Stream stream, int compressedSize, int decompressedSize)
{
    byte[] decompressed = new byte[decompressedSize];
    int i = 0;

    long endPosition = stream.Position + compressedSize - 2;
    while (stream.Position < endPosition)
    {
        byte b = stream.Read1Byte();
        if (b == 0xFF)
        {
            // Copy existing data.
            byte mask1 = stream.Read1Byte();
            byte mask2 = stream.Read1Byte();
            int offset = mask2 & 0x0FFF | ((mask1 & 0x000F) << 8);
            int bytesToCopy = stream.Read1Byte();
            for (int j = 0; j < bytesToCopy; j++)
            {
                int outIndex = i + j;
                decompressed[outIndex] = decompressed[outIndex - offset];
            }
            i += bytesToCopy;
        }
        else
        {
            // Raw transfer next byte.
            decompressed[i++] = b;
        }
    }

    if (stream.ReadUInt16() != 0x0080)
        throw new InvalidDataException("Invalid check bytes at end of compressed image data.");
    return decompressed;
}
Personal tools