using System;
namespace Raw2Picture
{
public class ColorFormatString
{
public class ColorComponent
{
public uint BitMask;
public int BitStartPos;
public int BitCount;
public string Name = "";
public void reset(string myName)
{
BitMask = 0;
BitStartPos = 0;
BitCount = 0;
Name = myName;
}
public override string ToString()
{
return Name +
String.Format(" BitMask:{0:X8}", BitMask) +
String.Format(" BitStartPos:{0:d2}", BitStartPos) +
String.Format(" BitCount:{0:d2}", BitCount);
}
}
public ColorFormatString()
{
red = new ColorComponent();
green = new ColorComponent();
blue = new ColorComponent();
alpha = new ColorComponent();
reset();
}
private void reset()
{
theString = "";
perPixelBitCount = 0;
perPixelByteCount = 0;
red.reset("red ");
green.reset("green");
blue.reset("blue ");
alpha.reset("alpha");
}
private String theString;
public String TheString { get { return theString; } }
private int perPixelByteCount;
public int PerPixelByteCount { get { return perPixelByteCount; } }
private int perPixelBitCount;
public int PerPixelBitCount { get { return perPixelBitCount; } }
private ColorComponent red;
public ColorComponent Red { get { return red; } }
private ColorComponent green;
public ColorComponent Green { get { return green; } }
private ColorComponent blue;
public ColorComponent Blue { get { return blue; } }
private ColorComponent alpha;
public ColorComponent Alpha { get { return alpha; } }
public readonly char[] ValidFormatChars = { 'r', 'g', 'b', 'a', 'R', 'G', 'B', 'A' };
public String parse(string s)
{
int bitMaskStart = 0;
reset();
if (s.Length == 0)
{
return "ColorFormatString: string length is zero";
}
theString = "" + s;
for (int i = 0; i < s.Length; i += 2)
{
char currentChar = s[i];
if (!isValidFormatChar(currentChar))
{
reset();
String err = "ColorFormatString: unknown char: " + currentChar;
err += Form1.NEWLINE + "hint: following chars are OK: ";
for (int e = 0; e < ValidFormatChars.Length; e++)
{
err += ValidFormatChars[e] + " ";
}
return err;
}
if (s.Length <= i + 1)
{
reset();
return "ColorFormatString: unexpected end of string" +
Form1.NEWLINE + "hint: each char must follow a number" +
Form1.NEWLINE + "hint: current char is: " + currentChar;
}
if (!Form1.isNumeric(s[i + 1].ToString()))
{
reset();
return "ColorFormatString: each char must follow a number" +
Form1.NEWLINE + "hint: current char is: " + currentChar +
Form1.NEWLINE + "hint: this is not a number: " + s[i + 1];
}
try
{
int bitCount = Convert.ToInt32(s[i + 1].ToString());
if (s.Length > i + 2)
{
if (Form1.isNumeric(s[i + 2].ToString()))
{
String twoCharNumber = "" + s[i + 1].ToString() + s[i + 2].ToString();
bitCount = Convert.ToInt32(twoCharNumber);
i++;
if (s.Length > i + 2)
{
if (Form1.isNumeric(s[i + 2].ToString()))
{
reset();
return "ColorFormatString: number too large, only 0..99 supported.";
}
}
}
}
uint mask = 0x00000000;
for (int k = 0; k < bitCount; k++)
{
int bitPos = bitMaskStart + k;
mask |= (uint)((0x80000000) >> bitPos);
}
if ((currentChar == 'r') || (currentChar == 'R'))
{
if (red.BitCount != 0 || red.BitMask != 0 || red.BitStartPos != 0)
{
reset();
return "ColorFormatString error: multiple occurrence of char: " + currentChar;
}
red.BitMask = mask;
red.BitStartPos = bitMaskStart;
red.BitCount = bitCount;
}
else if ((currentChar == 'g') || (currentChar == 'G'))
{
if (green.BitCount != 0 || green.BitMask != 0 || green.BitStartPos != 0)
{
reset();
return "ColorFormatString error: multiple occurrence of char: " + currentChar;
}
green.BitMask = mask;
green.BitStartPos = bitMaskStart;
green.BitCount = bitCount;
}
else if ((currentChar == 'b') || (currentChar == 'B'))
{
if (blue.BitCount != 0 || blue.BitMask != 0 || blue.BitStartPos != 0)
{
reset();
return "ColorFormatString error: multiple occurrence of char: " + currentChar;
}
blue.BitMask = mask;
blue.BitStartPos = bitMaskStart;
blue.BitCount = bitCount;
}
else if ((currentChar == 'a') || (currentChar == 'A'))
{
if (alpha.BitCount != 0 || alpha.BitMask != 0 || alpha.BitStartPos != 0)
{
reset();
return "ColorFormatString error: multiple occurrence of char: " + currentChar;
}
alpha.BitMask = mask;
alpha.BitStartPos = bitMaskStart;
alpha.BitCount = bitCount;
}
else
{
reset();
return "ColorFormatString error: unknown char: " + currentChar;
}
bitMaskStart += bitCount;
}
catch (Exception ex)
{
reset();
return "ColorFormatString error: " + ex.Message;
}
}
perPixelBitCount = bitMaskStart;
if (perPixelBitCount == 8)
{
perPixelByteCount = 1;
}
else if (perPixelBitCount == 16)
{
perPixelByteCount = 2;
}
else if (perPixelBitCount == 24)
{
perPixelByteCount = 3;
}
else if (perPixelBitCount == 32)
{
perPixelByteCount = 4;
}
else if (perPixelBitCount > 32)
{
int bc = perPixelBitCount;
reset();
return "ColorFormatString: BitCount too large, only 32 allowed. BitCount = " + bc;
}
else
{
int bc = perPixelBitCount;
reset();
return "ColorFormatString: BitCount not byte aligned. BitCount = " + bc;
}
return "ok";
}
public bool isValidFormatChar(char c)
{
for (int i = 0; i < ValidFormatChars.Length; i++)
{
if (c == ValidFormatChars[i])
{
return true;
}
}
return false;
}
}
}