* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Drawing / Test / System.Drawing / TestBitmap.cs
index 7576f2f4eeb2708f7c7126d36b8bd9f8261e51f3..121dfec02d8939e3e61e7842555745f9f74abc20 100644 (file)
@@ -4,8 +4,29 @@
 // Author:
 //
 //      Jordi Mas i Hernàndez (jmas@softcatala.org>
+//      Jonathan Gilbert <logic@deltaq.org>
 //
 // (C) 2004 Ximian, Inc.  http://www.ximian.com
+// Copyright (C) 2004,2006 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
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 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;
@@ -15,26 +36,19 @@ using System.IO;
 using System.Security.Cryptography;
 using System.Text;
 using System.Runtime.InteropServices;
+using System.Security.Permissions;
 
 namespace MonoTests.System.Drawing{
 
-       [TestFixture]   
+       [TestFixture]
+       [SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
        public class TestBitmap {
                
-               [TearDown]
-               public void Clean() {}
-               
-               [SetUp]
-               public void GetReady()          
-               {
-               
-               }
-                       
-               //[Test]
+               [Test]
                public void TestPixels() 
                {               
                        // Tests GetSetPixel/SetPixel                   
-                       Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);                                                                                    
+                       Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);
                        bmp.SetPixel(0,0,Color.FromArgb(255,128,128,128));                                      
                        Color color = bmp.GetPixel(0,0);                                
                                                
@@ -44,7 +58,26 @@ namespace MonoTests.System.Drawing{
                        Color color2 = bmp.GetPixel(99,99);                                                                             
                        Assert.AreEqual (Color.FromArgb(255,255,0,155), color2);                        
                }
-               
+
+               [Test]
+               public void LockBits_NonIndexedWrite ()
+               {
+                       Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);
+                       Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+                        BitmapData mybitmapdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+                       bmp.UnlockBits (mybitmapdata);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void LockBits_IndexedWrite ()
+               {
+                       Bitmap bmp= new Bitmap(100,100, PixelFormat.Format8bppIndexed);
+                       Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+                        BitmapData mybitmapdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+                       bmp.UnlockBits (mybitmapdata);
+               }
+
                /* Get the output directory depending on the runtime and location*/
                public static string getOutSubDir()
                {                               
@@ -79,9 +112,8 @@ namespace MonoTests.System.Drawing{
                        
                        return sRslt;
                }
-               
-       
 
+               // note: this test fails when saving (for the same reason) on Mono and MS.NET
                //[Test]
                public void MakeTransparent() 
                {
@@ -89,7 +121,6 @@ namespace MonoTests.System.Drawing{
                        string sOutFile =  getOutSubDir() + "transparent.bmp";
                                                
                        Bitmap  bmp = new Bitmap(sInFile);
-                       Console.WriteLine("Bitmap loaded OK", bmp != null);
                                        
                        bmp.MakeTransparent();
                        bmp.Save(sOutFile);                                                     
@@ -100,17 +131,14 @@ namespace MonoTests.System.Drawing{
                        Assert.AreEqual (Color.Black.B, color.B);                                                                               
                }
                
-               //[Test]
+               [Test]
                public void Clone()
                {
                        string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
-                       string sOutFile =  getOutSubDir() + "clone24.bmp";                      
-                       
                        Rectangle rect = new Rectangle(0,0,50,50);                                              
                        Bitmap  bmp = new Bitmap(sInFile);                      
                        
                        Bitmap bmpNew = bmp.Clone (rect, PixelFormat.Format32bppArgb);                                                                  
-                       
                        Color colororg0 = bmp.GetPixel(0,0);            
                        Color colororg50 = bmp.GetPixel(49,49);                                 
                        Color colornew0 = bmpNew.GetPixel(0,0);         
@@ -120,7 +148,7 @@ namespace MonoTests.System.Drawing{
                        Assert.AreEqual (colororg50, colornew50);                               
                }       
                
-               //[Test]
+               [Test]
                public void CloneImage()
                {
                        string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
@@ -130,11 +158,11 @@ namespace MonoTests.System.Drawing{
                        
                        Assert.AreEqual (bmp.Width, bmpNew.Width);
                        Assert.AreEqual (bmp.Height, bmpNew.Height);            
-                       Assert.AreEqual (bmp.PixelFormat, bmpNew.PixelFormat);                  
+                       Assert.AreEqual (bmp.PixelFormat, bmpNew.PixelFormat);
                        
                }       
 
-               //[Test]
+               [Test]
                public void Frames()
                {
                        string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
@@ -145,6 +173,16 @@ namespace MonoTests.System.Drawing{
                        Assert.AreEqual (1, cnt);                                                               
                        Assert.AreEqual (0, active);                                                                                    
                }
+               
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+#if TARGET_JVM
+               [Category ("NotWorking")]
+#endif
+               public void FileDoesNotExists ()
+               {                       
+                       Bitmap  bmp = new Bitmap ("FileDoesNotExists.jpg");                     
+               }
 
                static string ByteArrayToString(byte[] arrInput)
                {
@@ -160,18 +198,17 @@ namespace MonoTests.System.Drawing{
 
                public string RotateBmp (Bitmap src, RotateFlipType rotate)
                {                       
-                       int witdh = 150, height = 150, index = 0;                       
-                       byte[] pixels = new byte [witdh * height * 3];
+                       int width = 150, height = 150, index = 0;                       
+                       byte[] pixels = new byte [width * height * 3];
                        Bitmap bmp_rotate;
                        byte[] hash;
                        Color clr;
 
-
-                       bmp_rotate = src.Clone (new RectangleF (0,0, witdh, height), PixelFormat.Format32bppArgb);      
+                       bmp_rotate = src.Clone (new RectangleF (0,0, width, height), PixelFormat.Format32bppArgb);      
                        bmp_rotate.RotateFlip (rotate);                 
 
                        for (int y = 0; y < height; y++) {
-                               for (int x = 0; x < witdh; x++) {                               
+                               for (int x = 0; x < width; x++) {
                                        clr = bmp_rotate.GetPixel (x,y);
                                        pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++]  = clr.B;     
                                }                               
@@ -180,17 +217,69 @@ namespace MonoTests.System.Drawing{
                        hash = new MD5CryptoServiceProvider().ComputeHash (pixels);
                        return ByteArrayToString (hash);
                }
+#if !TARGET_JVM
+               public string RotateIndexedBmp (Bitmap src, RotateFlipType type)
+               {
+                       int pixels_per_byte;
+
+                       switch (src.PixelFormat)
+                       {
+                               case PixelFormat.Format1bppIndexed: pixels_per_byte = 8; break;
+                               case PixelFormat.Format4bppIndexed: pixels_per_byte = 2; break;
+                               case PixelFormat.Format8bppIndexed: pixels_per_byte = 1; break;
+
+                               default: throw new Exception("Cannot pass a bitmap of format " + src.PixelFormat + " to RotateIndexedBmp");
+                       }
+
+                       Bitmap test = src.Clone () as Bitmap;
+
+                       test.RotateFlip (type);
+
+                       BitmapData data = null;
+                       byte[] pixel_data;
+
+                       try
+                       {
+                               data = test.LockBits (new Rectangle (0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat);
+
+                               int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte;
+                               pixel_data = new byte[data.Height * scan_size];
+
+                               for (int y=0; y < data.Height; y++) {
+                                       IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64 ());
+                                       int dest_offset = y * scan_size;
+                                       for (int x=0; x < scan_size; x++)
+                                               pixel_data[dest_offset + x] = Marshal.ReadByte (src_ptr, x);
+                               }
+                       }
+                       finally
+                       {
+                               if (test != null) {
+                                       if (data != null)
+                                               try { test.UnlockBits(data); } catch {}
+
+                                       try { test.Dispose(); } catch {}
+                               }
+                       }
+
+                       if (pixel_data == null)
+                               return "--ERROR--";
+
+                       byte[] hash = new MD5CryptoServiceProvider().ComputeHash (pixel_data);
+                       return ByteArrayToString (hash);
+               }
+#endif         
                
                
                /*
                        Rotate bitmap in diffent ways, and check the result
                        pixels using MD5
                */
-               //[Test]
+               [Test]
                public void Rotate()
                {
                        string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");     
-                       Bitmap  bmp = new Bitmap(sInFile);              
+                       Bitmap  bmp = new Bitmap(sInFile);
                        
                        Assert.AreEqual ("312958A3C67402E1299413794988A3", RotateBmp (bmp, RotateFlipType.Rotate90FlipNone));   
                        Assert.AreEqual ("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp (bmp, RotateFlipType.Rotate180FlipNone));
@@ -201,6 +290,66 @@ namespace MonoTests.System.Drawing{
                        Assert.AreEqual ("71A173882C16755D86F4BC26532374", RotateBmp (bmp, RotateFlipType.Rotate270FlipX));
 
                }
+
+#if !TARGET_JVM
+               /*
+                       Rotate 1- and 4-bit bitmaps in different ways and check the
+                       resulting pixels using MD5
+               */
+               [Test]
+               [Category ("NotDotNet")] // that doesn't work under MS.NET and Windows (even without the StreamWriter)
+               public void Rotate1bit4bit()
+               {
+                       string[] files = {
+                                          getInFile ("bitmaps/1bit.png"),
+                                          getInFile ("bitmaps/4bit.png")
+                                        };
+
+                       StringBuilder md5s = new StringBuilder();
+
+                       foreach (string file in files)
+                               using (Bitmap bmp = new Bitmap(file))
+                                       foreach (RotateFlipType type in Enum.GetValues (typeof(RotateFlipType)))
+                                               md5s.Append (RotateIndexedBmp (bmp, type));
+
+                       using (StreamWriter writer = new StreamWriter("/tmp/md5s.txt"))
+                               writer.WriteLine(md5s);
+
+                       Assert.AreEqual (
+                               "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit RotateNoneFlipNone
+                               "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit Rotate180FlipXY
+                               "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate90FlipNone
+                               "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate270FlipXY
+                               "64AE60858A02228F7B1B18C7812FB6" + // 1-bit Rotate180FlipNone
+                               "64AE60858A02228F7B1B18C7812FB6" + // 1-bit RotateNoneFlipXY
+                               "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate270FlipNone
+                               "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate90FlipXY
+                               "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit RotateNoneFlipX
+                               "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit Rotate180FlipY
+                               "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate90FlipX
+                               "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate270FlipY
+                               "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit Rotate180FlipX
+                               "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit RotateNoneFlipY
+                               "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate270FlipX
+                               "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate90FlipY
+                               "3CC874B571902366AACED5D619E87D" + // 4-bit RotateNoneFlipNone
+                               "3CC874B571902366AACED5D619E87D" + // 4-bit Rotate180FlipXY
+                               "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate90FlipNone
+                               "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate270FlipXY
+                               "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit Rotate180FlipNone
+                               "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit RotateNoneFlipXY
+                               "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate270FlipNone
+                               "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate90FlipXY
+                               "545876C99ACF833E69FBFFBF436034" + // 4-bit RotateNoneFlipX
+                               "545876C99ACF833E69FBFFBF436034" + // 4-bit Rotate180FlipY
+                               "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate90FlipX
+                               "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate270FlipY
+                               "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit Rotate180FlipX
+                               "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit RotateNoneFlipY
+                               "B6B6245796C836923ABAABDF368B29" + // 4-bit Rotate270FlipX
+                               "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)
@@ -270,7 +419,8 @@ namespace MonoTests.System.Drawing{
                        firsts, changes them, and then using GetPixel does another check of the changes.
                        The results match the .Net framework
                */
-               //[Test]
+               [Test]
+               [Category ("NotWorking")]
                public void LockBitmap ()
                {       
                        string hash = "";               
@@ -311,6 +461,138 @@ namespace MonoTests.System.Drawing{
                        Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                            
                                                
                }
-               
+
+               /*
+                       Tests the LockBitmap and UnlockBitmap functions, specifically the copying
+                       of bitmap data in the directions indicated by the ImageLockMode.
+               */
+               [Test]
+               public void LockUnlockBitmap()
+               {
+                       BitmapData data;
+                       int pixel_value;
+                       Color pixel_colour;
+
+                       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.Format24bppRgb))
+                       {
+                               bmp.SetPixel (0, 0, red);
+
+                               data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
+                               pixel_value = Marshal.ReadInt32 (data.Scan0);
+                               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);
+
+                               Marshal.WriteInt32 (data.Scan0, blue.ToArgb ());
+
+                               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);
+
+                               Assert.AreEqual (red, pixel_colour);
+
+                               data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
+
+                               Marshal.WriteInt32 (data.Scan0, blue.ToArgb ());
+
+                               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);
+
+                               Assert.AreEqual (blue, pixel_colour);
+                       }
+
+                       using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
+                       {
+                               bmp.SetPixel (0, 0, red);
+
+                               data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
+
+                               int r, g, b;
+
+                               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);
+
+                               Assert.AreEqual (red, pixel_colour);
+
+                               Marshal.WriteByte (data.Scan0, 0, blue.B);
+                               Marshal.WriteByte (data.Scan0, 1, blue.G);
+                               Marshal.WriteByte (data.Scan0, 2, blue.R);
+
+                               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);
+
+                               Assert.AreEqual (red, bmp.GetPixel (0, 0));
+
+                               data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+
+                               Marshal.WriteByte (data.Scan0, 0, blue.B);
+                               Marshal.WriteByte (data.Scan0, 1, blue.G);
+                               Marshal.WriteByte (data.Scan0, 2, blue.R);
+
+                               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);
+
+                               Assert.AreEqual (blue, bmp.GetPixel (0, 0));
+                       }
+               }
+#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 ();
+                       }
+               }
        }
 }
+