All formats

Pfim

LanguageC# (.NET Standard 2.0)
LicenseMIT
Repositorygithub.com/nickbabcock/Pfim
DocumentationREADME and the samples in the repository
Depends onnothing
Read / writeyes / no; palette, grayscale and true-color TGA, raw and RLE

Pfim decodes TGA and DDS files into a raw pixel buffer and does nothing else: no drawing, no encoding. It’s fast, has no dependencies and works on any .NET runtime, which makes it a good fit for game tools, modding utilities and texture viewers. You pass the buffer to whatever displays or saves images: WPF, GDI+, a GPU texture, or ImageSharp.

Pixels come out in the byte order of the file: BGR for 24-bit and BGRA for 32-bit images, which matches the Bgra32 / Format32bppArgb layouts of WPF and GDI+.

Installation#

Shell
dotnet add package Pfim

Basic usage: decode a TGA#

C#
using Pfim;

using IImage image = Pfimage.FromFile("in.tga");
Console.WriteLine($"{image.Width} x {image.Height}, {image.BitsPerPixel} bpp, format {image.Format}");
Console.WriteLine($"stride {image.Stride}, {image.DataLen} bytes of pixels");
// image.Data holds the pixels; image.Format is Rgb24, Rgba32, Rgb8, R5g5b5 ...

Pfimage.FromFile checks for the DDS magic and otherwise decodes the file as TGA.

How to convert a TGA to PNG with ImageSharp#

C#
using Pfim;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;

using IImage tga = Pfimage.FromFile("in.tga");
using Image png = tga.Format switch
{
    Pfim.ImageFormat.Rgba32 => Image.LoadPixelData<Bgra32>(tga.Data.AsSpan(0, tga.DataLen), tga.Width, tga.Height, tga.Stride),
    Pfim.ImageFormat.Rgb24 => Image.LoadPixelData<Bgr24>(tga.Data.AsSpan(0, tga.DataLen), tga.Width, tga.Height, tga.Stride),
    _ => throw new NotSupportedException(tga.Format.ToString()),
};
png.SaveAsPng("out.png");

How to show a TGA in WPF#

C#
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Pfim;

using IImage tga = Pfimage.FromFile("in.tga");
PixelFormat format = tga.Format switch
{
    Pfim.ImageFormat.Rgba32 => PixelFormats.Bgra32,
    Pfim.ImageFormat.Rgb24 => PixelFormats.Bgr24,
    Pfim.ImageFormat.Rgb8 => PixelFormats.Gray8,
    _ => throw new NotSupportedException(tga.Format.ToString()),
};
BitmapSource bitmap = BitmapSource.Create(tga.Width, tga.Height, 96, 96, format, null, tga.Data, tga.Stride);
// imageControl.Source = bitmap;

How to read the TGA header#

Cast to Targa to get the parsed header:

C#
using Pfim;

using IImage image = Pfimage.FromFile("in.tga");
if (image is Targa targa)
{
    TargaHeader h = targa.Header;
    Console.WriteLine($"type {h.ImageType}, compressed {h.IsCompressed}, orientation {h.Orientation}, id \"{h.ImageId}\"");
}

How to decode a TGA from a stream#

C#
using var stream = File.OpenRead("texture.tga");
using IImage image = Targa.Create(stream, new PfimConfig());

Tips#