TGA

edit

TGA (Truevision TGA) is a simple format of asset pipelines and game tools. TgaEncoder writes true-color and grayscale images, uncompressed or run-length encoded, without loss for 8-bit pixels.

What is read and written

ReadingWriting
Image typesTrue-color, grayscale and color-mapped, uncompressed or run-lengthTrue-color and grayscale, uncompressed or run-length
Depths15/16, 24 and 32-bit color, 8-bit gray, gray with an attribute byte, 8 and 16-bit color-map indexes8-bit gray, 24-bit BGR, 32-bit BGRA
AlphaStraight alpha, as the image descriptor declares itStraight alpha for pixel formats with alpha
MetadataNoneNone

Gray pixel formats are written as 8-bit grayscale, pixel formats with alpha as 32-bit BGRA and the others as 24-bit BGR. Color-mapped and 15/16-bit files are read, never written.

Save a TGA file

public static ImageFormat SaveTga(string inputPath, string tgaPath)
{
    using var image = Image.Load(inputPath);

    // TGA stores one still image: save the first frame. Run-length packets are lossless and usually smaller on flat
    // colors; uncompressed rows (the default) are the most widely readable. 16-bit images are rounded to 8 bits only
    // with consent.
    image.Frames[0].Save(tgaPath, new TgaEncoder { Compression = TgaCompression.RunLength, AllowBitDepthReduction = true });

    // TGA has no signature: DetectFormat recognizes it from its whole 18-byte header
    var header = new byte[Image.FormatDetectionPrefixLength];
    using var stream = File.OpenRead(tgaPath);
    stream.ReadExactly(header);
    return Image.DetectFormat(header);
}

Options

OptionWhat it doesDefault
CompressionRunLength writes run-length packets, which never cross a row; None writes uncompressed rows, the most widely readable outputNone
AllowBitDepthReductionLets 16-bit pixel formats be rounded to 8 bitsfalse
MetadataHandlingWhat to do with metadata, which TGA cannot storeStrict

The .tga, .icb, .vda and .vst extensions select TgaEncoder with its defaults.

TGA has no signature

Every other format starts with a signature; a TGA file is recognized from a plausible 18-byte header, and only after every other format. Image.DetectFormat therefore needs Image.FormatDetectionPrefixLength (18) bytes, as in the example above.

Pitfalls

  • TGA stores one frame: save one frame of an animation with image.Frames[i].Save.
  • TGA stores no metadata: an ICC profile, EXIF, XMP, an orientation, a resolution or text entries follow MetadataHandling, which rejects them by default.
  • A side is at most 65,535 pixels.
  • The optional TGA 2.0 footer is at the end of the file, so the decoder reads a stream to its end: nothing can follow a TGA file on the same stream.
  • A file without a footer is a TGA 1.0 file, whose trailing bytes mean nothing: a file cut after its pixel data is a valid file, so truncation is only detected inside the pixel data.
  • Premultiplied alpha, which the extension area can declare, is rejected with an UnsupportedImageFeatureException.
  • A 16-bit grayscale file is read as an 8-bit gray sample and an attribute byte (gray and alpha when the descriptor declares 8 alpha bits), never as a 16-bit luminance.