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