X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Drawing%2FTest%2FSystem.Drawing%2FTestBitmap.cs;h=435377815f437845d1a1d5bfc809d30894902e0f;hb=90d6059c5475419ddf6e0fc4b49098158010cab0;hp=c1a8d5878099188fb342cceb33cd46529f79a7c0;hpb=d470e0ca31c5aeae86f8f2bb816eb8e2d78f6471;p=mono.git diff --git a/mcs/class/System.Drawing/Test/System.Drawing/TestBitmap.cs b/mcs/class/System.Drawing/Test/System.Drawing/TestBitmap.cs index c1a8d587809..435377815f4 100644 --- a/mcs/class/System.Drawing/Test/System.Drawing/TestBitmap.cs +++ b/mcs/class/System.Drawing/Test/System.Drawing/TestBitmap.cs @@ -1,13 +1,13 @@ // // Bitmap class testing unit // -// Author: -// -// Jordi Mas i Hernàndez (jmas@softcatala.org> -// Jonathan Gilbert +// Authors: +// Jordi Mas i Hernàndez (jmas@softcatala.org> +// Jonathan Gilbert +// Sebastien Pouliot // // (C) 2004 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com) +// Copyright (C) 2004,2006-2007 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -28,20 +28,28 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // + using System; using System.Drawing; using System.Drawing.Imaging; -using NUnit.Framework; using System.IO; -using System.Security.Cryptography; -using System.Text; using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.Runtime.Serialization.Formatters.Soap; +using System.Security.Cryptography; using System.Security.Permissions; +using System.Text; +using System.Xml.Serialization; +using NUnit.Framework; -namespace MonoTests.System.Drawing{ +namespace MonoTests.System.Drawing { [TestFixture] [SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)] +#if TARGET_JVM + [Category ("NotWorking")] +#endif public class TestBitmap { [Test] @@ -74,7 +82,6 @@ namespace MonoTests.System.Drawing{ } [Test] - [Category ("NotWorking")] public void LockBits_32_24_NonIndexedWrite () { using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) { @@ -89,7 +96,6 @@ namespace MonoTests.System.Drawing{ } [Test] - [Category ("NotWorking")] public void LockBits_24_24_NonIndexedWrite () { using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) { @@ -133,7 +139,19 @@ namespace MonoTests.System.Drawing{ { using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) { Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height); +#if NET_2_0 + BitmapData bd = new BitmapData (); + try { + bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, bd); + } + catch (ArgumentException) { + // test to see if there's a leak or not in this case + Assert.AreEqual (IntPtr.Zero, bd.Scan0, "Scan0"); + throw; + } +#else bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); +#endif } } @@ -151,6 +169,41 @@ namespace MonoTests.System.Drawing{ } } + [Test] + public void LockBits_ImageLockMode_Invalid () + { + using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) { + Rectangle r = new Rectangle (4, 4, 4, 4); + BitmapData data = bmp.LockBits (r, (ImageLockMode)0, PixelFormat.Format24bppRgb); + try { + Assert.AreEqual (4, data.Height, "Height"); + Assert.AreEqual (4, data.Width, "Width"); + Assert.IsTrue (data.Stride >= 12, "Stride"); + Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat"); + Assert.IsFalse (IntPtr.Zero.Equals (data.Scan0), "Scan0"); + } + finally { + bmp.UnlockBits (data); + } + } + } + + [Test] + [ExpectedException (typeof (InvalidOperationException))] + public void LockBits_Double () + { + using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) { + Rectangle r = new Rectangle (4, 4, 4, 4); + BitmapData data = bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + try { + bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + } + finally { + bmp.UnlockBits (data); + } + } + } + [Test] [ExpectedException (typeof (ArgumentException))] public void LockBits_Disposed () @@ -163,6 +216,7 @@ namespace MonoTests.System.Drawing{ [Test] [ExpectedException (typeof (ArgumentException))] + [Category ("Valgrind")] // this test is known to leak memory (API design limitation) public void UnlockBits_Disposed () { Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb); @@ -170,6 +224,8 @@ namespace MonoTests.System.Drawing{ BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); bmp.Dispose (); bmp.UnlockBits (data); + // and that results in something like this when executed under Valgrind + // "40,000 bytes in 1 blocks are possibly lost in loss record 88 of 92" } [Test] @@ -183,17 +239,26 @@ namespace MonoTests.System.Drawing{ #if NET_2_0 [Test] [ExpectedException (typeof (ArgumentException))] +#if TARGET_JVM + [Ignore ("Bitmap.LockBits is not implemented")] +#endif public void LockBits_BitmapData_Null () { +#if !TARGET_JVM using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) { Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height); bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, null); } +#endif } [Test] +#if TARGET_JVM + [Ignore ("Bitmap.LockBits is not implemented")] +#endif public void LockBits_32_32_BitmapData () { +#if !TARGET_JVM BitmapData data = new BitmapData (); using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) { Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height); @@ -204,12 +269,16 @@ namespace MonoTests.System.Drawing{ Assert.AreEqual (100, data.Width, "Width"); bmp.UnlockBits (data); } +#endif } [Test] - [Category ("NotWorking")] +#if TARGET_JVM + [Ignore ("Bitmap.LockBits is not implemented")] +#endif public void LockBits_32_24_BitmapData () { +#if !TARGET_JVM BitmapData data = new BitmapData (); using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) { Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height); @@ -220,12 +289,16 @@ namespace MonoTests.System.Drawing{ Assert.AreEqual (100, data.Width, "Width"); bmp.UnlockBits (data); } +#endif } [Test] - [Category ("NotWorking")] +#if TARGET_JVM + [Ignore ("Bitmap.LockBits is not implemented")] +#endif public void LockBits_24_24_BitmapData () { +#if !TARGET_JVM BitmapData data = new BitmapData (); using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) { Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height); @@ -236,11 +309,16 @@ namespace MonoTests.System.Drawing{ Assert.AreEqual (100, data.Width, "Width"); bmp.UnlockBits (data); } +#endif } [Test] +#if TARGET_JVM + [Ignore ("Bitmap.LockBits is not implemented")] +#endif public void LockBits_24_32_BitmapData () { +#if !TARGET_JVM BitmapData data = new BitmapData (); using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) { Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height); @@ -251,9 +329,217 @@ namespace MonoTests.System.Drawing{ Assert.AreEqual (100, data.Width, "Width"); bmp.UnlockBits (data); } +#endif } #endif + [Test] +#if NET_2_0 + [ExpectedException (typeof (InvalidOperationException))] +#else + [ExpectedException (typeof (Exception))] +#endif + public void Format1bppIndexed () + { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) { + Color c = bmp.GetPixel (0, 0); + Assert.AreEqual (-16777216, c.ToArgb (), "Color"); + bmp.SetPixel (0, 0, c); + } + } + + [Test] +#if NET_2_0 + [ExpectedException (typeof (InvalidOperationException))] +#else + [ExpectedException (typeof (Exception))] +#endif + public void Format4bppIndexed () + { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) { + Color c = bmp.GetPixel (0, 0); + Assert.AreEqual (-16777216, c.ToArgb (), "Color"); + bmp.SetPixel (0, 0, c); + } + } + + [Test] +#if NET_2_0 + [ExpectedException (typeof (InvalidOperationException))] +#else + [ExpectedException (typeof (Exception))] +#endif + public void Format8bppIndexed () + { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) { + Color c = bmp.GetPixel (0, 0); + Assert.AreEqual (-16777216, c.ToArgb (), "Color"); + bmp.SetPixel (0, 0, c); + } + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + [Category ("NotWorking")] // libgdiplus doesn't support this format + public void Format16bppGrayScale () + { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format16bppGrayScale)) { + // and MS GDI+ support seems quite limited too + bmp.GetPixel (0, 0); + } + } + + private void FormatTest (PixelFormat format) + { + bool alpha = Image.IsAlphaPixelFormat (format); + int size = Image.GetPixelFormatSize (format) / 8 * 2; + using (Bitmap bmp = new Bitmap (2, 1, format)) { + Color a = Color.FromArgb (128, 64, 32, 16); + Color b = Color.FromArgb (192, 96, 48, 24); + bmp.SetPixel (0, 0, a); + bmp.SetPixel (1, 0, b); + Color c = bmp.GetPixel (0, 0); + Color d = bmp.GetPixel (1, 0); + if (size == 4) { + Assert.AreEqual (255, c.A, "0,0-16bpp-A"); + Assert.AreEqual (66, c.R, "0,0-16bpp-R"); + if (format == PixelFormat.Format16bppRgb565) { + Assert.AreEqual (32, c.G, "0,0-16bpp-G"); + } else { + Assert.AreEqual (33, c.G, "0,0-16bpp-G"); + } + Assert.AreEqual (16, c.B, "0,0-16bpp-B"); + + Assert.AreEqual (255, d.A, "1,0-16bpp-A"); + Assert.AreEqual (99, d.R, "1,0-16bpp-R"); + if (format == PixelFormat.Format16bppRgb565) { + Assert.AreEqual (48, d.G, "1,0-16bpp-G"); + } else { + Assert.AreEqual (49, d.G, "1,0-16bpp-G"); + } + Assert.AreEqual (24, d.B, "1,0-16bpp-B"); + } else if (alpha) { + if (format == PixelFormat.Format32bppPArgb) { + Assert.AreEqual (a.A, c.A, "0,0-alpha-A"); + // note sure why the -1 + Assert.AreEqual (a.R - 1, c.R, "0,0-alpha-premultiplied-R"); + Assert.AreEqual (a.G - 1, c.G, "0,0-alpha-premultiplied-G"); + Assert.AreEqual (a.B - 1, c.B, "0,0-alpha-premultiplied-B"); + + Assert.AreEqual (b.A, d.A, "1,0-alpha-A"); + // note sure why the -1 + Assert.AreEqual (b.R - 1, d.R, "1,0-alpha-premultiplied-R"); + Assert.AreEqual (b.G - 1, d.G, "1,0-alpha-premultiplied-G"); + Assert.AreEqual (b.B - 1, d.B, "1,0-alpha-premultiplied-B"); + } else { + Assert.AreEqual (a, c, "0,0-alpha"); + Assert.AreEqual (b, d, "1,0-alpha"); + } + } else { + Assert.AreEqual (Color.FromArgb (255, 64, 32, 16), c, "0,0-non-alpha"); + Assert.AreEqual (Color.FromArgb (255, 96, 48, 24), d, "1,0-non-alpha"); + } + BitmapData bd = bmp.LockBits (new Rectangle (0, 0, 2, 1), ImageLockMode.ReadOnly, format); + try { + byte[] data = new byte[size]; + Marshal.Copy (bd.Scan0, data, 0, size); + if (format == PixelFormat.Format32bppPArgb) { + Assert.AreEqual (Math.Ceiling ((float)c.B * c.A / 255), data[0], "0.alpha-premultiplied-B"); + Assert.AreEqual (Math.Ceiling ((float)c.G * c.A / 255), data[1], "0.alpha-premultiplied-R"); + Assert.AreEqual (Math.Ceiling ((float)c.R * c.A / 255), data[2], "0.alpha-premultiplied-G"); + Assert.AreEqual (c.A, data[3], "0.alpha-A"); + Assert.AreEqual (Math.Ceiling ((float)d.B * d.A / 255), data[4], "1.alpha-premultiplied-B"); + Assert.AreEqual (Math.Ceiling ((float)d.G * d.A / 255), data[5], "1.alpha-premultiplied-R"); + Assert.AreEqual (Math.Ceiling ((float)d.R * d.A / 255), data[6], "1.alpha-premultiplied-G"); + Assert.AreEqual (d.A, data[7], "1.alpha-A"); + } else if (size == 4) { + int n = 0; + switch (format) { + case PixelFormat.Format16bppRgb565: + Assert.AreEqual (2, data[n++], "0"); + Assert.AreEqual (65, data[n++], "1"); + Assert.AreEqual (131, data[n++], "2"); + Assert.AreEqual (97, data[n++], "3"); + break; + case PixelFormat.Format16bppArgb1555: + Assert.AreEqual (130, data[n++], "0"); + Assert.AreEqual (160, data[n++], "1"); + Assert.AreEqual (195, data[n++], "2"); + Assert.AreEqual (176, data[n++], "3"); + break; + case PixelFormat.Format16bppRgb555: + Assert.AreEqual (130, data[n++], "0"); + Assert.AreEqual (32, data[n++], "1"); + Assert.AreEqual (195, data[n++], "2"); + Assert.AreEqual (48, data[n++], "3"); + break; + } + } else { + int n = 0; + Assert.AreEqual (c.B, data[n++], "0.B"); + Assert.AreEqual (c.G, data[n++], "0.R"); + Assert.AreEqual (c.R, data[n++], "0.G"); + if (size % 4 == 0) + Assert.AreEqual (c.A, data[n++], "0.A"); + Assert.AreEqual (d.B, data[n++], "1.B"); + Assert.AreEqual (d.G, data[n++], "1.R"); + Assert.AreEqual (d.R, data[n++], "1.G"); + if (size % 4 == 0) + Assert.AreEqual (d.A, data[n++], "1.A"); + } + } + finally { + bmp.UnlockBits (bd); + } + } + } + + [Test] + [Category ("NotWorking")] // libgdiplus doesn't support this format + public void Format16bppArgb1555 () + { + FormatTest (PixelFormat.Format16bppArgb1555); + } + + [Test] + [Category ("NotWorking")] // GetPixel is a few bits off + public void Format16bppRgb555 () + { + FormatTest (PixelFormat.Format16bppRgb555); + } + + [Test] + [Category ("NotWorking")] // GetPixel is a few bits off + public void Format16bppRgb565 () + { + FormatTest (PixelFormat.Format16bppRgb565); + } + + [Test] + public void Format32bppArgb () + { + FormatTest (PixelFormat.Format32bppArgb); + } + + [Test] + [Category ("NotWorking")] // I'm not sure we're handling this format anywhere (Cairo itself use it) + public void Format32bppPArgb () + { + FormatTest (PixelFormat.Format32bppPArgb); + } + + [Test] + public void Format32bppRgb () + { + FormatTest (PixelFormat.Format32bppRgb); + } + + [Test] + public void Format24bppRgb () + { + FormatTest (PixelFormat.Format24bppRgb); + } + /* Get the output directory depending on the runtime and location*/ public static string getOutSubDir() { @@ -473,7 +759,7 @@ namespace MonoTests.System.Drawing{ { if ((Environment.OSVersion.Platform != (PlatformID)4) && (Environment.OSVersion.Platform != (PlatformID)128)) - Assert.Ignore("This fails with Microsoft's GDIPLUS.DLL due to off-by-1 errors in their GdipBitmapRotateFlip function."); + Assert.Ignore("This does not work with Microsoft's GDIPLUS.DLL due to off-by-1 errors in their GdipBitmapRotateFlip function."); string[] files = { getInFile ("bitmaps/1bit.png"), @@ -525,116 +811,189 @@ namespace MonoTests.System.Drawing{ "B6B6245796C836923ABAABDF368B29", // 4-bit Rotate90FlipY md5s.ToString ()); } - - public void LockBmp (PixelFormat fmt, PixelFormat fmtlock, string output, - int lwidth , int lheight, ref string hash1, ref string hash2) - { - int width = 100, height = 100, bbps, cur, pos; - Bitmap bmp = new Bitmap (width, height, fmt); - Graphics gr = Graphics.FromImage (bmp); - byte[] hash; - Color clr; - byte[] btv = new byte[1]; - int y, x, len = width * height * 4, index = 0; + + private Bitmap CreateBitmap (int width, int height, PixelFormat fmt) + { + Bitmap bmp = new Bitmap (width, height, fmt); + using (Graphics gr = Graphics.FromImage (bmp)) { + Color c = Color.FromArgb (255, 100, 200, 250); + for (int x = 1; x < 80; x++) { + bmp.SetPixel (x, 1, c); + bmp.SetPixel (x, 2, c); + bmp.SetPixel (x, 78, c); + bmp.SetPixel (x, 79, c); + } + for (int y = 3; y < 78; y++) { + bmp.SetPixel (1, y, c); + bmp.SetPixel (2, y, c); + bmp.SetPixel (78, y, c); + bmp.SetPixel (79, y, c); + } + } + return bmp; + } + + private byte[] HashPixels (Bitmap bmp) + { + int len = bmp.Width * bmp.Height * 4; + int index = 0; byte[] pixels = new byte [len]; - hash1 = hash2 =""; - - bbps = Image.GetPixelFormatSize (fmt); - - Pen p = new Pen (Color.FromArgb (255, 100, 200, 250), 2); - gr.DrawRectangle(p, 1.0F, 1.0F, 80.0F, 80.0F); - - BitmapData bd = bmp.LockBits (new Rectangle (0, 0, lwidth, lheight), ImageLockMode.ReadOnly, fmtlock); - - pos = bd.Scan0.ToInt32(); - for (y = 0; y < bd.Height; y++) { - for (x = 0; x < bd.Width; x++) { - - /* Read the pixels*/ - for (int bt =0; bt < bbps/8; bt++, index++) { - cur = pos; - cur+= y * bd.Stride; - cur+= x * bbps/8; - cur+= bt; - Marshal.Copy ((IntPtr)cur, btv, 0, 1); - pixels[index] = btv[0]; - - /* Make change of all the colours = 250 to 10*/ - if (btv[0] == 250) { - btv[0] = 10; - Marshal.Copy (btv, 0, (IntPtr)cur, 1); + + for (int y = 0; y < bmp.Height; y++) { + for (int x = 0; x < bmp.Width; x++) { + Color clr = bmp.GetPixel (x, y); + pixels[index++] = clr.R; + pixels[index++] = clr.G; + pixels[index++] = clr.B; + } + } + return MD5.Create ().ComputeHash (pixels); + } + + private byte[] HashLock (Bitmap bmp, int width, int height, PixelFormat fmt, ImageLockMode mode) + { + int len = bmp.Width * bmp.Height * 4; + byte[] pixels = new byte[len]; + BitmapData bd = bmp.LockBits (new Rectangle (0, 0, width, height), mode, fmt); + try { + int index = 0; + int bbps = Image.GetPixelFormatSize (fmt); + long pos = bd.Scan0.ToInt64 (); + byte[] btv = new byte[1]; + for (int y = 0; y < bd.Height; y++) { + for (int x = 0; x < bd.Width; x++) { + + /* Read the pixels*/ + for (int bt = 0; bt < bbps / 8; bt++, index++) { + long cur = pos; + cur += y * bd.Stride; + cur += x * bbps / 8; + cur += bt; + Marshal.Copy ((IntPtr) cur, btv, 0, 1); + pixels[index] = btv[0]; + + /* Make change of all the colours = 250 to 10*/ + if (btv[0] == 250) { + btv[0] = 10; + Marshal.Copy (btv, 0, (IntPtr) cur, 1); + } } } } - } - - for (int i = index; i < len; i++) - pixels[index] = 0; - - hash = new MD5CryptoServiceProvider().ComputeHash (pixels); - bmp.UnlockBits (bd); - - hash1 = ByteArrayToString (hash); - - /* MD5 of the changed bitmap*/ - for (y = 0, index = 0; y < height; y++) { - for (x = 0; x < width; x++) { - clr = bmp.GetPixel (x,y); - pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++] = clr.B; - } + + for (int i = index; i < len; i++) + pixels[index] = 0; } - - hash = new MD5CryptoServiceProvider().ComputeHash (pixels); - hash2 = ByteArrayToString (hash); - - /*bmp.Save (output, ImageFormat.Bmp);*/ + finally { + bmp.UnlockBits (bd); + } + return MD5.Create ().ComputeHash (pixels); } + /* Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns firsts, changes them, and then using GetPixel does another check of the changes. The results match the .Net framework */ + private static byte[] DefaultBitmapHash = new byte[] { 0xD8, 0xD3, 0x68, 0x9C, 0x86, 0x7F, 0xB6, 0xA0, 0x76, 0xD6, 0x00, 0xEF, 0xFF, 0xE5, 0x8E, 0x1B }; + private static byte[] FinalWholeBitmapHash = new byte[] { 0x5F, 0x52, 0x98, 0x37, 0xE3, 0x94, 0xE1, 0xA6, 0x06, 0x6C, 0x5B, 0xF1, 0xA9, 0xC2, 0xA9, 0x43 }; + [Test] - [Category ("NotWorking")] - public void LockBitmap () - { - string hash = ""; - string hashchg = ""; - - /* Locks the whole bitmap*/ - LockBmp (PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, "output32bppArgb.bmp", 100, 100, ref hash, ref hashchg); - Assert.AreEqual ("AF5BFD4E98D6708FF4C9982CC9C68F", hash); - Assert.AreEqual ("BBEE27DC85563CB58EE11E8951230F", hashchg); - - LockBmp (PixelFormat.Format32bppPArgb, PixelFormat.Format32bppPArgb, "output32bppPArgb.bmp", 100, 100, ref hash, ref hashchg); - Assert.AreEqual ("AF5BFD4E98D6708FF4C9982CC9C68F", hash); - Assert.AreEqual ("BBEE27DC85563CB58EE11E8951230F", hashchg); - - LockBmp (PixelFormat.Format32bppRgb, PixelFormat.Format32bppRgb, "output32bppRgb.bmp", 100, 100, ref hash, ref hashchg); - Assert.AreEqual ("AF5BFD4E98D6708FF4C9982CC9C68F", hash); - Assert.AreEqual ("BBEE27DC85563CB58EE11E8951230F", hashchg); - - LockBmp (PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, "output24bppRgb.bmp", 100, 100, ref hash, ref hashchg); - Assert.AreEqual ("A8A071D0B3A3743905B4E193A62769", hash); - Assert.AreEqual ("EEE846FA8F892339C64082DFF775CF", hashchg); - - /* Locks a portion of the bitmap*/ - LockBmp (PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, "output32bppArgb.bmp", 50, 50, ref hash, ref hashchg); - Assert.AreEqual ("C361FBFD82A4F3C278605AE9EC5385", hash); - Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg); - - LockBmp (PixelFormat.Format32bppPArgb, PixelFormat.Format32bppPArgb, "output32bppPArgb.bmp", 50, 50, ref hash, ref hashchg); - Assert.AreEqual ("C361FBFD82A4F3C278605AE9EC5385", hash); - Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg); - - LockBmp (PixelFormat.Format32bppRgb, PixelFormat.Format32bppRgb, "output32bppRgb.bmp", 50, 50, ref hash, ref hashchg); - Assert.AreEqual ("C361FBFD82A4F3C278605AE9EC5385", hash); - Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg); - - LockBmp (PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, "output24bppRgb.bmp", 50, 50, ref hash, ref hashchg); - Assert.AreEqual ("FFE86628478591D1A1EB30E894C34F", hash); - Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg); - + public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Whole () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C }; + byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Full-Format32bppArgb"); + Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final"); + } + } + + [Test] + public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Whole () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C }; + byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Full-Format32bppPArgb"); + Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final"); + } + } + + [Test] + public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Whole () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0xC0, 0x28, 0xB5, 0x2E, 0x86, 0x90, 0x6F, 0x37, 0x09, 0x5F, 0x49, 0xA4, 0x91, 0xDA, 0xEE, 0xB9 }; + byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Full-Format32bppRgb"); + Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final"); + } + } + + [Test] + public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Whole () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0xA7, 0xB2, 0x50, 0x04, 0x11, 0x12, 0x64, 0x68, 0x6B, 0x7D, 0x2F, 0x6E, 0x69, 0x24, 0xCB, 0x14 }; + byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Full-Format24bppRgb"); + Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final"); + } + } + + private static byte[] FinalPartialBitmapHash = new byte[] { 0xED, 0xD8, 0xDC, 0x9B, 0x44, 0x00, 0x22, 0x9B, 0x07, 0x06, 0x4A, 0x21, 0x70, 0xA7, 0x31, 0x1D }; + + [Test] + public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Partial () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC }; + byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Partial-Format32bppArgb"); + Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final"); + } + } + + [Test] + public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Partial () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC }; + byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Partial-Format32bppPArgb"); + Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final"); + } + } + + [Test] + public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Partial () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0x72, 0x33, 0x09, 0x67, 0x53, 0x65, 0x38, 0xF9, 0xE4, 0x58, 0xE1, 0x0A, 0xAA, 0x6A, 0xCC, 0xB8 }; + byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Partial-Format32bppRgb"); + Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final"); + } + } + + [Test] + public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Partial () + { + using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) { + Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial"); + byte[] expected = { 0x4D, 0x39, 0x21, 0x88, 0xC2, 0x17, 0x14, 0x5F, 0x89, 0x9E, 0x02, 0x75, 0xF3, 0x64, 0xD8, 0xF0 }; + byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite); + Assert.AreEqual (expected, actual, "Partial-Format24bppRgb"); + Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final"); + } } /* @@ -642,7 +1001,7 @@ namespace MonoTests.System.Drawing{ of bitmap data in the directions indicated by the ImageLockMode. */ [Test] - public void LockUnlockBitmap() + public void LockUnlockBitmap () { BitmapData data; int pixel_value; @@ -651,134 +1010,874 @@ namespace MonoTests.System.Drawing{ Color red = Color.FromArgb (Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B); Color blue = Color.FromArgb (Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B); - using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppRgb)) - { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppRgb)) { bmp.SetPixel (0, 0, red); pixel_colour = bmp.GetPixel (0, 0); Assert.AreEqual (red, pixel_colour, "Set/Get-Red"); data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); - - // Marshal follows CPU endianess - if (BitConverter.IsLittleEndian) { - pixel_value = Marshal.ReadInt32 (data.Scan0); - } else { + try { pixel_value = Marshal.ReadByte (data.Scan0, 0); pixel_value |= Marshal.ReadByte (data.Scan0, 1) << 8; pixel_value |= Marshal.ReadByte (data.Scan0, 2) << 16; pixel_value |= Marshal.ReadByte (data.Scan0, 3) << 24; + + pixel_colour = Color.FromArgb (pixel_value); + // Disregard alpha information in the test + pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Original"); + + // write blue but we're locked in read-only... + Marshal.WriteByte (data.Scan0, 0, blue.B); + Marshal.WriteByte (data.Scan0, 1, blue.G); + Marshal.WriteByte (data.Scan0, 2, blue.R); + Marshal.WriteByte (data.Scan0, 3, blue.A); + } + finally { + bmp.UnlockBits (data); + pixel_colour = bmp.GetPixel (0, 0); + // Disregard alpha information in the test + pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + // ...so we still read red after unlocking + Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Unlocked"); } - pixel_colour = Color.FromArgb (pixel_value); - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); + try { + // write blue + Marshal.WriteByte (data.Scan0, 0, blue.B); + Marshal.WriteByte (data.Scan0, 1, blue.G); + Marshal.WriteByte (data.Scan0, 2, blue.R); + Marshal.WriteByte (data.Scan0, 3, blue.A); + } + finally { + bmp.UnlockBits (data); + pixel_colour = bmp.GetPixel (0, 0); + // Disregard alpha information in the test + pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + // read blue + Assert.AreEqual (blue, pixel_colour, "32RGB/32ARGB-ReadWrite-Blue-Unlock"); + } + } - Assert.AreEqual (red, pixel_colour, "Red-FromLockedBitmap"); + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppArgb)) { + bmp.SetPixel (0, 0, red); - Marshal.WriteInt32 (data.Scan0, blue.ToArgb ()); + data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + try { + byte b = Marshal.ReadByte (data.Scan0, 0); + byte g = Marshal.ReadByte (data.Scan0, 1); + byte r = Marshal.ReadByte (data.Scan0, 2); + pixel_colour = Color.FromArgb (red.A, r, g, b); + Assert.AreEqual (red, pixel_colour, "32ARGB/24RGB-ReadOnly-Red-Original"); + // write blue but we're locked in read-only... + Marshal.WriteByte (data.Scan0, 0, blue.B); + Marshal.WriteByte (data.Scan0, 1, blue.G); + Marshal.WriteByte (data.Scan0, 2, blue.R); + } + finally { + bmp.UnlockBits (data); + // ...so we still read red after unlocking + Assert.AreEqual (red, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadOnly-Red-Unlock"); + } + data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); + try { + // write blue + Marshal.WriteByte (data.Scan0, 0, blue.B); + Marshal.WriteByte (data.Scan0, 1, blue.G); + Marshal.WriteByte (data.Scan0, 2, blue.R); + } + finally { + bmp.UnlockBits (data); + // read blue + Assert.AreEqual (blue, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadWrite-Blue-Unlock"); + } + } + } +#endif + [Test] + public void DefaultFormat1 () + { + using (Bitmap bmp = new Bitmap (20, 20)) { + Assert.AreEqual (ImageFormat.MemoryBmp, bmp.RawFormat); + } + } + + [Test] + public void DefaultFormat2 () + { + string filename = Path.GetTempFileName (); + using (Bitmap bmp = new Bitmap (20, 20)) { + bmp.Save (filename); + } + + using (Bitmap other = new Bitmap (filename)) { + Assert.AreEqual (ImageFormat.Png, other.RawFormat); + } + File.Delete (filename); + } + + [Test] + public void BmpDataStride1 () + { + Bitmap bmp = new Bitmap (184, 184, PixelFormat.Format1bppIndexed); + BitmapData data = bmp.LockBits (new Rectangle (0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed); + try { + Assert.AreEqual (24, data.Stride); + } finally { bmp.UnlockBits (data); + bmp.Dispose (); + } + } - pixel_colour = bmp.GetPixel (0, 0); + private Stream Serialize (object o) + { + MemoryStream ms = new MemoryStream (); + IFormatter formatter = new BinaryFormatter (); + formatter.Serialize (ms, o); + ms.Position = 0; + return ms; + } - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + private object Deserialize (Stream s) + { + return new BinaryFormatter ().Deserialize (s); + } - Assert.AreEqual (red, pixel_colour); + [Test] + public void Serialize_Icon () + { + // this cause a problem with resgen, see http://bugzilla.ximian.com/show_bug.cgi?id=80565 + string filename = getInFile ("bitmaps/16x16x16.ico"); + using (Bitmap icon = new Bitmap (filename)) { + using (Stream s = Serialize (icon)) { + using (Bitmap copy = (Bitmap)Deserialize (s)) { + Assert.AreEqual (icon.Height, copy.Height, "Height"); + Assert.AreEqual (icon.Width, copy.Width, "Width"); + Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat"); + Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon"); + Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png"); + } + } + } + } - data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); + private Stream SoapSerialize (object o) + { + MemoryStream ms = new MemoryStream (); + IFormatter formatter = new SoapFormatter (); + formatter.Serialize (ms, o); + ms.Position = 0; + return ms; + } - Marshal.WriteInt32 (data.Scan0, blue.ToArgb ()); + private object SoapDeserialize (Stream s) + { + return new SoapFormatter ().Deserialize (s); + } - bmp.UnlockBits (data); + [Test] + public void SoapSerialize_Icon () + { + string filename = getInFile ("bitmaps/16x16x16.ico"); + using (Bitmap icon = new Bitmap (filename)) { + using (Stream s = SoapSerialize (icon)) { + using (Bitmap copy = (Bitmap) SoapDeserialize (s)) { + Assert.AreEqual (icon.Height, copy.Height, "Height"); + Assert.AreEqual (icon.Width, copy.Width, "Width"); + Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat"); + Assert.AreEqual (16, icon.Palette.Entries.Length, "icon Palette"); + Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon"); + Assert.AreEqual (0, copy.Palette.Entries.Length, "copy Palette"); + Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png"); + } + } + } + } - pixel_colour = bmp.GetPixel (0, 0); + [Test] + public void SoapSerialize_Bitmap8 () + { + string filename = getInFile ("bitmaps/almogaver8bits.bmp"); + using (Bitmap bmp = new Bitmap (filename)) { + using (Stream s = SoapSerialize (bmp)) { + using (Bitmap copy = (Bitmap) SoapDeserialize (s)) { + Assert.AreEqual (bmp.Height, copy.Height, "Height"); + Assert.AreEqual (bmp.Width, copy.Width, "Width"); + Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat"); + Assert.AreEqual (256, copy.Palette.Entries.Length, "Palette"); + Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat"); + } + } + } + } - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + [Test] + public void SoapSerialize_Bitmap24 () + { + string filename = getInFile ("bitmaps/almogaver24bits.bmp"); + using (Bitmap bmp = new Bitmap (filename)) { + using (Stream s = SoapSerialize (bmp)) { + using (Bitmap copy = (Bitmap) SoapDeserialize (s)) { + Assert.AreEqual (bmp.Height, copy.Height, "Height"); + Assert.AreEqual (bmp.Width, copy.Width, "Width"); + Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat"); + Assert.AreEqual (bmp.Palette.Entries.Length, copy.Palette.Entries.Length, "Palette"); + Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat"); + } + } + } + } - Assert.AreEqual (blue, pixel_colour); + [Test] +#if NET_2_0 + [Category ("NotWorking")] // http://bugzilla.ximian.com/show_bug.cgi?id=80558 +#else + [ExpectedException (typeof (InvalidOperationException))] +#endif + public void XmlSerialize () + { + new XmlSerializer (typeof (Bitmap)); + } + + static int[] palette1 = { + -16777216, + -1, + }; + + [Test] + public void Format1bppIndexed_Palette () + { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) { + ColorPalette pal = bmp.Palette; + Assert.AreEqual (2, pal.Entries.Length, "Length"); + for (int i = 0; i < pal.Entries.Length; i++) { + Assert.AreEqual (palette1[i], pal.Entries[i].ToArgb (), i.ToString ()); + } + Assert.AreEqual (2, pal.Flags, "Flags"); } + } - using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb)) - { - bmp.SetPixel (0, 0, red); + static int[] palette16 = { + -16777216, + -8388608, + -16744448, + -8355840, + -16777088, + -8388480, + -16744320, + -8355712, + -4144960, + -65536, + -16711936, + -256, + -16776961, + -65281, + -16711681, + -1, + }; - data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); + [Test] + public void Format4bppIndexed_Palette () + { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) { + ColorPalette pal = bmp.Palette; + Assert.AreEqual (16, pal.Entries.Length, "Length"); + for (int i = 0; i < pal.Entries.Length; i++) { + Assert.AreEqual (palette16 [i], pal.Entries[i].ToArgb (), i.ToString ()); + } + Assert.AreEqual (0, pal.Flags, "Flags"); + } + } - int r, g, b; + static int[] palette256 = { + -16777216, + -8388608, + -16744448, + -8355840, + -16777088, + -8388480, + -16744320, + -8355712, + -4144960, + -65536, + -16711936, + -256, + -16776961, + -65281, + -16711681, + -1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -16777216, + -16777165, + -16777114, + -16777063, + -16777012, + -16776961, + -16764160, + -16764109, + -16764058, + -16764007, + -16763956, + -16763905, + -16751104, + -16751053, + -16751002, + -16750951, + -16750900, + -16750849, + -16738048, + -16737997, + -16737946, + -16737895, + -16737844, + -16737793, + -16724992, + -16724941, + -16724890, + -16724839, + -16724788, + -16724737, + -16711936, + -16711885, + -16711834, + -16711783, + -16711732, + -16711681, + -13434880, + -13434829, + -13434778, + -13434727, + -13434676, + -13434625, + -13421824, + -13421773, + -13421722, + -13421671, + -13421620, + -13421569, + -13408768, + -13408717, + -13408666, + -13408615, + -13408564, + -13408513, + -13395712, + -13395661, + -13395610, + -13395559, + -13395508, + -13395457, + -13382656, + -13382605, + -13382554, + -13382503, + -13382452, + -13382401, + -13369600, + -13369549, + -13369498, + -13369447, + -13369396, + -13369345, + -10092544, + -10092493, + -10092442, + -10092391, + -10092340, + -10092289, + -10079488, + -10079437, + -10079386, + -10079335, + -10079284, + -10079233, + -10066432, + -10066381, + -10066330, + -10066279, + -10066228, + -10066177, + -10053376, + -10053325, + -10053274, + -10053223, + -10053172, + -10053121, + -10040320, + -10040269, + -10040218, + -10040167, + -10040116, + -10040065, + -10027264, + -10027213, + -10027162, + -10027111, + -10027060, + -10027009, + -6750208, + -6750157, + -6750106, + -6750055, + -6750004, + -6749953, + -6737152, + -6737101, + -6737050, + -6736999, + -6736948, + -6736897, + -6724096, + -6724045, + -6723994, + -6723943, + -6723892, + -6723841, + -6711040, + -6710989, + -6710938, + -6710887, + -6710836, + -6710785, + -6697984, + -6697933, + -6697882, + -6697831, + -6697780, + -6697729, + -6684928, + -6684877, + -6684826, + -6684775, + -6684724, + -6684673, + -3407872, + -3407821, + -3407770, + -3407719, + -3407668, + -3407617, + -3394816, + -3394765, + -3394714, + -3394663, + -3394612, + -3394561, + -3381760, + -3381709, + -3381658, + -3381607, + -3381556, + -3381505, + -3368704, + -3368653, + -3368602, + -3368551, + -3368500, + -3368449, + -3355648, + -3355597, + -3355546, + -3355495, + -3355444, + -3355393, + -3342592, + -3342541, + -3342490, + -3342439, + -3342388, + -3342337, + -65536, + -65485, + -65434, + -65383, + -65332, + -65281, + -52480, + -52429, + -52378, + -52327, + -52276, + -52225, + -39424, + -39373, + -39322, + -39271, + -39220, + -39169, + -26368, + -26317, + -26266, + -26215, + -26164, + -26113, + -13312, + -13261, + -13210, + -13159, + -13108, + -13057, + -256, + -205, + -154, + -103, + -52, + -1, + }; - b = Marshal.ReadByte (data.Scan0, 0); - g = Marshal.ReadByte (data.Scan0, 1); - r = Marshal.ReadByte (data.Scan0, 2); - pixel_colour = Color.FromArgb (red.A, r, g, b); + [Test] + public void Format8bppIndexed_Palette () + { + using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) { + ColorPalette pal = bmp.Palette; + Assert.AreEqual (256, pal.Entries.Length, "Length"); + for (int i = 0; i < pal.Entries.Length; i++) { + Assert.AreEqual (palette256[i], pal.Entries[i].ToArgb (), i.ToString ()); + } + Assert.AreEqual (4, pal.Flags, "Flags"); + } + } - Assert.AreEqual (red, pixel_colour); + [Test] +#if !NET_2_0 + [ExpectedException (typeof (InvalidOperationException))] +#endif + public void XmlSerialization () + { + new XmlSerializer (typeof (Bitmap)); + } - Marshal.WriteByte (data.Scan0, 0, blue.B); - Marshal.WriteByte (data.Scan0, 1, blue.G); - Marshal.WriteByte (data.Scan0, 2, blue.R); + [Test] + [ExpectedException (typeof (NullReferenceException))] + public void BitmapImageCtor () + { + new Bitmap ((Image) null); + } - bmp.UnlockBits (data); + [Test] + [ExpectedException (typeof (ArgumentException))] + public void BitmapImageSizeCtor () + { + new Bitmap ((Image) null, Size.Empty); + } - pixel_colour = bmp.GetPixel (0, 0); + [Test] + [ExpectedException (typeof (ArgumentException))] + public void BitmapImageIntIntCtor () + { + new Bitmap ((Image) null, Int32.MinValue, Int32.MaxValue); + } - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + [Test] + [ExpectedException (typeof (ArgumentException))] + public void BitmapIntIntCtor () + { + new Bitmap (Int32.MinValue, Int32.MaxValue); + } - Assert.AreEqual (red, bmp.GetPixel (0, 0)); + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void BitmapIntIntGraphicCtor () + { + new Bitmap (1, 1, null); + } - data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); + [Test] + [ExpectedException (typeof (ArgumentException))] + public void BitmapIntIntPixelFormatCtor () + { + new Bitmap (Int32.MinValue, Int32.MaxValue, PixelFormat.Format1bppIndexed); + } - Marshal.WriteByte (data.Scan0, 0, blue.B); - Marshal.WriteByte (data.Scan0, 1, blue.G); - Marshal.WriteByte (data.Scan0, 2, blue.R); + [Test] + [ExpectedException (typeof (ArgumentException))] + public void BitmapStreamCtor () + { + new Bitmap ((Stream) null); + } - bmp.UnlockBits(data); + [Test] + [ExpectedException (typeof (ArgumentException))] + public void BitmapStreamBoolCtor () + { + new Bitmap ((Stream) null, true); + } - pixel_colour = bmp.GetPixel (0, 0); + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void BitmapStringCtor () + { + new Bitmap ((string) null); + } - // Disregard alpha information in the test - pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B); + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void BitmapStringBoolCtor () + { + new Bitmap ((string) null, false); + } - Assert.AreEqual (blue, bmp.GetPixel (0, 0)); + [Test] + [ExpectedException (typeof (NullReferenceException))] + public void BitmapTypeStringCtor1 () + { + new Bitmap ((Type) null, "mono"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void BitmapTypeStringCtor2 () + { + new Bitmap (typeof (Bitmap), null); + } + + private void SetResolution (float x, float y) + { + using (Bitmap bmp = new Bitmap (1, 1)) { + bmp.SetResolution (x, y); } } -#endif + [Test] - public void DefaultFormat1 () + [ExpectedException (typeof (ArgumentException))] + public void SetResolution_Zero () { - using (Bitmap bmp = new Bitmap (20, 20)) { - Assert.AreEqual (ImageFormat.MemoryBmp, bmp.RawFormat); + SetResolution (0.0f, 0.0f); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void SetResolution_Negative_X () + { + SetResolution (-1.0f, 1.0f); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void SetResolution_Negative_Y () + { + SetResolution (1.0f, -1.0f); + } + + [Test] + public void SetResolution_MaxValue () + { + SetResolution (Single.MaxValue, Single.MaxValue); + } + + [Test] + public void SetResolution_PositiveInfinity () + { + SetResolution (Single.PositiveInfinity, Single.PositiveInfinity); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void SetResolution_NaN () + { + SetResolution (Single.NaN, Single.NaN); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void SetResolution_NegativeInfinity () + { + SetResolution (Single.NegativeInfinity, Single.NegativeInfinity); + } + } + + [TestFixture] +#if TARGET_JVM + [Ignore ("Unsafe code is not supported")] +#endif + public class BitmapFullTrustTest { +#if !TARGET_JVM + [Test] + public void BitmapIntIntIntPixelFormatIntPtrCtor () + { + new Bitmap (1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero); + } + + // BitmapFromHicon## is *almost* the same as IconTest.Icon##ToBitmap except + // for the Flags property + + private void HiconTest (string msg, Bitmap b, int size) + { + Assert.AreEqual (PixelFormat.Format32bppArgb, b.PixelFormat, msg + ".PixelFormat"); + // unlike the GDI+ icon decoder the palette isn't kept + Assert.AreEqual (0, b.Palette.Entries.Length, msg + ".Palette"); + Assert.AreEqual (size, b.Height, msg + ".Height"); + Assert.AreEqual (size, b.Width, msg + ".Width"); + Assert.IsTrue (b.RawFormat.Equals (ImageFormat.MemoryBmp), msg + ".RawFormat"); + Assert.AreEqual (335888, b.Flags, msg + ".Flags"); + } + + [Test] + public void Hicon16 () + { + IntPtr hicon; + int size; + using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/16x16x16.ico"))) { + size = icon.Width; + using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) { + HiconTest ("Icon.Handle/FromHicon", bitmap, size); + hicon = bitmap.GetHicon (); + } + } + using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) { + // hicon survives bitmap and icon disposal + HiconTest ("GetHicon/FromHicon", bitmap2, size); } } [Test] - public void DefaultFormat2 () + public void Hicon32 () { - string filename = Path.GetTempFileName (); - using (Bitmap bmp = new Bitmap (20, 20)) { - bmp.Save (filename); + IntPtr hicon; + int size; + using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/32x32x16.ico"))) { + size = icon.Width; + using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) { + HiconTest ("Icon.Handle/FromHicon", bitmap, size); + hicon = bitmap.GetHicon (); + } } + using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) { + // hicon survives bitmap and icon disposal + HiconTest ("GetHicon/FromHicon", bitmap2, size); + } + } - using (Bitmap other = new Bitmap (filename)) { - Assert.AreEqual (ImageFormat.Png, other.RawFormat); + [Test] + [ExpectedException (typeof (ArgumentException))] + [Category ("NotWorking")] // libgdiplus has lost track of the original 1bpp state + public void Hicon48 () + { + using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/48x48x1.ico"))) { + // looks like 1bbp icons aren't welcome as bitmaps ;-) + Bitmap.FromHicon (icon.Handle); } - File.Delete (filename); } [Test] - public void BmpDataStride1 () + public void Hicon64 () { - Bitmap bmp = new Bitmap (184, 184, PixelFormat.Format1bppIndexed); - BitmapData data = bmp.LockBits (new Rectangle (0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed); - try { - Assert.AreEqual (24, data.Stride); - } finally { - bmp.UnlockBits (data); - bmp.Dispose (); + IntPtr hicon; + int size; + using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/64x64x256.ico"))) { + size = icon.Width; + using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) { + HiconTest ("Icon.Handle/FromHicon", bitmap, size); + hicon = bitmap.GetHicon (); + } + } + using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) { + // hicon survives bitmap and icon disposal + HiconTest ("GetHicon/FromHicon", bitmap2, size); + } + } + + [Test] + public void Hicon96 () + { + IntPtr hicon; + int size; + using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/96x96x256.ico"))) { + size = icon.Width; + using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) { + HiconTest ("Icon.Handle/FromHicon", bitmap, size); + hicon = bitmap.GetHicon (); + } + } + using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) { + // hicon survives bitmap and icon disposal + HiconTest ("GetHicon/FromHicon", bitmap2, size); } } + + [Test] + public void HBitmap () + { + IntPtr hbitmap; + string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp"); + using (Bitmap bitmap = new Bitmap (sInFile)) { + Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat"); + Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette"); + Assert.AreEqual (183, bitmap.Height, "Original.Height"); + Assert.AreEqual (173, bitmap.Width, "Original.Width"); + Assert.AreEqual (73744, bitmap.Flags, "Original.Flags"); + Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat"); + hbitmap = bitmap.GetHbitmap (); + } + // hbitmap survives original bitmap disposal + using (Image image = Image.FromHbitmap (hbitmap)) { + //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "FromHbitmap.PixelFormat"); + Assert.AreEqual (0, image.Palette.Entries.Length, "FromHbitmap.Palette"); + Assert.AreEqual (183, image.Height, "FromHbitmap.Height"); + Assert.AreEqual (173, image.Width, "FromHbitmap.Width"); + Assert.AreEqual (335888, image.Flags, "FromHbitmap.Flags"); + Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "FromHbitmap.RawFormat"); + } + } + + [Test] + public void CreateMultipleBitmapFromSameHBITMAP () + { + IntPtr hbitmap; + string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp"); + using (Bitmap bitmap = new Bitmap (sInFile)) { + Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat"); + Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette"); + Assert.AreEqual (183, bitmap.Height, "Original.Height"); + Assert.AreEqual (173, bitmap.Width, "Original.Width"); + Assert.AreEqual (73744, bitmap.Flags, "Original.Flags"); + Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat"); + hbitmap = bitmap.GetHbitmap (); + } + // hbitmap survives original bitmap disposal + using (Image image = Image.FromHbitmap (hbitmap)) { + //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "1.PixelFormat"); + Assert.AreEqual (0, image.Palette.Entries.Length, "1.Palette"); + Assert.AreEqual (183, image.Height, "1.Height"); + Assert.AreEqual (173, image.Width, "1.Width"); + Assert.AreEqual (335888, image.Flags, "1.Flags"); + Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "1.RawFormat"); + } + using (Image image2 = Image.FromHbitmap (hbitmap)) { + //Assert.AreEqual (PixelFormat.Format32bppRgb, image2.PixelFormat, "2.PixelFormat"); + Assert.AreEqual (0, image2.Palette.Entries.Length, "2.Palette"); + Assert.AreEqual (183, image2.Height, "2.Height"); + Assert.AreEqual (173, image2.Width, "2.Width"); + Assert.AreEqual (335888, image2.Flags, "2.Flags"); + Assert.IsTrue (image2.RawFormat.Equals (ImageFormat.MemoryBmp), "2.RawFormat"); + } + } +#endif } }