[runtime] Switch getenv to use heap memory
[mono.git] / mcs / class / System.Drawing / Test / System.Drawing / TestBitmap.cs
1 //
2 // Bitmap class testing unit
3 //
4 // Authors:
5 //      Jordi Mas i Hernàndez (jmas@softcatala.org>
6 //      Jonathan Gilbert <logic@deltaq.org>
7 //      Sebastien Pouliot  <sebastien@ximian.com>
8 //
9 // (C) 2004 Ximian, Inc.  http://www.ximian.com
10 // Copyright (C) 2004,2006-2007 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
32 using System;
33 using System.Drawing;
34 using System.Drawing.Imaging;
35 using System.IO;
36 using System.Runtime.InteropServices;
37 using System.Runtime.Serialization;
38 using System.Runtime.Serialization.Formatters.Binary;
39 #if !NETCOREAPP2_0
40 using System.Runtime.Serialization.Formatters.Soap;
41 #endif
42 using System.Security.Cryptography;
43 using System.Security.Permissions;
44 using System.Text;
45 using System.Xml.Serialization;
46 using NUnit.Framework;
47
48 namespace MonoTests.System.Drawing {
49
50         [TestFixture]
51         public class TestBitmap {
52                 
53                 [Test]
54                 public void TestPixels() 
55                 {               
56                         // Tests GetSetPixel/SetPixel                   
57                         Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);
58                         bmp.SetPixel(0,0,Color.FromArgb(255,128,128,128));                                      
59                         Color color = bmp.GetPixel(0,0);                                
60                                                 
61                         Assert.AreEqual (Color.FromArgb(255,128,128,128), color);
62                         
63                         bmp.SetPixel(99,99,Color.FromArgb(255,255,0,155));                                      
64                         Color color2 = bmp.GetPixel(99,99);                                                                             
65                         Assert.AreEqual (Color.FromArgb(255,255,0,155), color2);                        
66                 }
67
68                 [Test]
69                 public void LockBits_32_32_NonIndexedWrite ()
70                 {
71                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
72                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
73                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
74                                 Assert.AreEqual (100, data.Height, "Height");
75                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
76                                 Assert.AreEqual (400, data.Stride, "Stride");
77                                 Assert.AreEqual (100, data.Width, "Width");
78                                 bmp.UnlockBits (data);
79                         }
80                 }
81
82                 [Test]
83                 public void LockBits_32_24_NonIndexedWrite ()
84                 {
85                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
86                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
87                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
88                                 Assert.AreEqual (100, data.Height, "Height");
89                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
90                                 Assert.AreEqual (300, data.Stride, "Stride");
91                                 Assert.AreEqual (100, data.Width, "Width");
92                                 bmp.UnlockBits (data);
93                         }
94                 }
95
96                 [Test]
97                 public void LockBits_24_24_NonIndexedWrite ()
98                 {
99                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
100                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
101                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
102                                 Assert.AreEqual (100, data.Height, "Height");
103                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
104                                 Assert.AreEqual (300, data.Stride, "Stride");
105                                 Assert.AreEqual (100, data.Width, "Width");
106                                 bmp.UnlockBits (data);
107                         }
108                 }
109
110                 [Test]
111                 public void LockBits_24_32_NonIndexedWrite ()
112                 {
113                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
114                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
115                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
116                                 Assert.AreEqual (100, data.Height, "Height");
117                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
118                                 Assert.AreEqual (400, data.Stride, "Stride");
119                                 Assert.AreEqual (100, data.Width, "Width");
120                                 bmp.UnlockBits (data);
121                         }
122                 }
123
124                 [Test]
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                                 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
130                         }
131                 }
132
133                 [Test]
134                 public void LockBits_NonIndexedWrite_ToIndexed ()
135                 {
136                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
137                                 BitmapData bd = new BitmapData ();
138                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
139                                 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, bd));
140
141                                 // test to see if there's a leak or not in this case
142                                 Assert.AreEqual (IntPtr.Zero, bd.Scan0, "Scan0");
143                         }
144                 }
145
146                 [Test]
147                 public void LockBits_IndexedWrite_SameIndexedFormat ()
148                 {
149                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
150                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
151                                 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
152                                 Assert.AreEqual (100, data.Height, "Height");
153                                 Assert.AreEqual (PixelFormat.Format8bppIndexed, data.PixelFormat, "PixelFormat");
154                                 Assert.AreEqual (100, data.Stride, "Stride");
155                                 Assert.AreEqual (100, data.Width, "Width");
156                                 bmp.UnlockBits (data);
157                         }
158                 }
159
160                 [Test]
161                 public void LockBits_ImageLockMode_Invalid ()
162                 {
163                         using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
164                                 Rectangle r = new Rectangle (4, 4, 4, 4);
165                                 BitmapData data = bmp.LockBits (r, (ImageLockMode)0, PixelFormat.Format24bppRgb);
166                                 try {
167                                         Assert.AreEqual (4, data.Height, "Height");
168                                         Assert.AreEqual (4, data.Width, "Width");
169                                         Assert.IsTrue (data.Stride >= 12, "Stride");
170                                         Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
171                                         Assert.IsFalse (IntPtr.Zero.Equals (data.Scan0), "Scan0");
172                                 }
173                                 finally {
174                                         bmp.UnlockBits (data);
175                                 }
176                         }
177                 }
178
179                 [Test]
180                 public void LockBits_Double ()
181                 {
182                         using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
183                                 Rectangle r = new Rectangle (4, 4, 4, 4);
184                                 BitmapData data = bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
185                                 try {
186                                         Assert.Throws<InvalidOperationException> (() => bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb));
187                                 }
188                                 finally {
189                                         bmp.UnlockBits (data);
190                                 }
191                         }
192                 }
193
194                 [Test]
195                 public void LockBits_Disposed ()
196                 {
197                         Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
198                         Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
199                         bmp.Dispose ();
200                         Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
201                 }
202
203                 [Test]
204                 [Category ("Valgrind")] // this test is known to leak memory (API design limitation)
205                 public void UnlockBits_Disposed ()
206                 {
207                         Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
208                         Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
209                         BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
210                         bmp.Dispose ();
211                         Assert.Throws<ArgumentException> (() => bmp.UnlockBits (data));
212                         // and that results in something like this when executed under Valgrind 
213                         // "40,000 bytes in 1 blocks are possibly lost in loss record 88 of 92"
214                 }
215
216                 [Test]
217                 public void UnlockBits_Null ()
218                 {
219                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
220                                 Assert.Throws<ArgumentException> (() => bmp.UnlockBits (null));
221                         }
222                 }
223                 [Test]
224                 public void LockBits_BitmapData_Null ()
225                 {
226                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
227                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
228                                 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, null));
229                         }
230                 }
231
232                 [Test]
233                 public void LockBits_32_32_BitmapData ()
234                 {
235                         BitmapData data = new BitmapData ();
236                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
237                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
238                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
239                                 Assert.AreEqual (100, data.Height, "Height");
240                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
241                                 Assert.AreEqual (400, data.Stride, "Stride");
242                                 Assert.AreEqual (100, data.Width, "Width");
243                                 bmp.UnlockBits (data);
244                         }
245                 }
246
247                 [Test]
248                 public void LockBits_32_24_BitmapData ()
249                 {
250                         BitmapData data = new BitmapData ();
251                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
252                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
253                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
254                                 Assert.AreEqual (100, data.Height, "Height");
255                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
256                                 Assert.AreEqual (300, data.Stride, "Stride");
257                                 Assert.AreEqual (100, data.Width, "Width");
258                                 bmp.UnlockBits (data);
259                         }
260                 }
261
262                 [Test]
263                 public void LockBits_24_24_BitmapData ()
264                 {
265                         BitmapData data = new BitmapData ();
266                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
267                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
268                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
269                                 Assert.AreEqual (100, data.Height, "Height");
270                                 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
271                                 Assert.AreEqual (300, data.Stride, "Stride");
272                                 Assert.AreEqual (100, data.Width, "Width");
273                                 bmp.UnlockBits (data);
274                         }
275                 }
276
277                 [Test]
278                 public void LockBits_24_32_BitmapData ()
279                 {
280                         BitmapData data = new BitmapData ();
281                         using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
282                                 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
283                                 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
284                                 Assert.AreEqual (100, data.Height, "Height");
285                                 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
286                                 Assert.AreEqual (400, data.Stride, "Stride");
287                                 Assert.AreEqual (100, data.Width, "Width");
288                                 bmp.UnlockBits (data);
289                         }
290                 }
291
292                 [Test]
293                 public void Format1bppIndexed ()
294                 {
295                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
296                                 Color c = bmp.GetPixel (0, 0);
297                                 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
298                                 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
299                         }
300                 }
301
302                 [Test]
303                 public void Format4bppIndexed ()
304                 {
305                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
306                                 Color c = bmp.GetPixel (0, 0);
307                                 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
308                                 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
309                         }
310                 }
311
312                 [Test]
313                 public void Format8bppIndexed ()
314                 {
315                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
316                                 Color c = bmp.GetPixel (0, 0);
317                                 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
318                                 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
319                         }
320                 }
321
322                 [Test]
323                 [Category ("NotWorking")] // libgdiplus doesn't support this format
324                 public void Format16bppGrayScale ()
325                 {
326                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format16bppGrayScale)) {
327                                 // and MS GDI+ support seems quite limited too
328                                 Assert.Throws<ArgumentException> (() => bmp.GetPixel (0, 0));
329                         }
330                 }
331
332                 private void FormatTest (PixelFormat format)
333                 {
334                         bool alpha = Image.IsAlphaPixelFormat (format);
335                         int size = Image.GetPixelFormatSize (format) / 8 * 2;
336                         using (Bitmap bmp = new Bitmap (2, 1, format)) {
337                                 Color a = Color.FromArgb (128, 64, 32, 16);
338                                 Color b = Color.FromArgb (192, 96, 48, 24);
339                                 bmp.SetPixel (0, 0, a);
340                                 bmp.SetPixel (1, 0, b);
341                                 Color c = bmp.GetPixel (0, 0);
342                                 Color d = bmp.GetPixel (1, 0);
343                                 if (size == 4) {
344                                         Assert.AreEqual (255, c.A, "0,0-16bpp-A");
345                                         Assert.AreEqual (66, c.R, "0,0-16bpp-R");
346                                         if (format == PixelFormat.Format16bppRgb565) {
347                                                 Assert.AreEqual (32, c.G, "0,0-16bpp-G");
348                                         } else {
349                                                 Assert.AreEqual (33, c.G, "0,0-16bpp-G");
350                                         }
351                                         Assert.AreEqual (16, c.B, "0,0-16bpp-B");
352
353                                         Assert.AreEqual (255, d.A, "1,0-16bpp-A");
354                                         Assert.AreEqual (99, d.R, "1,0-16bpp-R");
355                                         if (format == PixelFormat.Format16bppRgb565) {
356                                                 Assert.AreEqual (48, d.G, "1,0-16bpp-G");
357                                         } else {
358                                                 Assert.AreEqual (49, d.G, "1,0-16bpp-G");
359                                         }
360                                         Assert.AreEqual (24, d.B, "1,0-16bpp-B");
361                                 } else if (alpha) {
362                                         if (format == PixelFormat.Format32bppPArgb) {
363                                                 Assert.AreEqual (a.A, c.A, "0,0-alpha-A");
364                                                 // note sure why the -1
365                                                 Assert.AreEqual (a.R - 1, c.R, "0,0-alpha-premultiplied-R");
366                                                 Assert.AreEqual (a.G - 1, c.G, "0,0-alpha-premultiplied-G");
367                                                 Assert.AreEqual (a.B - 1, c.B, "0,0-alpha-premultiplied-B");
368
369                                                 Assert.AreEqual (b.A, d.A, "1,0-alpha-A");
370                                                 // note sure why the -1
371                                                 Assert.AreEqual (b.R - 1, d.R, "1,0-alpha-premultiplied-R");
372                                                 Assert.AreEqual (b.G - 1, d.G, "1,0-alpha-premultiplied-G");
373                                                 Assert.AreEqual (b.B - 1, d.B, "1,0-alpha-premultiplied-B");
374                                         } else {
375                                                 Assert.AreEqual (a, c, "0,0-alpha");
376                                                 Assert.AreEqual (b, d, "1,0-alpha");
377                                         }
378                                 } else {
379                                         Assert.AreEqual (Color.FromArgb (255, 64, 32, 16), c, "0,0-non-alpha");
380                                         Assert.AreEqual (Color.FromArgb (255, 96, 48, 24), d, "1,0-non-alpha");
381                                 }
382                                 BitmapData bd = bmp.LockBits (new Rectangle (0, 0, 2, 1), ImageLockMode.ReadOnly, format);
383                                 try {
384                                         byte[] data = new byte[size];
385                                         Marshal.Copy (bd.Scan0, data, 0, size);
386                                         if (format == PixelFormat.Format32bppPArgb) {
387                                                 Assert.AreEqual (Math.Ceiling ((float)c.B * c.A / 255), data[0], "0.alpha-premultiplied-B");
388                                                 Assert.AreEqual (Math.Ceiling ((float)c.G * c.A / 255), data[1], "0.alpha-premultiplied-R");
389                                                 Assert.AreEqual (Math.Ceiling ((float)c.R * c.A / 255), data[2], "0.alpha-premultiplied-G");
390                                                 Assert.AreEqual (c.A, data[3], "0.alpha-A");
391                                                 Assert.AreEqual (Math.Ceiling ((float)d.B * d.A / 255), data[4], "1.alpha-premultiplied-B");
392                                                 Assert.AreEqual (Math.Ceiling ((float)d.G * d.A / 255), data[5], "1.alpha-premultiplied-R");
393                                                 Assert.AreEqual (Math.Ceiling ((float)d.R * d.A / 255), data[6], "1.alpha-premultiplied-G");
394                                                 Assert.AreEqual (d.A, data[7], "1.alpha-A");
395                                         } else if (size == 4) {
396                                                 int n = 0;
397                                                 switch (format) {
398                                                 case PixelFormat.Format16bppRgb565:
399                                                         Assert.AreEqual (2, data[n++], "0");
400                                                         Assert.AreEqual (65, data[n++], "1");
401                                                         Assert.AreEqual (131, data[n++], "2");
402                                                         Assert.AreEqual (97, data[n++], "3");
403                                                         break;
404                                                 case PixelFormat.Format16bppArgb1555:
405                                                         Assert.AreEqual (130, data[n++], "0");
406                                                         Assert.AreEqual (160, data[n++], "1");
407                                                         Assert.AreEqual (195, data[n++], "2");
408                                                         Assert.AreEqual (176, data[n++], "3");
409                                                         break;
410                                                 case PixelFormat.Format16bppRgb555:
411                                                         Assert.AreEqual (130, data[n++], "0");
412                                                         Assert.AreEqual (32, data[n++], "1");
413                                                         Assert.AreEqual (195, data[n++], "2");
414                                                         Assert.AreEqual (48, data[n++], "3");
415                                                         break;
416                                                 }
417                                         } else {
418                                                 int n = 0;
419                                                 Assert.AreEqual (c.B, data[n++], "0.B");
420                                                 Assert.AreEqual (c.G, data[n++], "0.R");
421                                                 Assert.AreEqual (c.R, data[n++], "0.G");
422                                                 if (size % 4 == 0)
423                                                         Assert.AreEqual (c.A, data[n++], "0.A");
424                                                 Assert.AreEqual (d.B, data[n++], "1.B");
425                                                 Assert.AreEqual (d.G, data[n++], "1.R");
426                                                 Assert.AreEqual (d.R, data[n++], "1.G");
427                                                 if (size % 4 == 0)
428                                                         Assert.AreEqual (d.A, data[n++], "1.A");
429                                         }
430                                 }
431                                 finally {
432                                         bmp.UnlockBits (bd);
433                                 }
434                         }
435                 }
436
437                 [Test]
438                 [Category ("NotWorking")] // libgdiplus doesn't support this format
439                 public void Format16bppArgb1555 ()
440                 {
441                         FormatTest (PixelFormat.Format16bppArgb1555);
442                 }
443
444                 [Test]
445                 [Category ("NotWorking")] // GetPixel is a few bits off
446                 public void Format16bppRgb555 ()
447                 {
448                         FormatTest (PixelFormat.Format16bppRgb555);
449                 }
450
451                 [Test]
452                 [Category ("NotWorking")] // GetPixel is a few bits off
453                 public void Format16bppRgb565 ()
454                 {
455                         FormatTest (PixelFormat.Format16bppRgb565);
456                 }
457
458                 [Test]
459                 public void Format32bppArgb ()
460                 {
461                         FormatTest (PixelFormat.Format32bppArgb);
462                 }
463
464                 [Test]
465                 [Category ("NotWorking")] // I'm not sure we're handling this format anywhere (Cairo itself use it)
466                 public void Format32bppPArgb ()
467                 {
468                         FormatTest (PixelFormat.Format32bppPArgb);
469                 }
470
471                 [Test]
472                 public void Format32bppRgb ()
473                 {
474                         FormatTest (PixelFormat.Format32bppRgb);
475                 }
476
477                 [Test]
478                 public void Format24bppRgb ()
479                 {
480                         FormatTest (PixelFormat.Format24bppRgb);
481                 }
482
483                 /* Get the output directory depending on the runtime and location*/
484                 public static string getOutSubDir()
485                 {                               
486                         string sSub, sRslt;                     
487                         
488                         if (Environment.GetEnvironmentVariable("MSNet")==null)
489                                 sSub = "mono/";
490                         else
491                                 sSub = "MSNet/";                        
492                         
493                         sRslt = Path.GetFullPath (sSub);
494                                 
495                         if (Directory.Exists(sRslt) ==  false) 
496                                 sRslt = "Test/System.Drawing/" + sSub;                                                  
497                         
498                         if (sRslt.Length > 0)
499                                 if (sRslt[sRslt.Length-1] != '\\' && sRslt[sRslt.Length-1] != '/')
500                                         sRslt += "/";                                   
501                         
502                         return sRslt;
503                 }
504                 
505                 /* Get the input directory depending on the runtime*/
506                 public static string getInFile(string file)
507                 {                               
508                         string sRslt = Path.GetFullPath ("../System.Drawing/" + file);
509                         if (!File.Exists (sRslt))
510                                 sRslt = "Test/System.Drawing/" + file;
511                         return sRslt;
512                 }
513
514                 // note: this test fails when saving (for the same reason) on Mono and MS.NET
515                 //[Test]
516                 public void MakeTransparent() 
517                 {
518                         string sInFile =   getInFile("bitmaps/maketransparent.bmp");
519                         string sOutFile =  getOutSubDir() + "transparent.bmp";
520                                                 
521                         Bitmap  bmp = new Bitmap(sInFile);
522                                         
523                         bmp.MakeTransparent();
524                         bmp.Save(sOutFile);                                                     
525                         
526                         Color color = bmp.GetPixel(1,1);                                                        
527                         Assert.AreEqual (Color.Black.R, color.R);                                                                                       
528                         Assert.AreEqual (Color.Black.G, color.G);                                                                                       
529                         Assert.AreEqual (Color.Black.B, color.B);                                                                               
530                 }
531                 
532                 [Test]
533                 public void Clone()
534                 {
535                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
536                         Rectangle rect = new Rectangle(0,0,50,50);                                              
537                         Bitmap  bmp = new Bitmap(sInFile);                      
538                         
539                         Bitmap bmpNew = bmp.Clone (rect, PixelFormat.Format32bppArgb);                                                                  
540                         Color colororg0 = bmp.GetPixel(0,0);            
541                         Color colororg50 = bmp.GetPixel(49,49);                                 
542                         Color colornew0 = bmpNew.GetPixel(0,0);         
543                         Color colornew50 = bmpNew.GetPixel(49,49);                              
544                         
545                         Assert.AreEqual (colororg0, colornew0);                                                                                 
546                         Assert.AreEqual (colororg50, colornew50);                               
547                 }       
548                 
549                 [Test]
550                 public void CloneImage()
551                 {
552                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
553                         Bitmap  bmp = new Bitmap(sInFile);                      
554                         
555                         Bitmap bmpNew = (Bitmap) bmp.Clone ();                  
556                         
557                         Assert.AreEqual (bmp.Width, bmpNew.Width);
558                         Assert.AreEqual (bmp.Height, bmpNew.Height);            
559                         Assert.AreEqual (bmp.PixelFormat, bmpNew.PixelFormat);
560                         
561                 }       
562
563                 [Test]
564                 public void Frames()
565                 {
566                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
567                         Bitmap  bmp = new Bitmap(sInFile);                                              
568                         int cnt = bmp.GetFrameCount(FrameDimension.Page);                       
569                         int active = bmp.SelectActiveFrame (FrameDimension.Page, 0);
570                         
571                         Assert.AreEqual (1, cnt);                                                               
572                         Assert.AreEqual (0, active);                                                                                    
573                 }
574                 
575                 [Test]
576                 public void FileDoesNotExists ()
577                 {                       
578                         Assert.Throws<ArgumentException> (() => new Bitmap ("FileDoesNotExists.jpg"));                  
579                 }
580
581                 static string ByteArrayToString(byte[] arrInput)
582                 {
583                         int i;
584                         StringBuilder sOutput = new StringBuilder(arrInput.Length);
585                         for (i=0;i < arrInput.Length -1; i++) 
586                         {
587                                 sOutput.Append(arrInput[i].ToString("X2"));
588                         }
589                         return sOutput.ToString();
590                 }
591
592
593                 public string RotateBmp (Bitmap src, RotateFlipType rotate)
594                 {                       
595                         int width = 150, height = 150, index = 0;                       
596                         byte[] pixels = new byte [width * height * 3];
597                         Bitmap bmp_rotate;
598                         byte[] hash;
599                         Color clr;
600
601                         bmp_rotate = src.Clone (new RectangleF (0,0, width, height), PixelFormat.Format32bppArgb);      
602                         bmp_rotate.RotateFlip (rotate);                 
603
604                         for (int y = 0; y < height; y++) {
605                                 for (int x = 0; x < width; x++) {
606                                         clr = bmp_rotate.GetPixel (x,y);
607                                         pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++]  = clr.B;     
608                                 }                               
609                         }
610                 
611                         hash = new MD5CryptoServiceProvider().ComputeHash (pixels);
612                         return ByteArrayToString (hash);
613                 }
614                 public string RotateIndexedBmp (Bitmap src, RotateFlipType type)
615                 {
616                         int pixels_per_byte;
617
618                         switch (src.PixelFormat)
619                         {
620                                 case PixelFormat.Format1bppIndexed: pixels_per_byte = 8; break;
621                                 case PixelFormat.Format4bppIndexed: pixels_per_byte = 2; break;
622                                 case PixelFormat.Format8bppIndexed: pixels_per_byte = 1; break;
623
624                                 default: throw new Exception("Cannot pass a bitmap of format " + src.PixelFormat + " to RotateIndexedBmp");
625                         }
626
627                         Bitmap test = src.Clone () as Bitmap;
628
629                         test.RotateFlip (type);
630
631                         BitmapData data = null;
632                         byte[] pixel_data;
633
634                         try
635                         {
636                                 data = test.LockBits (new Rectangle (0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat);
637
638                                 int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte;
639                                 pixel_data = new byte[data.Height * scan_size];
640
641                                 for (int y=0; y < data.Height; y++) {
642                                         IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64 ());
643                                         int dest_offset = y * scan_size;
644                                         for (int x=0; x < scan_size; x++)
645                                                 pixel_data[dest_offset + x] = Marshal.ReadByte (src_ptr, x);
646                                 }
647                         }
648                         finally
649                         {
650                                 if (test != null) {
651                                         if (data != null)
652                                                 try { test.UnlockBits(data); } catch {}
653
654                                         try { test.Dispose(); } catch {}
655                                 }
656                         }
657
658                         if (pixel_data == null)
659                                 return "--ERROR--";
660
661                         byte[] hash = new MD5CryptoServiceProvider().ComputeHash (pixel_data);
662                         return ByteArrayToString (hash);
663                 }
664                 
665                 
666                 /*
667                         Rotate bitmap in diffent ways, and check the result
668                         pixels using MD5
669                 */
670                 [Test]
671                 public void Rotate()
672                 {
673                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");     
674                         Bitmap  bmp = new Bitmap(sInFile);
675                         
676                         Assert.AreEqual ("312958A3C67402E1299413794988A3", RotateBmp (bmp, RotateFlipType.Rotate90FlipNone));   
677                         Assert.AreEqual ("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp (bmp, RotateFlipType.Rotate180FlipNone));
678                         Assert.AreEqual ("15AD2ADBDC7090C0EC744D0F7ACE2F", RotateBmp (bmp, RotateFlipType.Rotate270FlipNone));
679                         Assert.AreEqual ("2E10FEC1F4FD64ECC51D7CE68AEB18", RotateBmp (bmp, RotateFlipType.RotateNoneFlipX));
680                         Assert.AreEqual ("E63204779B566ED01162B90B49BD9E", RotateBmp (bmp, RotateFlipType.Rotate90FlipX));
681                         Assert.AreEqual ("B1ECB17B5093E13D04FF55CFCF7763", RotateBmp (bmp, RotateFlipType.Rotate180FlipX));
682                         Assert.AreEqual ("71A173882C16755D86F4BC26532374", RotateBmp (bmp, RotateFlipType.Rotate270FlipX));
683
684                 }
685
686                 /*
687                         Rotate 1- and 4-bit bitmaps in different ways and check the
688                         resulting pixels using MD5
689                 */
690                 [Test]
691                 public void Rotate1bit4bit()
692                 {
693                         if ((Environment.OSVersion.Platform != (PlatformID)4)
694                          && (Environment.OSVersion.Platform != (PlatformID)128))
695                                 Assert.Ignore("This does not work with Microsoft's GDIPLUS.DLL due to off-by-1 errors in their GdipBitmapRotateFlip function.");
696
697                         string[] files = {
698                                            getInFile ("bitmaps/1bit.png"),
699                                            getInFile ("bitmaps/4bit.png")
700                                          };
701
702                         StringBuilder md5s = new StringBuilder();
703
704                         foreach (string file in files)
705                                 using (Bitmap bmp = new Bitmap(file))
706                                         foreach (RotateFlipType type in Enum.GetValues (typeof(RotateFlipType)))
707                                                 md5s.Append (RotateIndexedBmp (bmp, type));
708
709                         using (StreamWriter writer = new StreamWriter("/tmp/md5s.txt"))
710                                 writer.WriteLine(md5s);
711
712                         Assert.AreEqual (
713                                 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit RotateNoneFlipNone
714                                 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit Rotate180FlipXY
715                                 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate90FlipNone
716                                 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate270FlipXY
717                                 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit Rotate180FlipNone
718                                 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit RotateNoneFlipXY
719                                 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate270FlipNone
720                                 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate90FlipXY
721                                 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit RotateNoneFlipX
722                                 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit Rotate180FlipY
723                                 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate90FlipX
724                                 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate270FlipY
725                                 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit Rotate180FlipX
726                                 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit RotateNoneFlipY
727                                 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate270FlipX
728                                 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate90FlipY
729                                 "3CC874B571902366AACED5D619E87D" + // 4-bit RotateNoneFlipNone
730                                 "3CC874B571902366AACED5D619E87D" + // 4-bit Rotate180FlipXY
731                                 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate90FlipNone
732                                 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate270FlipXY
733                                 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit Rotate180FlipNone
734                                 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit RotateNoneFlipXY
735                                 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate270FlipNone
736                                 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate90FlipXY
737                                 "545876C99ACF833E69FBFFBF436034" + // 4-bit RotateNoneFlipX
738                                 "545876C99ACF833E69FBFFBF436034" + // 4-bit Rotate180FlipY
739                                 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate90FlipX
740                                 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate270FlipY
741                                 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit Rotate180FlipX
742                                 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit RotateNoneFlipY
743                                 "B6B6245796C836923ABAABDF368B29" + // 4-bit Rotate270FlipX
744                                 "B6B6245796C836923ABAABDF368B29",  // 4-bit Rotate90FlipY
745                                 md5s.ToString ());
746                 }
747
748                 private Bitmap CreateBitmap (int width, int height, PixelFormat fmt)
749                 {
750                         Bitmap bmp = new Bitmap (width, height, fmt);
751                         using (Graphics gr = Graphics.FromImage (bmp)) {
752                                 Color c = Color.FromArgb (255, 100, 200, 250);
753                                 for (int x = 1; x < 80; x++) {
754                                         bmp.SetPixel (x, 1, c);
755                                         bmp.SetPixel (x, 2, c);
756                                         bmp.SetPixel (x, 78, c);
757                                         bmp.SetPixel (x, 79, c);
758                                 }
759                                 for (int y = 3; y < 78; y++) {
760                                         bmp.SetPixel (1, y, c);
761                                         bmp.SetPixel (2, y, c);
762                                         bmp.SetPixel (78, y, c);
763                                         bmp.SetPixel (79, y, c);
764                                 }
765                         }
766                         return bmp;
767                 }
768
769                 private byte[] HashPixels (Bitmap bmp)
770                 {
771                         int len = bmp.Width * bmp.Height * 4;
772                         int index = 0;
773                         byte[] pixels = new byte [len];
774
775                         for (int y = 0; y < bmp.Height; y++) {
776                                 for (int x = 0; x < bmp.Width; x++) {
777                                         Color clr = bmp.GetPixel (x, y);
778                                         pixels[index++] = clr.R;
779                                         pixels[index++] = clr.G;
780                                         pixels[index++] = clr.B;
781                                 }
782                         }
783                         return MD5.Create ().ComputeHash (pixels);
784                 }
785
786                 private byte[] HashLock (Bitmap bmp, int width, int height, PixelFormat fmt, ImageLockMode mode)
787                 {
788                         int len = bmp.Width * bmp.Height * 4;
789                         byte[] pixels = new byte[len];
790                         BitmapData bd = bmp.LockBits (new Rectangle (0, 0, width, height), mode, fmt);
791                         try {
792                                 int index = 0;
793                                 int bbps = Image.GetPixelFormatSize (fmt);
794                                 long pos = bd.Scan0.ToInt64 ();
795                                 byte[] btv = new byte[1];
796                                 for (int y = 0; y < bd.Height; y++) {
797                                         for (int x = 0; x < bd.Width; x++) {
798
799                                                 /* Read the pixels*/
800                                                 for (int bt = 0; bt < bbps / 8; bt++, index++) {
801                                                         long cur = pos;
802                                                         cur += y * bd.Stride;
803                                                         cur += x * bbps / 8;
804                                                         cur += bt;
805                                                         Marshal.Copy ((IntPtr) cur, btv, 0, 1);
806                                                         pixels[index] = btv[0];
807
808                                                         /* Make change of all the colours = 250 to 10*/
809                                                         if (btv[0] == 250) {
810                                                                 btv[0] = 10;
811                                                                 Marshal.Copy (btv, 0, (IntPtr) cur, 1);
812                                                         }
813                                                 }
814                                         }
815                                 }
816
817                                 for (int i = index; i < len; i++)
818                                         pixels[index] = 0;
819                         }
820                         finally {
821                                 bmp.UnlockBits (bd);
822                         }
823                         return MD5.Create ().ComputeHash (pixels);
824                 }
825
826                 /*
827                         Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns
828                         firsts, changes them, and then using GetPixel does another check of the changes.
829                         The results match the .Net framework
830                 */
831                 private static byte[] DefaultBitmapHash = new byte[] { 0xD8, 0xD3, 0x68, 0x9C, 0x86, 0x7F, 0xB6, 0xA0, 0x76, 0xD6, 0x00, 0xEF, 0xFF, 0xE5, 0x8E, 0x1B };
832                 private static byte[] FinalWholeBitmapHash = new byte[] { 0x5F, 0x52, 0x98, 0x37, 0xE3, 0x94, 0xE1, 0xA6, 0x06, 0x6C, 0x5B, 0xF1, 0xA9, 0xC2, 0xA9, 0x43 };
833
834                 [Test]
835                 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Whole ()
836                 {
837                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
838                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
839                                 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
840                                 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
841                                 Assert.AreEqual (expected, actual, "Full-Format32bppArgb");
842                                 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
843                         }
844                 }
845
846                 [Test]
847                 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Whole ()
848                 {
849                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
850                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
851                                 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
852                                 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
853                                 Assert.AreEqual (expected, actual, "Full-Format32bppPArgb");
854                                 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
855                         }
856                 }
857
858                 [Test]
859                 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Whole ()
860                 {
861                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
862                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
863                                 byte[] expected = { 0xC0, 0x28, 0xB5, 0x2E, 0x86, 0x90, 0x6F, 0x37, 0x09, 0x5F, 0x49, 0xA4, 0x91, 0xDA, 0xEE, 0xB9 };
864                                 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
865                                 Assert.AreEqual (expected, actual, "Full-Format32bppRgb");
866                                 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
867                         }
868                 }
869
870                 [Test]
871                 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Whole ()
872                 {
873                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
874                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
875                                 byte[] expected = { 0xA7, 0xB2, 0x50, 0x04, 0x11, 0x12, 0x64, 0x68, 0x6B, 0x7D, 0x2F, 0x6E, 0x69, 0x24, 0xCB, 0x14 };
876                                 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
877                                 Assert.AreEqual (expected, actual, "Full-Format24bppRgb");
878                                 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
879                         }
880                 }
881
882                 private static byte[] FinalPartialBitmapHash = new byte[] { 0xED, 0xD8, 0xDC, 0x9B, 0x44, 0x00, 0x22, 0x9B, 0x07, 0x06, 0x4A, 0x21, 0x70, 0xA7, 0x31, 0x1D };
883
884                 [Test]
885                 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Partial ()
886                 {
887                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
888                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
889                                 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
890                                 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
891                                 Assert.AreEqual (expected, actual, "Partial-Format32bppArgb");
892                                 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
893                         }
894                 }
895
896                 [Test]
897                 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Partial ()
898                 {
899                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
900                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
901                                 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
902                                 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
903                                 Assert.AreEqual (expected, actual, "Partial-Format32bppPArgb");
904                                 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
905                         }
906                 }
907
908                 [Test]
909                 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Partial ()
910                 {
911                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
912                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
913                                 byte[] expected = { 0x72, 0x33, 0x09, 0x67, 0x53, 0x65, 0x38, 0xF9, 0xE4, 0x58, 0xE1, 0x0A, 0xAA, 0x6A, 0xCC, 0xB8 };
914                                 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
915                                 Assert.AreEqual (expected, actual, "Partial-Format32bppRgb");
916                                 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
917                         }
918                 }
919
920                 [Test]
921                 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Partial ()
922                 {
923                         using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
924                                 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
925                                 byte[] expected = { 0x4D, 0x39, 0x21, 0x88, 0xC2, 0x17, 0x14, 0x5F, 0x89, 0x9E, 0x02, 0x75, 0xF3, 0x64, 0xD8, 0xF0 };
926                                 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
927                                 Assert.AreEqual (expected, actual, "Partial-Format24bppRgb");
928                                 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
929                         }
930                 }
931
932                 /*
933                         Tests the LockBitmap and UnlockBitmap functions, specifically the copying
934                         of bitmap data in the directions indicated by the ImageLockMode.
935                 */
936                 [Test]
937                 public void LockUnlockBitmap ()
938                 {
939                         BitmapData data;
940                         int pixel_value;
941                         Color pixel_colour;
942
943                         Color red  = Color.FromArgb (Color.Red.A,  Color.Red.R,  Color.Red.G,  Color.Red.B);
944                         Color blue = Color.FromArgb (Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B);
945
946                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppRgb)) {
947                                 bmp.SetPixel (0, 0, red);
948                                 pixel_colour = bmp.GetPixel (0, 0);
949                                 Assert.AreEqual (red, pixel_colour, "Set/Get-Red");
950
951                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
952                                 try {
953                                         pixel_value = Marshal.ReadByte (data.Scan0, 0);
954                                         pixel_value |= Marshal.ReadByte (data.Scan0, 1) << 8;
955                                         pixel_value |= Marshal.ReadByte (data.Scan0, 2) << 16;
956                                         pixel_value |= Marshal.ReadByte (data.Scan0, 3) << 24;
957
958                                         pixel_colour = Color.FromArgb (pixel_value);
959                                         // Disregard alpha information in the test
960                                         pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
961                                         Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Original");
962
963                                         // write blue but we're locked in read-only...
964                                         Marshal.WriteByte (data.Scan0, 0, blue.B);
965                                         Marshal.WriteByte (data.Scan0, 1, blue.G);
966                                         Marshal.WriteByte (data.Scan0, 2, blue.R);
967                                         Marshal.WriteByte (data.Scan0, 3, blue.A);
968                                 }
969                                 finally {
970                                         bmp.UnlockBits (data);
971                                         pixel_colour = bmp.GetPixel (0, 0);
972                                         // Disregard alpha information in the test
973                                         pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
974                                         // ...so we still read red after unlocking
975                                         Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Unlocked");
976                                 }
977
978                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
979                                 try {
980                                         // write blue
981                                         Marshal.WriteByte (data.Scan0, 0, blue.B);
982                                         Marshal.WriteByte (data.Scan0, 1, blue.G);
983                                         Marshal.WriteByte (data.Scan0, 2, blue.R);
984                                         Marshal.WriteByte (data.Scan0, 3, blue.A);
985                                 }
986                                 finally {
987                                         bmp.UnlockBits (data);
988                                         pixel_colour = bmp.GetPixel (0, 0);
989                                         // Disregard alpha information in the test
990                                         pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
991                                         // read blue
992                                         Assert.AreEqual (blue, pixel_colour, "32RGB/32ARGB-ReadWrite-Blue-Unlock");
993                                 }
994                         }
995
996                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppArgb)) {
997                                 bmp.SetPixel (0, 0, red);
998
999                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
1000                                 try {
1001                                         byte b = Marshal.ReadByte (data.Scan0, 0);
1002                                         byte g = Marshal.ReadByte (data.Scan0, 1);
1003                                         byte r = Marshal.ReadByte (data.Scan0, 2);
1004                                         pixel_colour = Color.FromArgb (red.A, r, g, b);
1005                                         Assert.AreEqual (red, pixel_colour, "32ARGB/24RGB-ReadOnly-Red-Original");
1006                                         // write blue but we're locked in read-only...
1007                                         Marshal.WriteByte (data.Scan0, 0, blue.B);
1008                                         Marshal.WriteByte (data.Scan0, 1, blue.G);
1009                                         Marshal.WriteByte (data.Scan0, 2, blue.R);
1010                                 }
1011                                 finally {
1012                                         bmp.UnlockBits (data);
1013                                         // ...so we still read red after unlocking
1014                                         Assert.AreEqual (red, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadOnly-Red-Unlock");
1015                                 }
1016
1017                                 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
1018                                 try {
1019                                         // write blue
1020                                         Marshal.WriteByte (data.Scan0, 0, blue.B);
1021                                         Marshal.WriteByte (data.Scan0, 1, blue.G);
1022                                         Marshal.WriteByte (data.Scan0, 2, blue.R);
1023                                 }
1024                                 finally {
1025                                         bmp.UnlockBits (data);
1026                                         // read blue
1027                                         Assert.AreEqual (blue, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadWrite-Blue-Unlock");
1028                                 }
1029                         }
1030                 }
1031                 [Test]
1032                 public void DefaultFormat1 ()
1033                 {
1034                         using (Bitmap bmp = new Bitmap (20, 20)) {
1035                                 Assert.AreEqual (ImageFormat.MemoryBmp, bmp.RawFormat);
1036                         }
1037                 }
1038
1039                 [Test]
1040                 public void DefaultFormat2 ()
1041                 {
1042                         string filename =  Path.GetTempFileName ();
1043                         using (Bitmap bmp = new Bitmap (20, 20)) {
1044                                 bmp.Save (filename);
1045                         }
1046
1047                         using (Bitmap other = new Bitmap (filename)) {
1048                                 Assert.AreEqual (ImageFormat.Png, other.RawFormat);
1049                         }
1050                         File.Delete (filename);
1051                 }
1052
1053                 [Test]
1054                 public void BmpDataStride1 ()
1055                 {
1056                         Bitmap bmp = new Bitmap (184, 184, PixelFormat.Format1bppIndexed);
1057                         BitmapData data = bmp.LockBits (new Rectangle (0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
1058                         try {
1059                                 Assert.AreEqual (24, data.Stride);
1060                         } finally {
1061                                 bmp.UnlockBits (data);
1062                                 bmp.Dispose ();
1063                         }
1064                 }
1065
1066                 private Stream Serialize (object o)
1067                 {
1068                         MemoryStream ms = new MemoryStream ();
1069                         IFormatter formatter = new BinaryFormatter ();
1070                         formatter.Serialize (ms, o);
1071                         ms.Position = 0;
1072                         return ms;
1073                 }
1074
1075                 private object Deserialize (Stream s)
1076                 {
1077                         return new BinaryFormatter ().Deserialize (s);
1078                 }
1079
1080                 [Test]
1081                 public void Serialize_Icon ()
1082                 {
1083                         // this cause a problem with resgen, see http://bugzilla.ximian.com/show_bug.cgi?id=80565
1084                         string filename = getInFile ("bitmaps/16x16x16.ico");
1085                         using (Bitmap icon = new Bitmap (filename)) {
1086                                 using (Stream s = Serialize (icon)) {
1087                                         using (Bitmap copy = (Bitmap)Deserialize (s)) {
1088                                                 Assert.AreEqual (icon.Height, copy.Height, "Height");
1089                                                 Assert.AreEqual (icon.Width, copy.Width, "Width");
1090                                                 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1091                                                 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1092                                                 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1093                                         }
1094                                 }
1095                         }
1096                 }
1097
1098 #if !NETCOREAPP2_0
1099                 private Stream SoapSerialize (object o)
1100                 {
1101                         MemoryStream ms = new MemoryStream ();
1102                         IFormatter formatter = new SoapFormatter ();
1103                         formatter.Serialize (ms, o);
1104                         ms.Position = 0;
1105                         return ms;
1106                 }
1107
1108                 private object SoapDeserialize (Stream s)
1109                 {
1110                         return new SoapFormatter ().Deserialize (s);
1111                 }
1112
1113                 [Test]
1114                 public void SoapSerialize_Icon ()
1115                 {
1116                         string filename = getInFile ("bitmaps/16x16x16.ico");
1117                         using (Bitmap icon = new Bitmap (filename)) {
1118                                 using (Stream s = SoapSerialize (icon)) {
1119                                         using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1120                                                 Assert.AreEqual (icon.Height, copy.Height, "Height");
1121                                                 Assert.AreEqual (icon.Width, copy.Width, "Width");
1122                                                 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1123                                                 Assert.AreEqual (16, icon.Palette.Entries.Length, "icon Palette");
1124                                                 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1125                                                 Assert.AreEqual (0, copy.Palette.Entries.Length, "copy Palette");
1126                                                 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1127                                         }
1128                                 }
1129                         }
1130                 }
1131
1132                 [Test]
1133                 public void SoapSerialize_Bitmap8 ()
1134                 {
1135                         string filename = getInFile ("bitmaps/almogaver8bits.bmp");
1136                         using (Bitmap bmp = new Bitmap (filename)) {
1137                                 using (Stream s = SoapSerialize (bmp)) {
1138                                         using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1139                                                 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1140                                                 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1141                                                 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1142                                                 Assert.AreEqual (256, copy.Palette.Entries.Length, "Palette");
1143                                                 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1144                                         }
1145                                 }
1146                         }
1147                 }
1148
1149                 [Test]
1150                 public void SoapSerialize_Bitmap24 ()
1151                 {
1152                         string filename = getInFile ("bitmaps/almogaver24bits.bmp");
1153                         using (Bitmap bmp = new Bitmap (filename)) {
1154                                 using (Stream s = SoapSerialize (bmp)) {
1155                                         using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1156                                                 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1157                                                 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1158                                                 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1159                                                 Assert.AreEqual (bmp.Palette.Entries.Length, copy.Palette.Entries.Length, "Palette");
1160                                                 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1161                                         }
1162                                 }
1163                         }
1164                 }
1165 #endif
1166
1167                 [Test]
1168                 [Category ("NotWorking")]       // http://bugzilla.ximian.com/show_bug.cgi?id=80558
1169                 public void XmlSerialize ()
1170                 {
1171                         new XmlSerializer (typeof (Bitmap));
1172                 }
1173
1174                 static int[] palette1 = {
1175                         -16777216,
1176                         -1,
1177                 };
1178
1179                 [Test]
1180                 public void Format1bppIndexed_Palette ()
1181                 {
1182                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
1183                                 ColorPalette pal = bmp.Palette;
1184                                 Assert.AreEqual (2, pal.Entries.Length, "Length");
1185                                 for (int i = 0; i < pal.Entries.Length; i++) {
1186                                         Assert.AreEqual (palette1[i], pal.Entries[i].ToArgb (), i.ToString ());
1187                                 }
1188                                 Assert.AreEqual (2, pal.Flags, "Flags");
1189                         }
1190                 }
1191
1192                 static int[] palette16 = {
1193                         -16777216,
1194                         -8388608,
1195                         -16744448,
1196                         -8355840,
1197                         -16777088,
1198                         -8388480,
1199                         -16744320,
1200                         -8355712,
1201                         -4144960,
1202                         -65536,
1203                         -16711936,
1204                         -256,
1205                         -16776961,
1206                         -65281,
1207                         -16711681,
1208                         -1,
1209                 };
1210
1211                 [Test]
1212                 public void Format4bppIndexed_Palette ()
1213                 {
1214                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
1215                                 ColorPalette pal = bmp.Palette;
1216                                 Assert.AreEqual (16, pal.Entries.Length, "Length");
1217                                 for (int i = 0; i < pal.Entries.Length; i++) {
1218                                         Assert.AreEqual (palette16 [i], pal.Entries[i].ToArgb (), i.ToString ());
1219                                 }
1220                                 Assert.AreEqual (0, pal.Flags, "Flags");
1221                         }
1222                 }
1223
1224                 static int[] palette256 = {
1225                         -16777216,
1226                         -8388608,
1227                         -16744448,
1228                         -8355840,
1229                         -16777088,
1230                         -8388480,
1231                         -16744320,
1232                         -8355712,
1233                         -4144960,
1234                         -65536,
1235                         -16711936,
1236                         -256,
1237                         -16776961,
1238                         -65281,
1239                         -16711681,
1240                         -1,
1241                         0,
1242                         0,
1243                         0,
1244                         0,
1245                         0,
1246                         0,
1247                         0,
1248                         0,
1249                         0,
1250                         0,
1251                         0,
1252                         0,
1253                         0,
1254                         0,
1255                         0,
1256                         0,
1257                         0,
1258                         0,
1259                         0,
1260                         0,
1261                         0,
1262                         0,
1263                         0,
1264                         0,
1265                         -16777216,
1266                         -16777165,
1267                         -16777114,
1268                         -16777063,
1269                         -16777012,
1270                         -16776961,
1271                         -16764160,
1272                         -16764109,
1273                         -16764058,
1274                         -16764007,
1275                         -16763956,
1276                         -16763905,
1277                         -16751104,
1278                         -16751053,
1279                         -16751002,
1280                         -16750951,
1281                         -16750900,
1282                         -16750849,
1283                         -16738048,
1284                         -16737997,
1285                         -16737946,
1286                         -16737895,
1287                         -16737844,
1288                         -16737793,
1289                         -16724992,
1290                         -16724941,
1291                         -16724890,
1292                         -16724839,
1293                         -16724788,
1294                         -16724737,
1295                         -16711936,
1296                         -16711885,
1297                         -16711834,
1298                         -16711783,
1299                         -16711732,
1300                         -16711681,
1301                         -13434880,
1302                         -13434829,
1303                         -13434778,
1304                         -13434727,
1305                         -13434676,
1306                         -13434625,
1307                         -13421824,
1308                         -13421773,
1309                         -13421722,
1310                         -13421671,
1311                         -13421620,
1312                         -13421569,
1313                         -13408768,
1314                         -13408717,
1315                         -13408666,
1316                         -13408615,
1317                         -13408564,
1318                         -13408513,
1319                         -13395712,
1320                         -13395661,
1321                         -13395610,
1322                         -13395559,
1323                         -13395508,
1324                         -13395457,
1325                         -13382656,
1326                         -13382605,
1327                         -13382554,
1328                         -13382503,
1329                         -13382452,
1330                         -13382401,
1331                         -13369600,
1332                         -13369549,
1333                         -13369498,
1334                         -13369447,
1335                         -13369396,
1336                         -13369345,
1337                         -10092544,
1338                         -10092493,
1339                         -10092442,
1340                         -10092391,
1341                         -10092340,
1342                         -10092289,
1343                         -10079488,
1344                         -10079437,
1345                         -10079386,
1346                         -10079335,
1347                         -10079284,
1348                         -10079233,
1349                         -10066432,
1350                         -10066381,
1351                         -10066330,
1352                         -10066279,
1353                         -10066228,
1354                         -10066177,
1355                         -10053376,
1356                         -10053325,
1357                         -10053274,
1358                         -10053223,
1359                         -10053172,
1360                         -10053121,
1361                         -10040320,
1362                         -10040269,
1363                         -10040218,
1364                         -10040167,
1365                         -10040116,
1366                         -10040065,
1367                         -10027264,
1368                         -10027213,
1369                         -10027162,
1370                         -10027111,
1371                         -10027060,
1372                         -10027009,
1373                         -6750208,
1374                         -6750157,
1375                         -6750106,
1376                         -6750055,
1377                         -6750004,
1378                         -6749953,
1379                         -6737152,
1380                         -6737101,
1381                         -6737050,
1382                         -6736999,
1383                         -6736948,
1384                         -6736897,
1385                         -6724096,
1386                         -6724045,
1387                         -6723994,
1388                         -6723943,
1389                         -6723892,
1390                         -6723841,
1391                         -6711040,
1392                         -6710989,
1393                         -6710938,
1394                         -6710887,
1395                         -6710836,
1396                         -6710785,
1397                         -6697984,
1398                         -6697933,
1399                         -6697882,
1400                         -6697831,
1401                         -6697780,
1402                         -6697729,
1403                         -6684928,
1404                         -6684877,
1405                         -6684826,
1406                         -6684775,
1407                         -6684724,
1408                         -6684673,
1409                         -3407872,
1410                         -3407821,
1411                         -3407770,
1412                         -3407719,
1413                         -3407668,
1414                         -3407617,
1415                         -3394816,
1416                         -3394765,
1417                         -3394714,
1418                         -3394663,
1419                         -3394612,
1420                         -3394561,
1421                         -3381760,
1422                         -3381709,
1423                         -3381658,
1424                         -3381607,
1425                         -3381556,
1426                         -3381505,
1427                         -3368704,
1428                         -3368653,
1429                         -3368602,
1430                         -3368551,
1431                         -3368500,
1432                         -3368449,
1433                         -3355648,
1434                         -3355597,
1435                         -3355546,
1436                         -3355495,
1437                         -3355444,
1438                         -3355393,
1439                         -3342592,
1440                         -3342541,
1441                         -3342490,
1442                         -3342439,
1443                         -3342388,
1444                         -3342337,
1445                         -65536,
1446                         -65485,
1447                         -65434,
1448                         -65383,
1449                         -65332,
1450                         -65281,
1451                         -52480,
1452                         -52429,
1453                         -52378,
1454                         -52327,
1455                         -52276,
1456                         -52225,
1457                         -39424,
1458                         -39373,
1459                         -39322,
1460                         -39271,
1461                         -39220,
1462                         -39169,
1463                         -26368,
1464                         -26317,
1465                         -26266,
1466                         -26215,
1467                         -26164,
1468                         -26113,
1469                         -13312,
1470                         -13261,
1471                         -13210,
1472                         -13159,
1473                         -13108,
1474                         -13057,
1475                         -256,
1476                         -205,
1477                         -154,
1478                         -103,
1479                         -52,
1480                         -1,
1481                 };
1482
1483                 [Test]
1484                 public void Format8bppIndexed_Palette ()
1485                 {
1486                         using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
1487                                 ColorPalette pal = bmp.Palette;
1488                                 Assert.AreEqual (256, pal.Entries.Length, "Length");
1489                                 for (int i = 0; i < pal.Entries.Length; i++) {
1490                                         Assert.AreEqual (palette256[i], pal.Entries[i].ToArgb (), i.ToString ());
1491                                 }
1492                                 Assert.AreEqual (4, pal.Flags, "Flags");
1493                         }
1494                 }
1495
1496                 [Test]
1497                 public void XmlSerialization ()
1498                 {
1499                         new XmlSerializer (typeof (Bitmap));
1500                 }
1501
1502                 [Test]
1503                 public void BitmapImageCtor ()
1504                 {
1505                         Assert.Throws<NullReferenceException> (() => new Bitmap ((Image) null));
1506                 }
1507
1508                 [Test]
1509                 public void BitmapImageSizeCtor ()
1510                 {
1511                         Assert.Throws<ArgumentException> (() => new Bitmap ((Image) null, Size.Empty));
1512                 }
1513
1514                 [Test]
1515                 public void BitmapImageIntIntCtor ()
1516                 {
1517                         Assert.Throws<ArgumentException> (() => new Bitmap ((Image) null, Int32.MinValue, Int32.MaxValue));
1518                 }
1519
1520                 [Test]
1521                 public void BitmapIntIntCtor ()
1522                 {
1523                         Assert.Throws<ArgumentException> (() => new Bitmap (Int32.MinValue, Int32.MaxValue));
1524                 }
1525
1526                 [Test]
1527                 public void BitmapIntIntGraphicCtor ()
1528                 {
1529                         Assert.Throws<ArgumentNullException> (() => new Bitmap (1, 1, null));
1530                 }
1531
1532                 [Test]
1533                 public void BitmapIntIntPixelFormatCtor ()
1534                 {
1535                         Assert.Throws<ArgumentException> (() => new Bitmap (Int32.MinValue, Int32.MaxValue, PixelFormat.Format1bppIndexed));
1536                 }
1537
1538                 [Test]
1539                 public void BitmapStreamCtor ()
1540                 {
1541                         Assert.Throws<ArgumentException> (() => new Bitmap ((Stream) null));
1542                 }
1543
1544                 [Test]
1545                 public void BitmapStreamBoolCtor ()
1546                 {
1547                         Assert.Throws<ArgumentException> (() => new Bitmap ((Stream) null, true));
1548                 }
1549
1550                 [Test]
1551                 public void BitmapStringCtor ()
1552                 {
1553                         Assert.Throws<ArgumentNullException> (() => new Bitmap ((string) null));
1554                 }
1555
1556                 [Test]
1557                 public void BitmapStringBoolCtor ()
1558                 {
1559                         Assert.Throws<ArgumentNullException> (() => new Bitmap ((string) null, false));
1560                 }
1561
1562                 [Test]
1563                 public void BitmapTypeStringCtor1 ()
1564                 {
1565                         Assert.Throws<NullReferenceException> (() => new Bitmap ((Type) null, "mono"));
1566                 }
1567
1568                 [Test]
1569                 public void BitmapTypeStringCtor2 ()
1570                 {
1571                         Assert.Throws<ArgumentException> (() => new Bitmap (typeof (Bitmap), null));
1572                 }
1573
1574                 private void SetResolution (float x, float y)
1575                 {
1576                         using (Bitmap bmp = new Bitmap (1, 1)) {
1577                                 bmp.SetResolution (x, y);
1578                         }
1579                 }
1580
1581                 [Test]
1582                 public void SetResolution_Zero ()
1583                 {
1584                         Assert.Throws<ArgumentException> (() => SetResolution (0.0f, 0.0f));
1585                 }
1586
1587                 [Test]
1588                 public void SetResolution_Negative_X ()
1589                 {
1590                         Assert.Throws<ArgumentException> (() => SetResolution (-1.0f, 1.0f));
1591                 }
1592
1593                 [Test]
1594                 public void SetResolution_Negative_Y ()
1595                 {
1596                         Assert.Throws<ArgumentException> (() => SetResolution (1.0f, -1.0f));
1597                 }
1598
1599                 [Test]
1600                 public void SetResolution_MaxValue ()
1601                 {
1602                         SetResolution (Single.MaxValue, Single.MaxValue);
1603                 }
1604
1605                 [Test]
1606                 public void SetResolution_PositiveInfinity ()
1607                 {
1608                         SetResolution (Single.PositiveInfinity, Single.PositiveInfinity);
1609                 }
1610
1611                 [Test]
1612                 public void SetResolution_NaN ()
1613                 {
1614                         Assert.Throws<ArgumentException> (() => SetResolution (Single.NaN, Single.NaN));
1615                 }
1616
1617                 [Test]
1618                 public void SetResolution_NegativeInfinity ()
1619                 {
1620                         Assert.Throws<ArgumentException> (() => SetResolution (Single.NegativeInfinity, Single.NegativeInfinity));
1621                 }
1622         }
1623
1624         [TestFixture]
1625         public class BitmapFullTrustTest {
1626                 [Test]
1627                 public void BitmapIntIntIntPixelFormatIntPtrCtor ()
1628                 {
1629                         new Bitmap (1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero);
1630                 }
1631
1632                 // BitmapFromHicon## is *almost* the same as IconTest.Icon##ToBitmap except
1633                 // for the Flags property
1634
1635                 private void HiconTest (string msg, Bitmap b, int size)
1636                 {
1637                         Assert.AreEqual (PixelFormat.Format32bppArgb, b.PixelFormat, msg + ".PixelFormat");
1638                         // unlike the GDI+ icon decoder the palette isn't kept
1639                         Assert.AreEqual (0, b.Palette.Entries.Length, msg + ".Palette");
1640                         Assert.AreEqual (size, b.Height, msg + ".Height");
1641                         Assert.AreEqual (size, b.Width, msg + ".Width");
1642                         Assert.IsTrue (b.RawFormat.Equals (ImageFormat.MemoryBmp), msg + ".RawFormat");
1643                         Assert.AreEqual (335888, b.Flags, msg + ".Flags");
1644                 }
1645
1646                 [Test]
1647                 public void Hicon16 ()
1648                 {
1649                         IntPtr hicon;
1650                         int size;
1651                         using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/16x16x16.ico"))) {
1652                                 size = icon.Width;
1653                                 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1654                                         HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1655                                         hicon = bitmap.GetHicon ();
1656                                 }
1657                         }
1658                         using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1659                                 // hicon survives bitmap and icon disposal
1660                                 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1661                         }
1662                 }
1663
1664                 [Test]
1665                 public void Hicon32 ()
1666                 {
1667                         IntPtr hicon;
1668                         int size;
1669                         using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/32x32x16.ico"))) {
1670                                 size = icon.Width;
1671                                 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1672                                         HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1673                                         hicon = bitmap.GetHicon ();
1674                                 }
1675                         }
1676                         using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1677                                 // hicon survives bitmap and icon disposal
1678                                 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1679                         }
1680                 }
1681
1682                 [Test]
1683                 [Category ("NotWorking")] // libgdiplus has lost track of the original 1bpp state
1684                 public void Hicon48 ()
1685                 {
1686                         using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/48x48x1.ico"))) {
1687                                 // looks like 1bbp icons aren't welcome as bitmaps ;-)
1688                                 Assert.Throws<ArgumentException> (() => Bitmap.FromHicon (icon.Handle));
1689                         }
1690                 }
1691
1692                 [Test]
1693                 public void Hicon64 ()
1694                 {
1695                         IntPtr hicon;
1696                         int size;
1697                         using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/64x64x256.ico"))) {
1698                                 size = icon.Width;
1699                                 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1700                                         HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1701                                         hicon = bitmap.GetHicon ();
1702                                 }
1703                         }
1704                         using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1705                                 // hicon survives bitmap and icon disposal
1706                                 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1707                         }
1708                 }
1709
1710                 [Test]
1711                 public void Hicon96 ()
1712                 {
1713                         IntPtr hicon;
1714                         int size;
1715                         using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/96x96x256.ico"))) {
1716                                 size = icon.Width;
1717                                 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1718                                         HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1719                                         hicon = bitmap.GetHicon ();
1720                                 }
1721                         }
1722                         using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1723                                 // hicon survives bitmap and icon disposal
1724                                 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1725                         }
1726                 }
1727
1728                 [Test]
1729                 public void HBitmap ()
1730                 {
1731                         IntPtr hbitmap;
1732                         string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1733                         using (Bitmap bitmap = new Bitmap (sInFile)) {
1734                                 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1735                                 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1736                                 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1737                                 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1738                                 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1739                                 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1740                                 hbitmap = bitmap.GetHbitmap ();
1741                         }
1742                         // hbitmap survives original bitmap disposal
1743                         using (Image image = Image.FromHbitmap (hbitmap)) {
1744                                 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "FromHbitmap.PixelFormat");
1745                                 Assert.AreEqual (0, image.Palette.Entries.Length, "FromHbitmap.Palette");
1746                                 Assert.AreEqual (183, image.Height, "FromHbitmap.Height");
1747                                 Assert.AreEqual (173, image.Width, "FromHbitmap.Width");
1748                                 Assert.AreEqual (335888, image.Flags, "FromHbitmap.Flags");
1749                                 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "FromHbitmap.RawFormat");
1750                         }
1751                 }
1752
1753                 [Test]
1754                 public void CreateMultipleBitmapFromSameHBITMAP ()
1755                 {
1756                         IntPtr hbitmap;
1757                         string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1758                         using (Bitmap bitmap = new Bitmap (sInFile)) {
1759                                 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1760                                 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1761                                 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1762                                 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1763                                 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1764                                 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1765                                 hbitmap = bitmap.GetHbitmap ();
1766                         }
1767                         // hbitmap survives original bitmap disposal
1768                         using (Image image = Image.FromHbitmap (hbitmap)) {
1769                                 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "1.PixelFormat");
1770                                 Assert.AreEqual (0, image.Palette.Entries.Length, "1.Palette");
1771                                 Assert.AreEqual (183, image.Height, "1.Height");
1772                                 Assert.AreEqual (173, image.Width, "1.Width");
1773                                 Assert.AreEqual (335888, image.Flags, "1.Flags");
1774                                 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "1.RawFormat");
1775                         }
1776                         using (Image image2 = Image.FromHbitmap (hbitmap)) {
1777                                 //Assert.AreEqual (PixelFormat.Format32bppRgb, image2.PixelFormat, "2.PixelFormat");
1778                                 Assert.AreEqual (0, image2.Palette.Entries.Length, "2.Palette");
1779                                 Assert.AreEqual (183, image2.Height, "2.Height");
1780                                 Assert.AreEqual (173, image2.Width, "2.Width");
1781                                 Assert.AreEqual (335888, image2.Flags, "2.Flags");
1782                                 Assert.IsTrue (image2.RawFormat.Equals (ImageFormat.MemoryBmp), "2.RawFormat");
1783                         }
1784                 }
1785         }
1786 }
1787