New test.
[mono.git] / mcs / class / System.Drawing / Test / System.Drawing / TestBitmap.cs
1 //
2 // Bitmap class testing unit
3 //
4 // Author:
5 //
6 //       Jordi Mas i Hernàndez (jmas@softcatala.org>
7 //       Jonathan Gilbert <logic@deltaq.org>
8 //
9 // (C) 2004 Ximian, Inc.  http://www.ximian.com
10 // Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 using System;
32 using System.Drawing;
33 using System.Drawing.Imaging;
34 using NUnit.Framework;
35 using System.IO;
36 using System.Security.Cryptography;
37 using System.Text;
38 using System.Runtime.InteropServices;
39 using System.Security.Permissions;
40
41 namespace MonoTests.System.Drawing{
42
43         [TestFixture]
44         [SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
45 #if TARGET_JVM
46         [Category ("NotWorking")]
47 #endif
48         public class TestBitmap {
49                 
50                 [Test]
51                 public void TestPixels() 
52                 {               
53                         // Tests GetSetPixel/SetPixel                   
54                         Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);
55                         bmp.SetPixel(0,0,Color.FromArgb(255,128,128,128));                                      
56                         Color color = bmp.GetPixel(0,0);                                
57                                                 
58                         Assert.AreEqual (Color.FromArgb(255,128,128,128), color);
59                         
60                         bmp.SetPixel(99,99,Color.FromArgb(255,255,0,155));                                      
61                         Color color2 = bmp.GetPixel(99,99);                                                                             
62                         Assert.AreEqual (Color.FromArgb(255,255,0,155), color2);                        
63                 }
64
65                 [Test]
66                 public void LockBits_32_32_NonIndexedWrite ()
67                 {
68                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
69                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
70                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
71                                 Assert.AreEqual (100, data.Height, "Height");
72                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
73                                 Assert.AreEqual (400, data.Stride, "Stride");
74                                 Assert.AreEqual (100, data.Width, "Width");
75                                 bmp.UnlockBits (data);
76                         }
77                 }
78
79                 [Test]
80                 [Category ("NotWorking")]
81                 public void LockBits_32_24_NonIndexedWrite ()
82                 {
83                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
84                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
85                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
86                                 Assert.AreEqual (100, data.Height, "Height");
87                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
88                                 Assert.AreEqual (300, data.Stride, "Stride");
89                                 Assert.AreEqual (100, data.Width, "Width");
90                                 bmp.UnlockBits (data);
91                         }
92                 }
93
94                 [Test]
95                 [Category ("NotWorking")]
96                 public void LockBits_24_24_NonIndexedWrite ()
97                 {
98                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
99                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
100                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
101                                 Assert.AreEqual (100, data.Height, "Height");
102                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
103                                 Assert.AreEqual (300, data.Stride, "Stride");
104                                 Assert.AreEqual (100, data.Width, "Width");
105                                 bmp.UnlockBits (data);
106                         }
107                 }
108
109                 [Test]
110                 public void LockBits_24_32_NonIndexedWrite ()
111                 {
112                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
113                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
114                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
115                                 Assert.AreEqual (100, data.Height, "Height");
116                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
117                                 Assert.AreEqual (400, data.Stride, "Stride");
118                                 Assert.AreEqual (100, data.Width, "Width");
119                                 bmp.UnlockBits (data);
120                         }
121                 }
122
123                 [Test]
124                 [ExpectedException (typeof (ArgumentException))]
125                 public void LockBits_IndexedWrite_NonIndexed ()
126                 {
127                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
128                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
129                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
130                         }
131                 }
132
133                 [Test]
134                 [ExpectedException (typeof (ArgumentException))]
135                 public void LockBits_NonIndexedWrite_ToIndexed ()
136                 {
137                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
138                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
139                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
140                         }
141                 }
142
143                 [Test]
144                 public void LockBits_IndexedWrite_SameIndexedFormat ()
145                 {
146                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
147                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
148                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
149                                 Assert.AreEqual (100, data.Height, "Height");
150                                 Assert.AreEqual (PixelFormat.Format8bppIndexed, data.PixelFormat, "PixelFormat");
151                                 Assert.AreEqual (100, data.Stride, "Stride");
152                                 Assert.AreEqual (100, data.Width, "Width");
153                                 bmp.UnlockBits (data);
154                         }
155                 }
156
157                 [Test]
158                 [ExpectedException (typeof (ArgumentException))]
159                 public void LockBits_Disposed ()
160                 {
161                         Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
162                         Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
163                         bmp.Dispose ();
164                         bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
165                 }
166
167                 [Test]
168                 [ExpectedException (typeof (ArgumentException))]
169                 public void UnlockBits_Disposed ()
170                 {
171                         Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
172                         Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
173                         BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
174                         bmp.Dispose ();
175                         bmp.UnlockBits (data);
176                 }
177
178                 [Test]
179                 [ExpectedException (typeof (ArgumentException))]
180                 public void UnlockBits_Null ()
181                 {
182                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
183                                 bmp.UnlockBits (null);
184                         }
185                 }
186 #if NET_2_0
187                 [Test]
188                 [ExpectedException (typeof (ArgumentException))]
189                 public void LockBits_BitmapData_Null ()
190                 {
191                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
192                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
193                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, null);
194                         }
195                 }
196
197                 [Test]
198                 public void LockBits_32_32_BitmapData ()
199                 {
200                         BitmapData data = new BitmapData ();
201                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
202                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
203                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
204                                 Assert.AreEqual (100, data.Height, "Height");
205                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
206                                 Assert.AreEqual (400, data.Stride, "Stride");
207                                 Assert.AreEqual (100, data.Width, "Width");
208                                 bmp.UnlockBits (data);
209                         }
210                 }
211
212                 [Test]
213                 [Category ("NotWorking")]
214                 public void LockBits_32_24_BitmapData ()
215                 {
216                         BitmapData data = new BitmapData ();
217                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
218                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
219                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
220                                 Assert.AreEqual (100, data.Height, "Height");
221                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
222                                 Assert.AreEqual (300, data.Stride, "Stride");
223                                 Assert.AreEqual (100, data.Width, "Width");
224                                 bmp.UnlockBits (data);
225                         }
226                 }
227
228                 [Test]
229                 [Category ("NotWorking")]
230                 public void LockBits_24_24_BitmapData ()
231                 {
232                         BitmapData data = new BitmapData ();
233                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
234                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
235                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
236                                 Assert.AreEqual (100, data.Height, "Height");
237                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
238                                 Assert.AreEqual (300, data.Stride, "Stride");
239                                 Assert.AreEqual (100, data.Width, "Width");
240                                 bmp.UnlockBits (data);
241                         }
242                 }
243
244                 [Test]
245                 public void LockBits_24_32_BitmapData ()
246                 {
247                         BitmapData data = new BitmapData ();
248                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
249                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
250                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
251                                 Assert.AreEqual (100, data.Height, "Height");
252                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
253                                 Assert.AreEqual (400, data.Stride, "Stride");
254                                 Assert.AreEqual (100, data.Width, "Width");
255                                 bmp.UnlockBits (data);
256                         }
257                 }
258 #endif
259
260                 /* Get the output directory depending on the runtime and location*/
261                 public static string getOutSubDir()
262                 {                               
263                         string sSub, sRslt;                     
264                         
265                         if (Environment.GetEnvironmentVariable("MSNet")==null)
266                                 sSub = "mono/";
267                         else
268                                 sSub = "MSNet/";                        
269                         
270                         sRslt = Path.GetFullPath (sSub);
271                                 
272                         if (Directory.Exists(sRslt) ==  false) 
273                                 sRslt = "Test/System.Drawing/" + sSub;                                                  
274                         
275                         if (sRslt.Length > 0)
276                                 if (sRslt[sRslt.Length-1] != '\\' && sRslt[sRslt.Length-1] != '/')
277                                         sRslt += "/";                                   
278                         
279                         return sRslt;
280                 }
281                 
282                 /* Get the input directory depending on the runtime*/
283                 public static string getInFile(string file)
284                 {                               
285                         string sRslt = Path.GetFullPath ("../System.Drawing/" + file);
286                         if (!File.Exists (sRslt))
287                                 sRslt = "Test/System.Drawing/" + file;
288                         return sRslt;
289                 }
290
291                 // note: this test fails when saving (for the same reason) on Mono and MS.NET
292                 //[Test]
293                 public void MakeTransparent() 
294                 {
295                         string sInFile =   getInFile("bitmaps/maketransparent.bmp");
296                         string sOutFile =  getOutSubDir() + "transparent.bmp";
297                                                 
298                         Bitmap  bmp = new Bitmap(sInFile);
299                                         
300                         bmp.MakeTransparent();
301                         bmp.Save(sOutFile);                                                     
302                         
303                         Color color = bmp.GetPixel(1,1);                                                        
304                         Assert.AreEqual (Color.Black.R, color.R);                                                                                       
305                         Assert.AreEqual (Color.Black.G, color.G);                                                                                       
306                         Assert.AreEqual (Color.Black.B, color.B);                                                                               
307                 }
308                 
309                 [Test]
310                 public void Clone()
311                 {
312                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
313                         Rectangle rect = new Rectangle(0,0,50,50);                                              
314                         Bitmap  bmp = new Bitmap(sInFile);                      
315                         
316                         Bitmap bmpNew = bmp.Clone (rect, PixelFormat.Format32bppArgb);                                                                  
317                         Color colororg0 = bmp.GetPixel(0,0);            
318                         Color colororg50 = bmp.GetPixel(49,49);                                 
319                         Color colornew0 = bmpNew.GetPixel(0,0);         
320                         Color colornew50 = bmpNew.GetPixel(49,49);                              
321                         
322                         Assert.AreEqual (colororg0, colornew0);                                                                                 
323                         Assert.AreEqual (colororg50, colornew50);                               
324                 }       
325                 
326                 [Test]
327                 public void CloneImage()
328                 {
329                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
330                         Bitmap  bmp = new Bitmap(sInFile);                      
331                         
332                         Bitmap bmpNew = (Bitmap) bmp.Clone ();                  
333                         
334                         Assert.AreEqual (bmp.Width, bmpNew.Width);
335                         Assert.AreEqual (bmp.Height, bmpNew.Height);            
336                         Assert.AreEqual (bmp.PixelFormat, bmpNew.PixelFormat);
337                         
338                 }       
339
340                 [Test]
341                 public void Frames()
342                 {
343                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
344                         Bitmap  bmp = new Bitmap(sInFile);                                              
345                         int cnt = bmp.GetFrameCount(FrameDimension.Page);                       
346                         int active = bmp.SelectActiveFrame (FrameDimension.Page, 0);
347                         
348                         Assert.AreEqual (1, cnt);                                                               
349                         Assert.AreEqual (0, active);                                                                                    
350                 }
351                 
352                 [Test]
353                 [ExpectedException (typeof (ArgumentException))]
354 #if TARGET_JVM
355                 [Category ("NotWorking")]
356 #endif
357                 public void FileDoesNotExists ()
358                 {                       
359                         Bitmap  bmp = new Bitmap ("FileDoesNotExists.jpg");                     
360                 }
361
362                 static string ByteArrayToString(byte[] arrInput)
363                 {
364                         int i;
365                         StringBuilder sOutput = new StringBuilder(arrInput.Length);
366                         for (i=0;i < arrInput.Length -1; i++) 
367                         {
368                                 sOutput.Append(arrInput[i].ToString("X2"));
369                         }
370                         return sOutput.ToString();
371                 }
372
373
374                 public string RotateBmp (Bitmap src, RotateFlipType rotate)
375                 {                       
376                         int width = 150, height = 150, index = 0;                       
377                         byte[] pixels = new byte [width * height * 3];
378                         Bitmap bmp_rotate;
379                         byte[] hash;
380                         Color clr;
381
382                         bmp_rotate = src.Clone (new RectangleF (0,0, width, height), PixelFormat.Format32bppArgb);      
383                         bmp_rotate.RotateFlip (rotate);                 
384
385                         for (int y = 0; y < height; y++) {
386                                 for (int x = 0; x < width; x++) {
387                                         clr = bmp_rotate.GetPixel (x,y);
388                                         pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++]  = clr.B;     
389                                 }                               
390                         }
391                 
392                         hash = new MD5CryptoServiceProvider().ComputeHash (pixels);
393                         return ByteArrayToString (hash);
394                 }
395 #if !TARGET_JVM
396                 public string RotateIndexedBmp (Bitmap src, RotateFlipType type)
397                 {
398                         int pixels_per_byte;
399
400                         switch (src.PixelFormat)
401                         {
402                                 case PixelFormat.Format1bppIndexed: pixels_per_byte = 8; break;
403                                 case PixelFormat.Format4bppIndexed: pixels_per_byte = 2; break;
404                                 case PixelFormat.Format8bppIndexed: pixels_per_byte = 1; break;
405
406                                 default: throw new Exception("Cannot pass a bitmap of format " + src.PixelFormat + " to RotateIndexedBmp");
407                         }
408
409                         Bitmap test = src.Clone () as Bitmap;
410
411                         test.RotateFlip (type);
412
413                         BitmapData data = null;
414                         byte[] pixel_data;
415
416                         try
417                         {
418                                 data = test.LockBits (new Rectangle (0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat);
419
420                                 int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte;
421                                 pixel_data = new byte[data.Height * scan_size];
422
423                                 for (int y=0; y < data.Height; y++) {
424                                         IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64 ());
425                                         int dest_offset = y * scan_size;
426                                         for (int x=0; x < scan_size; x++)
427                                                 pixel_data[dest_offset + x] = Marshal.ReadByte (src_ptr, x);
428                                 }
429                         }
430                         finally
431                         {
432                                 if (test != null) {
433                                         if (data != null)
434                                                 try { test.UnlockBits(data); } catch {}
435
436                                         try { test.Dispose(); } catch {}
437                                 }
438                         }
439
440                         if (pixel_data == null)
441                                 return "--ERROR--";
442
443                         byte[] hash = new MD5CryptoServiceProvider().ComputeHash (pixel_data);
444                         return ByteArrayToString (hash);
445                 }
446 #endif          
447                 
448                 
449                 /*
450                         Rotate bitmap in diffent ways, and check the result
451                         pixels using MD5
452                 */
453                 [Test]
454                 public void Rotate()
455                 {
456                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");     
457                         Bitmap  bmp = new Bitmap(sInFile);
458                         
459                         Assert.AreEqual ("312958A3C67402E1299413794988A3", RotateBmp (bmp, RotateFlipType.Rotate90FlipNone));   
460                         Assert.AreEqual ("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp (bmp, RotateFlipType.Rotate180FlipNone));
461                         Assert.AreEqual ("15AD2ADBDC7090C0EC744D0F7ACE2F", RotateBmp (bmp, RotateFlipType.Rotate270FlipNone));
462                         Assert.AreEqual ("2E10FEC1F4FD64ECC51D7CE68AEB18", RotateBmp (bmp, RotateFlipType.RotateNoneFlipX));
463                         Assert.AreEqual ("E63204779B566ED01162B90B49BD9E", RotateBmp (bmp, RotateFlipType.Rotate90FlipX));
464                         Assert.AreEqual ("B1ECB17B5093E13D04FF55CFCF7763", RotateBmp (bmp, RotateFlipType.Rotate180FlipX));
465                         Assert.AreEqual ("71A173882C16755D86F4BC26532374", RotateBmp (bmp, RotateFlipType.Rotate270FlipX));
466
467                 }
468
469 #if !TARGET_JVM
470                 /*
471                         Rotate 1- and 4-bit bitmaps in different ways and check the
472                         resulting pixels using MD5
473                 */
474                 [Test]
475                 public void Rotate1bit4bit()
476                 {
477                         if ((Environment.OSVersion.Platform != (PlatformID)4)
478                          && (Environment.OSVersion.Platform != (PlatformID)128))
479                                 Assert.Ignore("This fails with Microsoft's GDIPLUS.DLL due to off-by-1 errors in their GdipBitmapRotateFlip function.");
480
481                         string[] files = {
482                                            getInFile ("bitmaps/1bit.png"),
483                                            getInFile ("bitmaps/4bit.png")
484                                          };
485
486                         StringBuilder md5s = new StringBuilder();
487
488                         foreach (string file in files)
489                                 using (Bitmap bmp = new Bitmap(file))
490                                         foreach (RotateFlipType type in Enum.GetValues (typeof(RotateFlipType)))
491                                                 md5s.Append (RotateIndexedBmp (bmp, type));
492
493                         using (StreamWriter writer = new StreamWriter("/tmp/md5s.txt"))
494                                 writer.WriteLine(md5s);
495
496                         Assert.AreEqual (
497                                 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit RotateNoneFlipNone
498                                 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit Rotate180FlipXY
499                                 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate90FlipNone
500                                 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate270FlipXY
501                                 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit Rotate180FlipNone
502                                 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit RotateNoneFlipXY
503                                 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate270FlipNone
504                                 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate90FlipXY
505                                 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit RotateNoneFlipX
506                                 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit Rotate180FlipY
507                                 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate90FlipX
508                                 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate270FlipY
509                                 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit Rotate180FlipX
510                                 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit RotateNoneFlipY
511                                 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate270FlipX
512                                 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate90FlipY
513                                 "3CC874B571902366AACED5D619E87D" + // 4-bit RotateNoneFlipNone
514                                 "3CC874B571902366AACED5D619E87D" + // 4-bit Rotate180FlipXY
515                                 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate90FlipNone
516                                 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate270FlipXY
517                                 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit Rotate180FlipNone
518                                 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit RotateNoneFlipXY
519                                 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate270FlipNone
520                                 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate90FlipXY
521                                 "545876C99ACF833E69FBFFBF436034" + // 4-bit RotateNoneFlipX
522                                 "545876C99ACF833E69FBFFBF436034" + // 4-bit Rotate180FlipY
523                                 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate90FlipX
524                                 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate270FlipY
525                                 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit Rotate180FlipX
526                                 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit RotateNoneFlipY
527                                 "B6B6245796C836923ABAABDF368B29" + // 4-bit Rotate270FlipX
528                                 "B6B6245796C836923ABAABDF368B29",  // 4-bit Rotate90FlipY
529                                 md5s.ToString ());
530                 }
531                 
532                 public void LockBmp (PixelFormat fmt, PixelFormat fmtlock, string output, 
533                         int lwidth , int lheight, ref string hash1, ref string hash2)
534                 {                       
535                         int width = 100, height = 100, bbps, cur, pos;
536                         Bitmap  bmp = new Bitmap (width, height, fmt);                                                                          
537                         Graphics gr = Graphics.FromImage (bmp);                 
538                         byte[] hash;
539                         Color clr;
540                         byte[] btv = new byte[1];                                               
541                         int y, x, len = width * height * 4, index = 0;                  
542                         byte[] pixels = new byte [len];
543                         hash1 = hash2 ="";
544                         
545                         bbps = Image.GetPixelFormatSize (fmt);                  
546                                  
547                         Pen p = new Pen (Color.FromArgb (255, 100, 200, 250), 2);                               
548                         gr.DrawRectangle(p, 1.0F, 1.0F, 80.0F, 80.0F);                          
549                         
550                         BitmapData bd = bmp.LockBits (new Rectangle (0, 0, lwidth, lheight), ImageLockMode.ReadOnly,  fmtlock);
551                         
552                         pos = bd.Scan0.ToInt32();                       
553                         for (y = 0; y < bd.Height; y++) {                       
554                                 for (x = 0; x < bd.Width; x++) {
555                                         
556                                         /* Read the pixels*/
557                                         for (int bt =0; bt < bbps/8; bt++, index++) {
558                                                 cur = pos;
559                                                 cur+= y * bd.Stride;
560                                                 cur+= x * bbps/8;                                       
561                                                 cur+= bt;                                       
562                                                 Marshal.Copy ((IntPtr)cur, btv, 0, 1);
563                                                 pixels[index] = btv[0];
564                                                 
565                                                 /* Make change of all the colours = 250 to 10*/                                         
566                                                 if (btv[0] == 250) {
567                                                         btv[0] = 10;
568                                                         Marshal.Copy (btv, 0, (IntPtr)cur, 1);
569                                                 }
570                                         }
571                                 }
572                         }                                       
573                         
574                         for (int i = index; i < len; i++)
575                                 pixels[index] = 0;
576                 
577                         hash = new MD5CryptoServiceProvider().ComputeHash (pixels);                     
578                         bmp.UnlockBits (bd);                                                    
579                                                 
580                         hash1 = ByteArrayToString (hash);
581                         
582                         /* MD5 of the changed bitmap*/
583                         for (y = 0, index = 0; y < height; y++) {
584                                 for (x = 0; x < width; x++) {                           
585                                         clr = bmp.GetPixel (x,y);
586                                         pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++]  = clr.B;     
587                                 }                               
588                         }
589                         
590                         hash = new MD5CryptoServiceProvider().ComputeHash (pixels);                                             
591                         hash2 = ByteArrayToString (hash);
592                         
593                         /*bmp.Save (output, ImageFormat.Bmp);*/
594                 }
595                 /*
596                         Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns
597                         firsts, changes them, and then using GetPixel does another check of the changes.
598                         The results match the .Net framework
599                 */
600                 [Test]
601                 [Category ("NotWorking")]
602                 public void LockBitmap ()
603                 {       
604                         string hash = "";               
605                         string hashchg = "";                            
606                                                         
607                         /* Locks the whole bitmap*/                     
608                         LockBmp (PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, "output32bppArgb.bmp", 100, 100, ref hash, ref hashchg);                             
609                         Assert.AreEqual ("AF5BFD4E98D6708FF4C9982CC9C68F", hash);                       
610                         Assert.AreEqual ("BBEE27DC85563CB58EE11E8951230F", hashchg);                    
611                         
612                         LockBmp (PixelFormat.Format32bppPArgb, PixelFormat.Format32bppPArgb, "output32bppPArgb.bmp", 100, 100, ref hash, ref hashchg);                  
613                         Assert.AreEqual ("AF5BFD4E98D6708FF4C9982CC9C68F", hash);                       
614                         Assert.AreEqual ("BBEE27DC85563CB58EE11E8951230F", hashchg);                    
615                         
616                         LockBmp (PixelFormat.Format32bppRgb, PixelFormat.Format32bppRgb, "output32bppRgb.bmp", 100, 100, ref hash, ref hashchg);
617                         Assert.AreEqual ("AF5BFD4E98D6708FF4C9982CC9C68F", hash);                       
618                         Assert.AreEqual ("BBEE27DC85563CB58EE11E8951230F", hashchg);            
619                         
620                         LockBmp (PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, "output24bppRgb.bmp", 100, 100, ref hash, ref hashchg);
621                         Assert.AreEqual ("A8A071D0B3A3743905B4E193A62769", hash);                       
622                         Assert.AreEqual ("EEE846FA8F892339C64082DFF775CF", hashchg);                                    
623                         
624                         /* Locks a portion of the bitmap*/              
625                         LockBmp (PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, "output32bppArgb.bmp", 50, 50, ref hash, ref hashchg);                               
626                         Assert.AreEqual ("C361FBFD82A4F3C278605AE9EC5385", hash);                       
627                         Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                    
628                         
629                         LockBmp (PixelFormat.Format32bppPArgb, PixelFormat.Format32bppPArgb, "output32bppPArgb.bmp", 50, 50, ref hash, ref hashchg);                    
630                         Assert.AreEqual ("C361FBFD82A4F3C278605AE9EC5385", hash);                       
631                         Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                    
632                 
633                         LockBmp (PixelFormat.Format32bppRgb, PixelFormat.Format32bppRgb, "output32bppRgb.bmp", 50, 50, ref hash, ref hashchg);
634                         Assert.AreEqual ("C361FBFD82A4F3C278605AE9EC5385", hash);                       
635                         Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                    
636                         
637                         LockBmp (PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, "output24bppRgb.bmp", 50, 50, ref hash, ref hashchg);
638                         Assert.AreEqual ("FFE86628478591D1A1EB30E894C34F", hash);                       
639                         Assert.AreEqual ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                            
640                                                 
641                 }
642
643                 /*
644                         Tests the LockBitmap and UnlockBitmap functions, specifically the copying
645                         of bitmap data in the directions indicated by the ImageLockMode.
646                 */
647                 [Test]
648                 public void LockUnlockBitmap()
649                 {
650                         BitmapData data;
651                         int pixel_value;
652                         Color pixel_colour;
653
654                         Color red  = Color.FromArgb (Color.Red.A,  Color.Red.R,  Color.Red.G,  Color.Red.B);
655                         Color blue = Color.FromArgb (Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B);
656
657                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppRgb))
658                         {
659                                 bmp.SetPixel (0, 0, red);
660                                 pixel_colour = bmp.GetPixel (0, 0);
661                                 Assert.AreEqual (red, pixel_colour, "Set/Get-Red");
662
663                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
664
665                                 // Marshal follows CPU endianess
666                                 if (BitConverter.IsLittleEndian) {
667                                         pixel_value = Marshal.ReadInt32 (data.Scan0);
668                                 } else {
669                                         pixel_value = Marshal.ReadByte (data.Scan0, 0);
670                                         pixel_value |= Marshal.ReadByte (data.Scan0, 1) << 8;
671                                         pixel_value |= Marshal.ReadByte (data.Scan0, 2) << 16;
672                                         pixel_value |= Marshal.ReadByte (data.Scan0, 3) << 24;
673                                 }
674                                 pixel_colour = Color.FromArgb (pixel_value);
675
676                                 // Disregard alpha information in the test
677                                 pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
678
679                                 Assert.AreEqual (red, pixel_colour, "Red-FromLockedBitmap");
680
681                                 Marshal.WriteInt32 (data.Scan0, blue.ToArgb ());
682
683                                 bmp.UnlockBits (data);
684
685                                 pixel_colour = bmp.GetPixel (0, 0);
686
687                                 // Disregard alpha information in the test
688                                 pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
689
690                                 Assert.AreEqual (red, pixel_colour);
691
692                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
693
694                                 Marshal.WriteInt32 (data.Scan0, blue.ToArgb ());
695
696                                 bmp.UnlockBits (data);
697
698                                 pixel_colour = bmp.GetPixel (0, 0);
699
700                                 // Disregard alpha information in the test
701                                 pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
702
703                                 Assert.AreEqual (blue, pixel_colour);
704                         }
705
706                         using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
707                         {
708                                 bmp.SetPixel (0, 0, red);
709
710                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
711
712                                 int r, g, b;
713
714                                 b = Marshal.ReadByte (data.Scan0, 0);
715                                 g = Marshal.ReadByte (data.Scan0, 1);
716                                 r = Marshal.ReadByte (data.Scan0, 2);
717                                 pixel_colour = Color.FromArgb (red.A, r, g, b);
718
719                                 Assert.AreEqual (red, pixel_colour);
720
721                                 Marshal.WriteByte (data.Scan0, 0, blue.B);
722                                 Marshal.WriteByte (data.Scan0, 1, blue.G);
723                                 Marshal.WriteByte (data.Scan0, 2, blue.R);
724
725                                 bmp.UnlockBits (data);
726
727                                 pixel_colour = bmp.GetPixel (0, 0);
728
729                                 // Disregard alpha information in the test
730                                 pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
731
732                                 Assert.AreEqual (red, bmp.GetPixel (0, 0));
733
734                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
735
736                                 Marshal.WriteByte (data.Scan0, 0, blue.B);
737                                 Marshal.WriteByte (data.Scan0, 1, blue.G);
738                                 Marshal.WriteByte (data.Scan0, 2, blue.R);
739
740                                 bmp.UnlockBits(data);
741
742                                 pixel_colour = bmp.GetPixel (0, 0);
743
744                                 // Disregard alpha information in the test
745                                 pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
746
747                                 Assert.AreEqual (blue, bmp.GetPixel (0, 0));
748                         }
749                 }
750 #endif          
751                 [Test]
752                 public void DefaultFormat1 ()
753                 {
754                         using (Bitmap bmp = new Bitmap (20, 20)) {
755                                 Assert.AreEqual (ImageFormat.MemoryBmp, bmp.RawFormat);
756                         }
757                 }
758
759                 [Test]
760                 public void DefaultFormat2 ()
761                 {
762                         string filename =  Path.GetTempFileName ();
763                         using (Bitmap bmp = new Bitmap (20, 20)) {
764                                 bmp.Save (filename);
765                         }
766
767                         using (Bitmap other = new Bitmap (filename)) {
768                                 Assert.AreEqual (ImageFormat.Png, other.RawFormat);
769                         }
770                         File.Delete (filename);
771                 }
772
773                 [Test]
774                 public void BmpDataStride1 ()
775                 {
776                         Bitmap bmp = new Bitmap (184, 184, PixelFormat.Format1bppIndexed);
777                         BitmapData data = bmp.LockBits (new Rectangle (0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
778                         try {
779                                 Assert.AreEqual (24, data.Stride);
780                         } finally {
781                                 bmp.UnlockBits (data);
782                                 bmp.Dispose ();
783                         }
784                 }
785         }
786 }
787