| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- using System;
- using System.Drawing;
- using System.Diagnostics;
- using System.IO;
- using System.Text;
- using Exocortex.DSP;
- using System.Reflection;
- using System.Xml.Serialization;
- using System.Collections;
- using System.Security.Cryptography;
- #if TARGET_JVM
- using awt = java.awt;
- using javax.imageio;
- using java.lang;
- using java.security;
- using java.awt.image;
- #else
- using System.Windows.Forms;
- using System.Drawing.Imaging;
- using System.Runtime.InteropServices;
- #endif
- using NUnit.Framework;
- namespace DrawingTestHelper
- {
- #region Results serialization classes
- public sealed class ExpectedResult {
- public ExpectedResult(){}
- public ExpectedResult(string testName, double norm) {
- TestName = testName;
- Norm = norm;
- }
- public string TestName;
- public double Norm;
- }
- public sealed class ExpectedResults {
- [XmlArrayItem(typeof(ExpectedResult))]
- public ArrayList Tests = new ArrayList();
- }
- public sealed class ExpectedResultsHash {
- Hashtable _hash;
- ExpectedResults _suite;
- public ExpectedResultsHash () {
- try {
- using (StreamReader s = new StreamReader (FileName)) {
- _suite = (ExpectedResults)TestSuiteSerializer.Deserialize(s);
- }
- }
- catch {
- _suite = new ExpectedResults ();
- }
- _hash = new Hashtable(_suite.Tests.Count);
- foreach (ExpectedResult res in _suite.Tests)
- _hash[res.TestName] = res.Norm;
- }
- public const string FileName = "ExpectedResults.xml";
- public readonly static XmlSerializer TestSuiteSerializer = new XmlSerializer(typeof(ExpectedResults));
- public double GetNorm(string testName) {
- object res = _hash[testName];
- if (res != null)
- return (double)res;
- return double.NaN;
- }
- public void WriteNorm (string testName, double myNorm) {
- if (_hash.Contains (testName)) {
- for (int i = 0; i < _suite.Tests.Count; i++) {
- ExpectedResult cur = (ExpectedResult) _suite.Tests[i];
- if (cur.TestName == testName) {
- cur.Norm = myNorm;
- break;
- }
- }
- }
- else
- _suite.Tests.Add(new ExpectedResult(testName, myNorm));
- _hash[testName] = myNorm;
- using(StreamWriter w = new StreamWriter(FileName))
- TestSuiteSerializer.Serialize(w, _suite);
- }
- }
- public sealed class CachedResult {
- public CachedResult (){}
- public CachedResult (string testName, string sha1, double norm) {
- TestName = testName;
- SHA1 = sha1;
- Norm = norm;
- DateTime = DateTime.Now;
- }
- public string TestName;
- public string SHA1;
- public double Norm;
- public DateTime DateTime;
- }
- public sealed class CachedResults {
- [XmlArrayItem(typeof(CachedResult))]
- public ArrayList Tests = new ArrayList();
- }
- public class Cache {
- Hashtable _hash;
- CachedResults _results;
- #if TARGET_JVM
- public const string FileName = "CachedResults.xml";
- public const string NewFileName = "NewCachedResults.xml";
- #else
- public const string FileName = "dotnet.CachedResults.xml";
- public const string NewFileName = "dotnet.NewCachedResults.xml";
- #endif
- public readonly static XmlSerializer TestSuiteSerializer =
- new XmlSerializer(typeof(CachedResults));
- public Cache () {
- try {
- using (StreamReader r = new StreamReader(FileName))
- _results = (CachedResults)TestSuiteSerializer.Deserialize(r);
- }
- catch {
- _results = new CachedResults ();
- }
-
- _hash = new Hashtable(_results.Tests.Count);
- foreach (CachedResult res in _results.Tests)
- _hash[res.SHA1] = res.Norm;
- }
- public double GetNorm (string sha1) {
- if (_hash.ContainsKey (sha1))
- return (double)_hash[sha1];
- else
- return double.NaN;
- }
- public void Add (string testName, string sha1, double norm) {
- if (_hash.ContainsKey (sha1))
- throw new ArgumentException ("This SHA1 is already in the cache", "sha1");
- _results.Tests.Add (new CachedResult(testName, sha1, norm));
- _hash.Add (sha1, norm);
- using(StreamWriter w = new StreamWriter(NewFileName))
- TestSuiteSerializer.Serialize(w, _results);
- }
- }
- #endregion
- /// <summary>
- /// Summary description for DrawingTest.
- /// </summary>
- public abstract class DrawingTest {
- public const float DEFAULT_FLOAT_TOLERANCE = 1e-5f;
- public const int DEFAULT_IMAGE_TOLERANCE = 2;
- Graphics _graphics;
- protected Bitmap _bitmap;
- static string _callingFunction;
- //static int _counter;
- static Hashtable _mpFuncCount = new Hashtable();
- static bool _showForms = false;
- static bool _createResults = true;
- protected string _ownerClass = "";
- protected Hashtable _specialTolerance = null;
- protected readonly static ExpectedResultsHash ExpectedResults = new ExpectedResultsHash ();
- protected readonly static Cache cache = new Cache ();
- public Graphics Graphics {get {return _graphics;}}
- public Bitmap Bitmap {get { return _bitmap; }}
- public Hashtable SpecialTolerance
- {
- get {return _specialTolerance;}
- set {_specialTolerance = value;}
- }
- public string OwnerClass
- {
- get {return _ownerClass;}
- set {_ownerClass = value;}
- }
- public static bool ShowForms
- {
- get {return _showForms;}
- set {_showForms = value;}
- }
- public static bool CreateResults {
- get {return _createResults;}
- set {_createResults = value;}
- }
- protected DrawingTest() {}
-
- private void Init (int width, int height) {
- Init (new Bitmap (width, height));
- }
- private void Init (Bitmap bitmap) {
- _bitmap = bitmap;
- _graphics = Graphics.FromImage (_bitmap);
- }
- protected abstract string DetermineCallingFunction ();
- protected interface IMyForm {
- void Show ();
- }
- protected abstract IMyForm CreateForm (string title);
- public void Show () {
- CheckCounter ();
- if (!ShowForms)
- return;
- IMyForm form = CreateForm(_callingFunction + _mpFuncCount[_callingFunction]);
- form.Show ();
- }
-
- static protected string TestName {
- get {
- return _callingFunction + ":" + _mpFuncCount[_callingFunction]/* + ".dat"*/;
- }
- }
- #region GetImageFFTArray
- private static ComplexF[] GetImageFFTArray(Bitmap bitmap) {
- float scale = 1F / (float) System.Math.Sqrt(bitmap.Width * bitmap.Height);
- ComplexF[] data = new ComplexF [bitmap.Width * bitmap.Height * 4];
- int offset = 0;
- for( int y = 0; y < bitmap.Height; y ++ )
- for( int x = 0; x < bitmap.Width; x ++ ) {
- Color c = bitmap.GetPixel (x, y);
- float s = 1F;
- if( (( x + y ) & 0x1 ) != 0 ) {
- s = -1F;
- }
- data [offset++] = new ComplexF( c.A * s / 256F, 0);
- data [offset++] = new ComplexF( c.R * s / -256F, 0);
- data [offset++] = new ComplexF( c.G * s / 256F, 0);
- data [offset++] = new ComplexF( c.B * s / -256F, 0);
- }
-
- Fourier.FFT3( data, 4, bitmap.Width, bitmap.Height, FourierDirection.Forward );
-
- for( int i = 0; i < data.Length; i ++ ) {
- data[i] *= scale;
- }
- return data;
- }
- #endregion
- abstract public string CalculateSHA1 ();
-
- public static double CalculateNorm (Bitmap bitmap) {
- ComplexF[] matrix = GetImageFFTArray(bitmap);
- double norm = 0;
- int size_x = 4; //ARGB values
- int size_y = bitmap.Width;
- int size_z = bitmap.Height;
- for (int x=1; x<=size_x; x++) {
- double norm_y = 0;
- for (int y=1; y<=size_y; y++) {
- double norm_z = 0;
- for (int z=1; z<=size_z; z++) {
- ComplexF cur = matrix[(size_x-x)+size_x*(size_y-y)+size_x*size_y*(size_z-z)];
- norm_z += cur.GetModulusSquared ();// * z;
- }
- norm_y += norm_z;// * y;
- }
- norm += norm_y;// * x;
- }
- return norm;
- }
- public double GetNorm () {
- string sha1 = CalculateSHA1 ();
- double norm = cache.GetNorm (sha1);
- if (double.IsNaN (norm)) {
- norm = CalculateNorm (_bitmap);
- cache.Add (TestName, sha1, norm);
- //_bitmap.Save(TestName.Replace(":", "_"));
- }
- return norm;
- }
- protected abstract double GetExpectedNorm (double myNorm);
- private void CheckCounter () {
- string callFunc = DetermineCallingFunction ();
- _callingFunction = callFunc;
- if (!_mpFuncCount.Contains(_callingFunction)) {
-
- _mpFuncCount[_callingFunction] = 1;
- }
- else {
- int counter = (int)_mpFuncCount[_callingFunction];
- counter ++;
- _mpFuncCount[_callingFunction] = counter;
- }
- }
- public static void AssertAlmostEqual (float expected, float actual)
- {
- AssertAlmostEqual (expected, actual, DEFAULT_FLOAT_TOLERANCE);
- }
-
- public static void AssertAlmostEqual (float expected, float actual, float tolerance)
- {
- string msg = String.Format("\nExpected : {0} \nActual : {1}",expected.ToString(),actual.ToString());
- AssertAlmostEqual (expected, actual, tolerance, msg);
- }
- private static void AssertAlmostEqual (float expected, float actual, float tolerance, string message)
- {
- float error = System.Math.Abs ((expected - actual) / (expected + actual + float.Epsilon));
- Assert.IsTrue (error < tolerance, message);
- }
- public static void AssertAlmostEqual (PointF expected, PointF actual)
- {
- string msg = String.Format("\nExpected : {0} \n Actual : {1}",expected.ToString(),actual.ToString());
- AssertAlmostEqual (expected.X, actual.X, DEFAULT_FLOAT_TOLERANCE, msg);
- AssertAlmostEqual (expected.Y, actual.Y, DEFAULT_FLOAT_TOLERANCE, msg);
- }
- /// <summary>
- /// Checks that the given bitmap norm is similar to expected
- /// </summary>
- /// <param name="tolerance">tolerance in percents (0..100)</param>
- /// <returns></returns>
- ///
- public bool Compare (double tolerance) {
- CheckCounter ();
- double error = CompareToExpectedInternal()*100;
- if (SpecialTolerance != null)
- return error <= GetSpecialTolerance(TestName);
- return error <= tolerance;
- }
- public bool PDCompare (double tolerance) {
- Bitmap ri = GetReferenceImage(TestName);
- if (ri == null)
- return true;
- double error = PDComparer.Compare(ri, _bitmap);
- return error <= tolerance;
- }
-
- public bool Compare () {
- CheckCounter ();
- double error = CompareToExpectedInternal()*100;
-
- if (SpecialTolerance != null)
- return error <= GetSpecialTolerance(TestName);
- return error <= DEFAULT_IMAGE_TOLERANCE;
- }
- public bool PDCompare () {
- Bitmap ri = GetReferenceImage(TestName);
- if (ri == null)
- return true;
- double error = PDComparer.Compare(ri, _bitmap);
- return error <= DEFAULT_IMAGE_TOLERANCE;
- }
- protected abstract Bitmap GetReferenceImage(string testName);
- protected double GetSpecialTolerance(string testName) {
- try {
- string shortTestName = testName.Substring( testName.LastIndexOf(".") + 1 );
- object o = SpecialTolerance[shortTestName];
- if (o == null)
- return DEFAULT_IMAGE_TOLERANCE;
- return Convert.ToDouble(o);
- }
- catch (System.Exception) {
- return DEFAULT_IMAGE_TOLERANCE;
- }
- }
- public void AssertCompare () {
- CheckCounter ();
- Assert.IsTrue ((CompareToExpectedInternal () * 100) < DEFAULT_IMAGE_TOLERANCE);
- }
- public void AssertCompare (double tolerance) {
- CheckCounter ();
- Assert.IsTrue ((CompareToExpectedInternal () * 100) < tolerance);
- }
-
- public double CompareToExpected () {
- CheckCounter ();
- return CompareToExpectedInternal ();
- }
- double CompareToExpectedInternal () {
- if (ShowForms)
- return 0;
- double norm = GetNorm ();
- double expNorm = GetExpectedNorm (norm);
- return System.Math.Abs (norm-expNorm)/(norm+expNorm+double.Epsilon);
- }
- public static DrawingTest Create (int width, int height) {
- return Create(width, height, "GraphicsFixture");
- }
- public static DrawingTest Create (int width, int height, string ownerClass) {
- DrawingTest test;
- #if TARGET_JVM
- test = new JavaDrawingTest ();
- #else
- test = new NetDrawingTest ();
- #endif
- test.Init (width, height);
- test.OwnerClass = ownerClass;
- return test;
- }
- }
- #if TARGET_JVM
- internal class JavaDrawingTest:DrawingTest {
- java.awt.image.BufferedImage _image;
- java.awt.image.BufferedImage Image {
- get {
- if (_image != null)
- return _image;
- Type imageType = typeof (Bitmap);
- PropertyInfo [] props = imageType.GetProperties (
- BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
- PropertyInfo prop = null;
- foreach (PropertyInfo p in props) {
- if (p.Name == "NativeObject")
- if (p.PropertyType == typeof(java.awt.image.BufferedImage))
- prop = p;
- }
- MethodInfo method = prop.GetGetMethod (true);
- _image = (java.awt.image.BufferedImage) method.Invoke (_bitmap, new object [0]);
- return _image;
- }
- }
- public JavaDrawingTest () {}
- protected override double GetExpectedNorm (double myNorm) {
- return ExpectedResults.GetNorm(TestName);
- }
- protected override Bitmap GetReferenceImage(string testName) {
- try{
- string dotNetResultsFolder = @"..\Debug\";
- string fileName = dotNetResultsFolder + testName.Replace(":", "_") + ".png";
- return new Bitmap(fileName);
- }
- catch(System.Exception e) {
- throw new System.Exception("Error creating .Net reference image");
- }
- }
- private class JavaForm:java.awt.Dialog,IMyForm {
- class EventListener : [email protected] {
- #region WindowListener Members
- public void windowOpened([email protected] arg_0) {
- // TODO: Add ttt.windowOpened implementation
- }
- public void windowActivated([email protected] arg_0) {
- // TODO: Add ttt.windowActivated implementation
- }
- public void windowClosed([email protected] arg_0) {
- // TODO: Add ttt.windowClosed implementation
- }
- public void windowDeiconified([email protected] arg_0) {
- // TODO: Add ttt.windowDeiconified implementation
- }
- public void windowIconified([email protected] arg_0) {
- // TODO: Add ttt.windowIconified implementation
- }
- public void windowClosing([email protected] arg_0) {
- // TODO: Add ttt.windowClosing implementation
- java.awt.Window w = arg_0.getWindow();
- java.awt.Window par = w.getOwner ();
- w.dispose();
- par.dispose ();
- }
- public void windowDeactivated([email protected] arg_0) {
- // TODO: Add ttt.windowDeactivated implementation
- }
- #endregion
- }
- java.awt.Image _image;
- Size _s;
- public JavaForm (string title, java.awt.Image anImage, Size s)
- : base(new java.awt.Frame(), title, true) {
- _image = anImage;
- _s = s;
-
- addWindowListener(new EventListener());
- }
- public override void paint (java.awt.Graphics g) {
- base.paint (g);
- awt.Insets insets = this.getInsets ();
- g.drawImage (_image, insets.left, insets.top, null);
- }
- void IMyForm.Show () {
- awt.Insets insets = this.getInsets ();
- base.setSize (_s.Width + insets.left + insets.right,
- _s.Width + insets.top + insets.bottom);
- this.show ();
- //save the image
- //ImageIO.write((java.awt.image.RenderedImage)_image, "png", new java.io.File("test.java.png"));
- }
- }
- protected override IMyForm CreateForm(string title) {
- return new JavaForm (title, Image, _bitmap.Size);
- }
-
- protected override string DetermineCallingFunction() {
- System.Exception e = new System.Exception ();
- java.lang.Class c = vmw.common.TypeUtils.ToClass (e);
- java.lang.reflect.Method m = c.getMethod ("getStackTrace",
- new java.lang.Class [0]);
- java.lang.StackTraceElement [] els = (java.lang.StackTraceElement [])
- m.invoke (e, new object [0]);
- java.lang.StackTraceElement el = els [4];
- return el.getClassName () + "." + _ownerClass + "." + el.getMethodName ();
- }
- public override string CalculateSHA1() {
- MessageDigest md = MessageDigest.getInstance ("SHA");
- DataBufferInt dbi = (DataBufferInt) Image.getRaster ().getDataBuffer ();
- for (int i=0; i<dbi.getNumBanks (); i++) {
- int [] curBank = dbi.getData (i);
- for (int j=0; j<curBank.Length; j++) {
- int x = curBank[j];
- md.update ((sbyte) (x & 0xFF));
- md.update ((sbyte) ((x>>8) & 0xFF));
- md.update ((sbyte) ((x>>16) & 0xFF));
- md.update ((sbyte) ((x>>24) & 0xFF));
- }
- }
- byte [] resdata = (byte[])vmw.common.TypeUtils.ToByteArray(md.digest());
- return Convert.ToBase64String (resdata);
- }
- }
- #else
- internal class NetDrawingTest:DrawingTest {
- public NetDrawingTest () {}
- protected override double GetExpectedNorm (double myNorm) {
- if (CreateResults)
- ExpectedResults.WriteNorm (TestName, myNorm);
- return myNorm;
- }
- protected override Bitmap GetReferenceImage(string testName) {
- try{
- string fileName = testName.Replace(":", "_") + ".png";
- _bitmap.Save( fileName );
- return null;
- }
- catch(System.Exception e) {
- throw new System.Exception("Error creating .Net reference image");
- }
- }
- private class NetForm:Form,IMyForm {
- Image image;
- public NetForm(string title, Image anImage):base() {
- base.Text = title;
- image = anImage;
- }
- protected override void OnPaint(PaintEventArgs e) {
- e.Graphics.DrawImageUnscaled (image, 0, 0);
- }
- void IMyForm.Show () {
- this.Size = image.Size;
- this.ShowDialog ();
- this.image.Save("test.net.png");
- }
- }
- protected override IMyForm CreateForm(string title) {
- return new NetForm (title, _bitmap);
- }
- protected override string DetermineCallingFunction() {
- StackFrame sf = new StackFrame (3, true);
- MethodBase mb = sf.GetMethod ();
- string name = mb.DeclaringType.FullName + "." + _ownerClass + "." + mb.Name;
- return name;
- }
- public override string CalculateSHA1() {
- Rectangle r = new Rectangle(0, 0, _bitmap.Width, _bitmap.Height);
-
- BitmapData data = _bitmap.LockBits (r, ImageLockMode.ReadOnly,
- _bitmap.PixelFormat);
- int dataSize = data.Stride * data.Height;
- byte [] bdata = new byte [dataSize];
- Marshal.Copy (data.Scan0, bdata, 0, dataSize);
- _bitmap.UnlockBits (data);
- SHA1 sha1 = new SHA1CryptoServiceProvider ();
- byte [] resdata = sha1.ComputeHash (bdata);
- return Convert.ToBase64String (resdata);
- }
- }
- #endif
- }
|