using System; namespace Oni.Imaging { internal static class TgaReader { public static Surface Read(string filePath) { using (var reader = new BinaryReader(filePath)) { var header = TgaHeader.Read(reader); Surface surface; switch (header.ImageType) { case TgaImageType.TrueColor: surface = LoadTrueColor(header, reader); break; case TgaImageType.RleTrueColor: surface = LoadRleTrueColor(header, reader); break; default: throw new NotSupportedException(string.Format("Invalid or unsupported TGA image type {0}", header.ImageType)); } if (header.XFlip) surface.FlipHorizontal(); if (!header.YFlip) surface.FlipVertical(); return surface; } } private static Surface LoadTrueColor(TgaHeader header, BinaryReader reader) { int pixelSize = header.PixelSize; var format = header.GetSurfaceFormat(); var dst = new Surface(header.Width, header.Height, format); var src = reader.ReadBytes(header.Width * header.Height * pixelSize); int srcOffset = 0; for (int y = 0; y < header.Height; y++) { for (int x = 0; x < header.Width; x++) { dst[x, y] = header.GetPixel(src, srcOffset); srcOffset += pixelSize; } } return dst; } private static Surface LoadRleTrueColor(TgaHeader header, BinaryReader reader) { int pixelSize = header.PixelSize; var format = header.GetSurfaceFormat(); var dst = new Surface(header.Width, header.Height, format); var src = reader.ReadBytes(reader.Length - reader.Position); int srcOffset = 0; int y = 0; int x = 0; var color = Color.Black; while (y < header.Height) { int packetType = src[srcOffset++]; int packetPixelCount = (packetType & 127) + 1; bool isRle = ((packetType & 128) != 0); for (int i = 0; i < packetPixelCount && y < header.Height; i++) { if (i == 0 || !isRle) { color = header.GetPixel(src, srcOffset); srcOffset += pixelSize; } dst[x, y] = color; x++; if (x == header.Width) { x = 0; y++; } } } return dst; } } }