using System;
using System.Collections.Generic;
namespace Raw2Picture
{
public class PreFilterString
{
public class FilterComponent
{
public string Name = "";
public uint BitMask;
public int BitStartPos;
public int BitCount;
public FilterComponent(string n, uint bm, int bst, int bc)
{
Name = n;
BitMask = bm;
BitStartPos = bst;
BitCount = bc;
}
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 PreFilterString()
{
reset();
}
private void reset()
{
theString = "";
perPixelBitCount = 0;
perPixelByteCount = 0;
dontCares.Clear();
setOnes.Clear();
setZeros.Clear();
}
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; } }
public readonly char[] ValidFormatChars = { 'x', 'z', 's', 'X', 'Z', 'S' };
private List<FilterComponent> dontCares = new List<FilterComponent>(32);
public uint DontCareBitMask
{
get
{
uint result = 0;
foreach (FilterComponent fc in dontCares)
{
result |= fc.BitMask;
}
return result;
}
}
private List<FilterComponent> setOnes = new List<FilterComponent>(32);
public uint SetOneBitMask
{
get
{
uint result = 0;
foreach (FilterComponent fc in setOnes)
{
result |= fc.BitMask;
}
return result;
}
}
private List<FilterComponent> setZeros = new List<FilterComponent>(32);
public uint SetZeroBitMask
{
get
{
uint result = 0;
foreach (FilterComponent fc in setZeros)
{
result |= fc.BitMask;
}
return result;
}
}
public String parse(string s)
{
int bitMaskStart = 0;
reset();
if (s.Length == 0)
{
return "PreFilterString: 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 = "PreFilterString: 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 "PreFilterString: 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 "PreFilterString: 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 "PreFilterString: 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 == 'x') || (currentChar == 'X'))
{
dontCares.Add(new FilterComponent("don't care", mask, bitMaskStart, bitCount));
}
else if ((currentChar == 's') || (currentChar == 'S'))
{
setOnes.Add(new FilterComponent("set to one", mask, bitMaskStart, bitCount));
}
else if ((currentChar == 'z') || (currentChar == 'Z'))
{
setZeros.Add(new FilterComponent("set to zero", mask, bitMaskStart, bitCount));
}
else
{
reset();
return "PreFilterString error: unknown char: " + currentChar;
}
bitMaskStart += bitCount;
}
catch (Exception ex)
{
reset();
return "PreFilterString 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 "PreFilterString: 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;
}
}
}