using System;
using System.Windows.Forms;
using System.IO;
namespace Raw2Picture
{
public partial class Form1 : Form
{
private ColorFormatString cfs = null;
private PreFilterString pfs = null;
private PictureBuffer pictureBuffer = null;
private string fileName = null;
public static string NEWLINE = Environment.NewLine;
private bool allowUserInput = false;
public Form1()
{
InitializeComponent();
cfs = new ColorFormatString();
pfs = new PreFilterString();
}
private void Form1_Shown(object sender, EventArgs e)
{
textBox2.Text = "320";
textBox3.Text = "240";
textBox4.Text = "X32";
textBox1.Text = "R8G8B8A8";
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
setToolTips();
log("Welcome to Raw2Picture by Sebastion Roll - Version 2008/10/06");
try
{
String[] args = Environment.GetCommandLineArgs();
if (args.Length >= 6)
{
fileName = args[1];
log("input file set to: " + fileName);
textBox2.Text = args[2]; // width
textBox3.Text = args[3]; // height
textBox3.Text = args[4]; // pre filter
textBox1.Text = args[5]; // color format
convert();
}
if (args.Length >= 7)
{
saveConvertedPicture(args[6]);
}
if (args.Length >= 8)
{
if (args[7].Equals("noDialog"))
{
Application.Exit();
}
}
}
catch (Exception ex)
{
handleError(ex.Message);
}
allowUserInput = true;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
openFileDialog1.InitialDirectory = Application.StartupPath;
openFileDialog1.Filter = "All Files (*.*)|*.*";
openFileDialog1.Title = "Open File";
DialogResult dr = openFileDialog1.ShowDialog();
if (dr == DialogResult.OK)
{
fileName = openFileDialog1.FileName;
if (fileName.ToLower().EndsWith("png") ||
fileName.ToLower().EndsWith("bmp") ||
fileName.ToLower().EndsWith("jpg") ||
fileName.ToLower().EndsWith("gif"))
{
loadPictureFromFile(fileName);
}
else
{
log("input file set to: " + fileName);
convert();
}
}
}
catch (Exception ex)
{
handleError(ex.Message);
}
}
private void button3_Click(object sender, EventArgs e)
{
try
{
if (pictureBuffer != null)
{
saveFileDialog1.Filter = "All Files (*.*)|*.*";
saveFileDialog1.DefaultExt = "png";
saveFileDialog1.Title = "Save BMP or PNG or JPG or GIF";
DialogResult dr = saveFileDialog1.ShowDialog();
if (dr == DialogResult.OK)
{
saveConvertedPicture(saveFileDialog1.FileName);
}
}
else
{
log("savePicture: nothing to save");
}
}
catch (Exception ex)
{
handleError(ex.Message);
}
}
private void convert()
{
FileStream fs = null;
BinaryReader br = null;
try
{
if (fileName == null)
{
log("convert: no input file");
return;
}
if (!File.Exists(fileName))
{
handleError("convert: input file not found: " + fileName);
return;
}
if (!isNumeric(textBox2.Text))
{
log("convert: width is no numeric expression: " + textBox2.Text);
return;
}
if (Convert.ToInt32(textBox2.Text) == 0)
{
log("convert: width is zero");
return;
}
if (!isNumeric(textBox3.Text))
{
log("convert: height is no numeric expression: " + textBox3.Text);
return;
}
if (Convert.ToInt32(textBox3.Text) == 0)
{
log("convert: height is zero");
return;
}
fs = new FileStream(fileName, FileMode.Open);
br = new BinaryReader(fs);
if (fs.Length == 0)
{
log("convert: input file length is zero");
return;
}
String result = "";
result = pfs.parse(textBox4.Text);
if (result.Equals("ok"))
{
log("PreFilter BytePerPixel: " + pfs.PerPixelByteCount);
log(String.Format("PreFilter DontCareBitMask : {0:X8}", pfs.DontCareBitMask));
log(String.Format("PreFilter SetToOneBitMask : {0:X8}", pfs.SetOneBitMask));
log(String.Format("PreFilter SetToZeroBitMask: {0:X8}", pfs.SetZeroBitMask));
result = cfs.parse(textBox1.Text);
}
if (result.Equals("ok"))
{
log("ColorFormat BytePerPixel: " + cfs.PerPixelByteCount);
log("ColorFormat " + cfs.Red.ToString());
log("ColorFormat " + cfs.Green.ToString());
log("ColorFormat " + cfs.Blue.ToString());
log("ColorFormat " + cfs.Alpha.ToString());
if (pfs.PerPixelByteCount != cfs.PerPixelByteCount)
{
log("*** Warning: PreFilter.BytePerPixel != ColorFormatString.BytePerPixel");
}
int w = Convert.ToInt32(textBox2.Text);
int h = Convert.ToInt32(textBox3.Text);
uint color = 0;
uint rawData = 0;
uint data = 0;
if (pictureBuffer != null)
{
pictureBuffer.Dispose();
}
pictureBuffer = new PictureBuffer(w, h);
pictureBox1.Image = pictureBuffer.Bitmap;
long inputFileLength = fs.Length;
log("input file length (physical): " + inputFileLength + " byte");
long expectedFileLength = w * h * cfs.PerPixelByteCount;
log("input file length (width * height * BytePerPixel): " + expectedFileLength + " byte");
if (inputFileLength != expectedFileLength)
{
log("*** Warning: input file length != width * height * BytePerPixel");
}
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
if (cfs.PerPixelByteCount == 1)
{
rawData = (uint)br.ReadByte() << 24;
}
else if (cfs.PerPixelByteCount == 2)
{
rawData = (uint)br.ReadByte() << 24;
rawData |= (uint)br.ReadByte() << 16;
}
else if (cfs.PerPixelByteCount == 3)
{
rawData = (uint)br.ReadByte() << 24;
rawData |= (uint)br.ReadByte() << 16;
rawData |= (uint)br.ReadByte() << 8;
}
else if (cfs.PerPixelByteCount == 4)
{
rawData = (uint)br.ReadByte() << 24;
rawData |= (uint)br.ReadByte() << 16;
rawData |= (uint)br.ReadByte() << 8;
rawData |= (uint)br.ReadByte() << 0;
}
data = rawData;
uint setZero = pfs.SetZeroBitMask;
setZero = ~setZero;
data = data & setZero;
uint setOne = pfs.SetOneBitMask;
data |= setOne;
uint alpha = data & cfs.Alpha.BitMask;
alpha >>= 32 - (cfs.Alpha.BitStartPos + cfs.Alpha.BitCount);
alpha = (uint)Math.Round(alpha * 256.0 / Math.Pow(2, cfs.Alpha.BitCount));
if (cfs.Alpha.BitCount == 0)
{
alpha = 0xFF;
}
color = alpha << 24;
uint red = data & cfs.Red.BitMask;
red >>= 32 - (cfs.Red.BitStartPos + cfs.Red.BitCount);
red = (uint)Math.Round(red * 256.0 / Math.Pow(2, cfs.Red.BitCount));
color |= red << 16;
uint green = data & cfs.Green.BitMask;
green >>= 32 - (cfs.Green.BitStartPos + cfs.Green.BitCount);
green = (uint)Math.Round(green * 256.0 / Math.Pow(2, cfs.Green.BitCount));
color |= green << 8;
uint blue = data & cfs.Blue.BitMask;
blue >>= 32 - (cfs.Blue.BitStartPos + cfs.Blue.BitCount);
blue = (uint)Math.Round(blue * 256.0 / Math.Pow(2, cfs.Blue.BitCount));
color |= blue << 0;
// 4 bytes per pixel, format: ARGB
pictureBuffer.Integers[y * w + x] = color;
}
}
textBox5.Text = String.Format("{0:X" + cfs.PerPixelByteCount * 2 + "}", rawData >> (32 - cfs.PerPixelByteCount * 8));
textBox6.Text = String.Format("{0:X8}", color);
pictureBox1.Image = pictureBuffer.Bitmap;
log("convert: OK");
}
else
{
log(result);
}
}
catch (EndOfStreamException eofEx)
{
string eofStr = eofEx.Message + NEWLINE + "*** width or height too large ***";
log(eofStr);
}
catch (Exception ex)
{
handleError(ex.Message);
}
finally
{
if (br != null)
{
br.Close();
}
if (fs != null)
{
fs.Close();
fs.Dispose();
}
}
}
public void log(string s)
{
logWindow.Text += s + NEWLINE;
logWindow.SelectionStart = logWindow.Text.Length;
logWindow.ScrollToCaret();
}
public void logProgress(int progress)
{
logWindow.Text = logWindow.Text.Substring(0, logWindow.Text.Length - 3);
logWindow.Text += String.Format("{0:d3}", progress);
logWindow.SelectionStart = logWindow.Text.Length;
logWindow.ScrollToCaret();
}
public void handleError(String error)
{
log(error);
MessageBox.Show(error, "Raw2Picture");
}
public static bool isNumeric(string s)
{
int retNum;
return Int32.TryParse(s, out retNum);
}
private void setToolTips()
{
toolTip1.SetToolTip(textBox2, "Width of picture data");
toolTip1.SetToolTip(textBox3, "Height of picture data");
toolTip1.SetToolTip(textBox1, "How to interprete picture data" + NEWLINE +
"Example 1: R5G6B5 <- MSB 5 bit is red channel. Following 6 bit is green channel. Following 5 bit is blue channel" + NEWLINE +
"Example 2: A1R5G5B5 <- MSB 1 bit is alpha channel. Following 5 bit is red channel. Following 5 bit is green channel. Following 5 bit is blue channel" + NEWLINE +
"Example 3: a8r8b8g8 <- MSB 8 bit is alpha channel. Following 8 bit is red channel. Following 8 bit is blue channel. Following 8 bit is green channel");
toolTip1.SetToolTip(textBox4, "Change data before conversion start" + NEWLINE +
"Example 1: X5S1X10 <- MSB 5 bit dont't care. Following 1 bit set to one. Following 10 bit don't care." + NEWLINE +
"Example 2: S1X15 <- MSB 1 bit set to one. Following 15 bit don't care." + NEWLINE +
"Example 3: X24Z8 <- MSB 24 bit don't care. Following 8 bit set to zero.");
toolTip1.SetToolTip(textBox5, "Last bytes (1..4) of raw input stream");
toolTip1.SetToolTip(textBox6, "Conversion value of last read input stream bytes in ARGB 8888 format");
toolTip1.SetToolTip(button1, "Show dialog to open input file and then convert data" + NEWLINE +
"If selected file is of type PNG, BMP, JPG or GIF: only PreView window is updated.");
toolTip1.SetToolTip(button3, "Show dialog to save PreView as BMP, PNG, JPG or GIF");
toolTip1.SetToolTip(button2, "Save PreView as PNG without any dialog");
toolTip1.SetToolTip(button4, "Save PreView as BMP without any dialog");
toolTip1.SetToolTip(button5, "Save PreView as JPG without any dialog");
toolTip1.SetToolTip(button6, "Save PreView as raw ARGB8888 without any dialog");
toolTip1.SetToolTip(button8, "Save PreView as raw RGBA8888 without any dialog");
toolTip1.SetToolTip(pictureBox1, "Show result of data conversion" + NEWLINE +
"Automatic updated on change of Width, Height, PreFilter, ColorFormat or InputData.");
toolTip1.SetToolTip(button7, "Show help");
}
private void loadPictureFromFile(string fileName)
{
System.Drawing.Bitmap b = null;
try
{
allowUserInput = false;
b = new System.Drawing.Bitmap(fileName);
if (b == null)
{
log("cannot load file");
return;
}
textBox2.Text = "" + b.Width;
textBox3.Text = "" + b.Height;
textBox1.Text = "A8R8G8B8";
logWindow.Text = "";
log("Loading file as PreView, not converting anything. You can save, though.");
if (pictureBuffer != null)
{
pictureBuffer.Dispose();
}
pictureBuffer = new PictureBuffer(b.Width, b.Height);
log("load progress...: ");
for (int y = 0; y < b.Height; y++)
{
for (int x = 0; x < b.Width; x++)
{
pictureBuffer.Integers[y * b.Width + x] = (uint)b.GetPixel(x, y).ToArgb();
}
logProgress((int)(y * 101.0 / b.Height));
Update();
}
pictureBox1.Image = pictureBuffer.Bitmap;
log("");
log("load file OK");
Update();
}
catch (Exception ex)
{
handleError(ex.Message);
}
finally
{
if (b != null)
{
b.Dispose();
}
allowUserInput = true;
}
}
public void saveConvertedPicture(string saveFileName)
{
if (pictureBuffer != null && saveFileName != null)
{
if (!saveFileName.Equals(""))
{
try
{
pictureBuffer.Bitmap.Save(saveFileName);
log("file saved to: " + saveFileName);
}
catch (Exception ex)
{
handleError(ex.Message);
}
}
else
{
log("savePicture: nothing to save");
}
}
else
{
log("savePicture: nothing to save");
}
}
public void quickSaveAs(string fileExtension)
{
if (fileName != null && pictureBuffer != null && fileExtension != null)
{
if (fileName != "" && fileExtension != "")
{
saveConvertedPicture(fileName + fileExtension);
}
else
{
log("quickSave: nothing to save");
}
}
else
{
log("quickSave: nothing to save");
}
}
private void safeRawData(RawFileGenerator.ByteFormat bf)
{
if (fileName != null && pictureBuffer != null)
{
if (fileName != "")
{
RawFileGenerator rfg = new RawFileGenerator();
string result = rfg.writeRawFile(fileName + ".bin", pictureBuffer.Integers, bf);
if (result.Equals("ok"))
{
log("file saved to: " + fileName + ".bin");
}
else
{
log(result);
}
}
else
{
log("quickSave: nothing to save");
}
}
else
{
log("quickSave: nothing to save");
}
}
private void button2_Click(object sender, EventArgs e)
{
quickSaveAs(".png");
}
private void button4_Click(object sender, EventArgs e)
{
quickSaveAs(".bmp");
}
private void button5_Click(object sender, EventArgs e)
{
quickSaveAs(".jpg");
}
private void button6_Click(object sender, EventArgs e)
{
safeRawData(RawFileGenerator.ByteFormat.ARGB8888);
}
private void button8_Click(object sender, EventArgs e)
{
safeRawData(RawFileGenerator.ByteFormat.RGBA8888);
}
private void button7_Click(object sender, EventArgs e)
{
HelpForm hf = new HelpForm();
hf.ShowDialog(this);
}
private void button9_Click(object sender, EventArgs e)
{
if (allowUserInput && fileName != null)
{
if (fileName != "")
{
HexViewForm hvf = new HexViewForm(fileName);
hvf.ShowDialog(this);
hvf.cleanup();
}
}
else
{
log("In Hex View: nothing to show");
}
}
private void button10_Click(object sender, EventArgs e)
{
if (allowUserInput)
{
if (pictureBuffer != null)
{
string tempFile = Environment.CurrentDirectory + "\\temp.tmp";
RawFileGenerator rfg = new RawFileGenerator();
string result = rfg.writeRawFile(tempFile, pictureBuffer.Integers, RawFileGenerator.ByteFormat.ARGB8888);
if (result.Equals("ok"))
{
HexViewForm hvf = new HexViewForm(tempFile);
hvf.ShowDialog(this);
hvf.cleanup();
File.Delete(tempFile);
}
else
{
log("Out Hex View: cannot show output data");
}
}
else
{
log("Out Hex View: nothing to show");
}
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
if (allowUserInput)
{
convert();
}
}
private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
{
if (allowUserInput)
{
if (Char.IsDigit(e.KeyChar))
{
// Digits are OK
}
else if (e.KeyChar == '\b')
{
// Backspace key is OK
}
else
{
// Swallow this invalid key
e.Handled = true;
}
}
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
if (allowUserInput)
{
convert();
}
}
private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
{
if (allowUserInput)
{
if (Char.IsDigit(e.KeyChar))
{
// Digits are OK
}
else if (e.KeyChar == '\b')
{
// Backspace key is OK
}
else
{
// Swallow this invalid key
e.Handled = true;
}
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (allowUserInput)
{
String result = cfs.parse(textBox1.Text);
if (result.Equals("ok"))
{
convert();
}
else
{
log(result);
}
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (allowUserInput)
{
if (cfs.isValidFormatChar(e.KeyChar))
{
// Color format syntax is OK
}
else if (Char.IsDigit(e.KeyChar))
{
// Digits are OK
}
else if (e.KeyChar == '\b')
{
// Backspace key is OK
}
else if (e.KeyChar == 0x0003)
{
// Strg + C is OK
}
else if (e.KeyChar == 0x0016)
{
// Strg + V is OK
}
else
{
// Swallow this invalid key
e.Handled = true;
}
}
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
if (allowUserInput)
{
String result = pfs.parse(textBox4.Text);
if (result.Equals("ok"))
{
convert();
}
else
{
log(result);
}
}
}
private void textBox4_KeyPress(object sender, KeyPressEventArgs e)
{
if (allowUserInput)
{
if (pfs.isValidFormatChar(e.KeyChar))
{
// PreFilter format syntax is OK
}
else if (Char.IsDigit(e.KeyChar))
{
// Digits are OK
}
else if (e.KeyChar == '\b')
{
// Backspace key is OK
}
else if (e.KeyChar == 0x03)
{
// Strg + C is OK
}
else if (e.KeyChar == 0x16)
{
// Strg + V is OK
}
else
{
// Swallow this invalid key
e.Handled = true;
}
}
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 0x1b)
{
Application.Exit();
}
}
}
}