Skip to content

Instantly share code, notes, and snippets.

@mvi
Created August 20, 2014 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mvi/284fa3b6fa9422da8297 to your computer and use it in GitHub Desktop.
Save mvi/284fa3b6fa9422da8297 to your computer and use it in GitHub Desktop.
Dune 2000 TGA <-> PNG Converter
// Really simple converter for Dune 2000 TGA format files <-> PNG files with WPF. Probably full of bugs since I coded it while cooking ;-)
using System;
using System.Drawing;
using System.IO;
using System.Windows;
using Microsoft.Win32;
namespace TGAConverter
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Filter = "TGA Image (*.tga)|*.tga";
if (openDialog.ShowDialog() == true)
{
ConvertTGAToPNG(openDialog.FileName);
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Filter = "PNG Image (*.png)|*.png";
if (openDialog.ShowDialog() == true)
{
ConvertPNGToTGA(openDialog.FileName);
}
}
private void ConvertTGAToPNG(string filename)
{
try
{
FileStream fs = File.OpenRead(filename);
BinaryReader br = new BinaryReader(fs);
byte idLength = br.ReadByte();
byte colorMapType = br.ReadByte();
byte imageType = br.ReadByte();
if (imageType != 2)
{
MessageBox.Show("Unsupported TGA Image Type. Must be 2 uncompressed true-color image");
return;
}
byte[] colorMapSpec = br.ReadBytes(5);
Int16 xOrigin = br.ReadInt16();
Int16 yOrigin = br.ReadInt16();
Int16 width = br.ReadInt16();
Int16 height = br.ReadInt16();
byte pixelDepth = br.ReadByte();
if (pixelDepth != 16)
{
MessageBox.Show("Pixel depth must be set to 16");
return;
}
byte imageDescriptor = br.ReadByte();
Bitmap bitmap = new Bitmap(width, height);
UInt16 color;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
color = br.ReadUInt16();
//Extract colour information from int 16
//bits = XRRRRRGGGGGBBBBB
byte red = (byte)((color >> 10) & 0x1f);
byte green = (byte)((color >> 5) & 0x1f);
byte blue = (byte)(color & 0x1f);
bitmap.SetPixel(x, (height - 1) - y, System.Drawing.Color.FromArgb(Convert.ToByte(255.0f * (float)red / 31), Convert.ToByte(255.0f * (float)green / 31), Convert.ToByte(255.0f * (float)blue / 31)));
}
}
br.Close();
fs.Close();
string outputPath = System.IO.Path.GetFileNameWithoutExtension(filename) + ".png";
bitmap.Save(outputPath, System.Drawing.Imaging.ImageFormat.Png);
MessageBox.Show("Converted");
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
private void ConvertPNGToTGA(string filename)
{
try
{
Bitmap bitmap = new Bitmap(filename);
string outputPath = System.IO.Path.GetFileNameWithoutExtension(filename) + ".tga";
FileStream fs = File.OpenWrite(outputPath);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write((byte)0);
bw.Write((byte)0);
bw.Write((byte)2);
bw.Write((byte)0);
bw.Write((byte)0);
bw.Write((byte)0);
bw.Write((byte)0);
bw.Write((byte)0);
bw.Write((Int16)0);
bw.Write((Int16)0);
bw.Write((Int16)bitmap.Width);
bw.Write((Int16)bitmap.Height);
bw.Write(16);
bw.Write(1);
for (int y = 0; y < bitmap.Height; y++)
{
for (int x = 0; x < bitmap.Width; x++)
{
System.Drawing.Color color = bitmap.GetPixel(x, (bitmap.Height - 1) - y);
byte red = (byte)(color.R / 8);
byte green = (byte)(color.G / 8);
byte blue = (byte)(color.B / 8);
UInt16 outputColor = 0;
outputColor = red;
outputColor = (UInt16)(outputColor << 5);
outputColor |= green;
outputColor = (UInt16)(outputColor << 5);
outputColor |= blue;
bw.Write(outputColor);
}
}
bw.Close();
fs.Close();
bitmap.Dispose();
MessageBox.Show("Converted");
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment