2 // Bitmap class testing unit
5 // Jordi Mas i Hernàndez (jmas@softcatala.org>
6 // Jonathan Gilbert <logic@deltaq.org>
7 // Sebastien Pouliot <sebastien@ximian.com>
9 // (C) 2004 Ximian, Inc. http://www.ximian.com
10 // Copyright (C) 2004,2006-2007 Novell, Inc (http://www.novell.com)
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
34 using System.Drawing.Imaging;
36 using System.Runtime.InteropServices;
37 using System.Runtime.Serialization;
38 using System.Runtime.Serialization.Formatters.Binary;
39 using System.Runtime.Serialization.Formatters.Soap;
40 using System.Security.Cryptography;
41 using System.Security.Permissions;
43 using System.Xml.Serialization;
44 using NUnit.Framework;
46 namespace MonoTests.System.Drawing {
49 [SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
50 public class TestBitmap {
53 public void TestPixels()
55 // Tests GetSetPixel/SetPixel
56 Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);
57 bmp.SetPixel(0,0,Color.FromArgb(255,128,128,128));
58 Color color = bmp.GetPixel(0,0);
60 Assert.AreEqual (Color.FromArgb(255,128,128,128), color);
62 bmp.SetPixel(99,99,Color.FromArgb(255,255,0,155));
63 Color color2 = bmp.GetPixel(99,99);
64 Assert.AreEqual (Color.FromArgb(255,255,0,155), color2);
68 public void LockBits_32_32_NonIndexedWrite ()
70 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
71 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
72 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
73 Assert.AreEqual (100, data.Height, "Height");
74 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
75 Assert.AreEqual (400, data.Stride, "Stride");
76 Assert.AreEqual (100, data.Width, "Width");
77 bmp.UnlockBits (data);
82 public void LockBits_32_24_NonIndexedWrite ()
84 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
85 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
86 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
87 Assert.AreEqual (100, data.Height, "Height");
88 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
89 Assert.AreEqual (300, data.Stride, "Stride");
90 Assert.AreEqual (100, data.Width, "Width");
91 bmp.UnlockBits (data);
96 public void LockBits_24_24_NonIndexedWrite ()
98 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
99 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
100 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
101 Assert.AreEqual (100, data.Height, "Height");
102 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
103 Assert.AreEqual (300, data.Stride, "Stride");
104 Assert.AreEqual (100, data.Width, "Width");
105 bmp.UnlockBits (data);
110 public void LockBits_24_32_NonIndexedWrite ()
112 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
113 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
114 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
115 Assert.AreEqual (100, data.Height, "Height");
116 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
117 Assert.AreEqual (400, data.Stride, "Stride");
118 Assert.AreEqual (100, data.Width, "Width");
119 bmp.UnlockBits (data);
124 [ExpectedException (typeof (ArgumentException))]
125 public void LockBits_IndexedWrite_NonIndexed ()
127 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
128 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
129 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
134 [ExpectedException (typeof (ArgumentException))]
135 public void LockBits_NonIndexedWrite_ToIndexed ()
137 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
138 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
140 BitmapData bd = new BitmapData ();
142 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, bd);
144 catch (ArgumentException) {
145 // test to see if there's a leak or not in this case
146 Assert.AreEqual (IntPtr.Zero, bd.Scan0, "Scan0");
150 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
156 public void LockBits_IndexedWrite_SameIndexedFormat ()
158 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
159 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
160 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
161 Assert.AreEqual (100, data.Height, "Height");
162 Assert.AreEqual (PixelFormat.Format8bppIndexed, data.PixelFormat, "PixelFormat");
163 Assert.AreEqual (100, data.Stride, "Stride");
164 Assert.AreEqual (100, data.Width, "Width");
165 bmp.UnlockBits (data);
170 public void LockBits_ImageLockMode_Invalid ()
172 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
173 Rectangle r = new Rectangle (4, 4, 4, 4);
174 BitmapData data = bmp.LockBits (r, (ImageLockMode)0, PixelFormat.Format24bppRgb);
176 Assert.AreEqual (4, data.Height, "Height");
177 Assert.AreEqual (4, data.Width, "Width");
178 Assert.IsTrue (data.Stride >= 12, "Stride");
179 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
180 Assert.IsFalse (IntPtr.Zero.Equals (data.Scan0), "Scan0");
183 bmp.UnlockBits (data);
189 [ExpectedException (typeof (InvalidOperationException))]
190 public void LockBits_Double ()
192 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
193 Rectangle r = new Rectangle (4, 4, 4, 4);
194 BitmapData data = bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
196 bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
199 bmp.UnlockBits (data);
205 [ExpectedException (typeof (ArgumentException))]
206 public void LockBits_Disposed ()
208 Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
209 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
211 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
215 [ExpectedException (typeof (ArgumentException))]
216 [Category ("Valgrind")] // this test is known to leak memory (API design limitation)
217 public void UnlockBits_Disposed ()
219 Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
220 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
221 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
223 bmp.UnlockBits (data);
224 // and that results in something like this when executed under Valgrind
225 // "40,000 bytes in 1 blocks are possibly lost in loss record 88 of 92"
229 [ExpectedException (typeof (ArgumentException))]
230 public void UnlockBits_Null ()
232 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
233 bmp.UnlockBits (null);
238 [ExpectedException (typeof (ArgumentException))]
239 public void LockBits_BitmapData_Null ()
241 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
242 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
243 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, null);
248 public void LockBits_32_32_BitmapData ()
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.Format32bppRgb, data);
254 Assert.AreEqual (100, data.Height, "Height");
255 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
256 Assert.AreEqual (400, data.Stride, "Stride");
257 Assert.AreEqual (100, data.Width, "Width");
258 bmp.UnlockBits (data);
263 public void LockBits_32_24_BitmapData ()
265 BitmapData data = new BitmapData ();
266 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
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);
278 public void LockBits_24_24_BitmapData ()
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.Format24bppRgb, data);
284 Assert.AreEqual (100, data.Height, "Height");
285 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
286 Assert.AreEqual (300, data.Stride, "Stride");
287 Assert.AreEqual (100, data.Width, "Width");
288 bmp.UnlockBits (data);
293 public void LockBits_24_32_BitmapData ()
295 BitmapData data = new BitmapData ();
296 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
297 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
298 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
299 Assert.AreEqual (100, data.Height, "Height");
300 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
301 Assert.AreEqual (400, data.Stride, "Stride");
302 Assert.AreEqual (100, data.Width, "Width");
303 bmp.UnlockBits (data);
310 [ExpectedException (typeof (InvalidOperationException))]
312 [ExpectedException (typeof (Exception))]
314 public void Format1bppIndexed ()
316 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
317 Color c = bmp.GetPixel (0, 0);
318 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
319 bmp.SetPixel (0, 0, c);
325 [ExpectedException (typeof (InvalidOperationException))]
327 [ExpectedException (typeof (Exception))]
329 public void Format4bppIndexed ()
331 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
332 Color c = bmp.GetPixel (0, 0);
333 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
334 bmp.SetPixel (0, 0, c);
340 [ExpectedException (typeof (InvalidOperationException))]
342 [ExpectedException (typeof (Exception))]
344 public void Format8bppIndexed ()
346 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
347 Color c = bmp.GetPixel (0, 0);
348 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
349 bmp.SetPixel (0, 0, c);
354 [ExpectedException (typeof (ArgumentException))]
355 [Category ("NotWorking")] // libgdiplus doesn't support this format
356 public void Format16bppGrayScale ()
358 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format16bppGrayScale)) {
359 // and MS GDI+ support seems quite limited too
364 private void FormatTest (PixelFormat format)
366 bool alpha = Image.IsAlphaPixelFormat (format);
367 int size = Image.GetPixelFormatSize (format) / 8 * 2;
368 using (Bitmap bmp = new Bitmap (2, 1, format)) {
369 Color a = Color.FromArgb (128, 64, 32, 16);
370 Color b = Color.FromArgb (192, 96, 48, 24);
371 bmp.SetPixel (0, 0, a);
372 bmp.SetPixel (1, 0, b);
373 Color c = bmp.GetPixel (0, 0);
374 Color d = bmp.GetPixel (1, 0);
376 Assert.AreEqual (255, c.A, "0,0-16bpp-A");
377 Assert.AreEqual (66, c.R, "0,0-16bpp-R");
378 if (format == PixelFormat.Format16bppRgb565) {
379 Assert.AreEqual (32, c.G, "0,0-16bpp-G");
381 Assert.AreEqual (33, c.G, "0,0-16bpp-G");
383 Assert.AreEqual (16, c.B, "0,0-16bpp-B");
385 Assert.AreEqual (255, d.A, "1,0-16bpp-A");
386 Assert.AreEqual (99, d.R, "1,0-16bpp-R");
387 if (format == PixelFormat.Format16bppRgb565) {
388 Assert.AreEqual (48, d.G, "1,0-16bpp-G");
390 Assert.AreEqual (49, d.G, "1,0-16bpp-G");
392 Assert.AreEqual (24, d.B, "1,0-16bpp-B");
394 if (format == PixelFormat.Format32bppPArgb) {
395 Assert.AreEqual (a.A, c.A, "0,0-alpha-A");
396 // note sure why the -1
397 Assert.AreEqual (a.R - 1, c.R, "0,0-alpha-premultiplied-R");
398 Assert.AreEqual (a.G - 1, c.G, "0,0-alpha-premultiplied-G");
399 Assert.AreEqual (a.B - 1, c.B, "0,0-alpha-premultiplied-B");
401 Assert.AreEqual (b.A, d.A, "1,0-alpha-A");
402 // note sure why the -1
403 Assert.AreEqual (b.R - 1, d.R, "1,0-alpha-premultiplied-R");
404 Assert.AreEqual (b.G - 1, d.G, "1,0-alpha-premultiplied-G");
405 Assert.AreEqual (b.B - 1, d.B, "1,0-alpha-premultiplied-B");
407 Assert.AreEqual (a, c, "0,0-alpha");
408 Assert.AreEqual (b, d, "1,0-alpha");
411 Assert.AreEqual (Color.FromArgb (255, 64, 32, 16), c, "0,0-non-alpha");
412 Assert.AreEqual (Color.FromArgb (255, 96, 48, 24), d, "1,0-non-alpha");
414 BitmapData bd = bmp.LockBits (new Rectangle (0, 0, 2, 1), ImageLockMode.ReadOnly, format);
416 byte[] data = new byte[size];
417 Marshal.Copy (bd.Scan0, data, 0, size);
418 if (format == PixelFormat.Format32bppPArgb) {
419 Assert.AreEqual (Math.Ceiling ((float)c.B * c.A / 255), data[0], "0.alpha-premultiplied-B");
420 Assert.AreEqual (Math.Ceiling ((float)c.G * c.A / 255), data[1], "0.alpha-premultiplied-R");
421 Assert.AreEqual (Math.Ceiling ((float)c.R * c.A / 255), data[2], "0.alpha-premultiplied-G");
422 Assert.AreEqual (c.A, data[3], "0.alpha-A");
423 Assert.AreEqual (Math.Ceiling ((float)d.B * d.A / 255), data[4], "1.alpha-premultiplied-B");
424 Assert.AreEqual (Math.Ceiling ((float)d.G * d.A / 255), data[5], "1.alpha-premultiplied-R");
425 Assert.AreEqual (Math.Ceiling ((float)d.R * d.A / 255), data[6], "1.alpha-premultiplied-G");
426 Assert.AreEqual (d.A, data[7], "1.alpha-A");
427 } else if (size == 4) {
430 case PixelFormat.Format16bppRgb565:
431 Assert.AreEqual (2, data[n++], "0");
432 Assert.AreEqual (65, data[n++], "1");
433 Assert.AreEqual (131, data[n++], "2");
434 Assert.AreEqual (97, data[n++], "3");
436 case PixelFormat.Format16bppArgb1555:
437 Assert.AreEqual (130, data[n++], "0");
438 Assert.AreEqual (160, data[n++], "1");
439 Assert.AreEqual (195, data[n++], "2");
440 Assert.AreEqual (176, data[n++], "3");
442 case PixelFormat.Format16bppRgb555:
443 Assert.AreEqual (130, data[n++], "0");
444 Assert.AreEqual (32, data[n++], "1");
445 Assert.AreEqual (195, data[n++], "2");
446 Assert.AreEqual (48, data[n++], "3");
451 Assert.AreEqual (c.B, data[n++], "0.B");
452 Assert.AreEqual (c.G, data[n++], "0.R");
453 Assert.AreEqual (c.R, data[n++], "0.G");
455 Assert.AreEqual (c.A, data[n++], "0.A");
456 Assert.AreEqual (d.B, data[n++], "1.B");
457 Assert.AreEqual (d.G, data[n++], "1.R");
458 Assert.AreEqual (d.R, data[n++], "1.G");
460 Assert.AreEqual (d.A, data[n++], "1.A");
470 [Category ("NotWorking")] // libgdiplus doesn't support this format
471 public void Format16bppArgb1555 ()
473 FormatTest (PixelFormat.Format16bppArgb1555);
477 [Category ("NotWorking")] // GetPixel is a few bits off
478 public void Format16bppRgb555 ()
480 FormatTest (PixelFormat.Format16bppRgb555);
484 [Category ("NotWorking")] // GetPixel is a few bits off
485 public void Format16bppRgb565 ()
487 FormatTest (PixelFormat.Format16bppRgb565);
491 public void Format32bppArgb ()
493 FormatTest (PixelFormat.Format32bppArgb);
497 [Category ("NotWorking")] // I'm not sure we're handling this format anywhere (Cairo itself use it)
498 public void Format32bppPArgb ()
500 FormatTest (PixelFormat.Format32bppPArgb);
504 public void Format32bppRgb ()
506 FormatTest (PixelFormat.Format32bppRgb);
510 public void Format24bppRgb ()
512 FormatTest (PixelFormat.Format24bppRgb);
515 /* Get the output directory depending on the runtime and location*/
516 public static string getOutSubDir()
520 if (Environment.GetEnvironmentVariable("MSNet")==null)
525 sRslt = Path.GetFullPath (sSub);
527 if (Directory.Exists(sRslt) == false)
528 sRslt = "Test/System.Drawing/" + sSub;
530 if (sRslt.Length > 0)
531 if (sRslt[sRslt.Length-1] != '\\' && sRslt[sRslt.Length-1] != '/')
537 /* Get the input directory depending on the runtime*/
538 public static string getInFile(string file)
540 string sRslt = Path.GetFullPath ("../System.Drawing/" + file);
541 if (!File.Exists (sRslt))
542 sRslt = "Test/System.Drawing/" + file;
546 // note: this test fails when saving (for the same reason) on Mono and MS.NET
548 public void MakeTransparent()
550 string sInFile = getInFile("bitmaps/maketransparent.bmp");
551 string sOutFile = getOutSubDir() + "transparent.bmp";
553 Bitmap bmp = new Bitmap(sInFile);
555 bmp.MakeTransparent();
558 Color color = bmp.GetPixel(1,1);
559 Assert.AreEqual (Color.Black.R, color.R);
560 Assert.AreEqual (Color.Black.G, color.G);
561 Assert.AreEqual (Color.Black.B, color.B);
567 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
568 Rectangle rect = new Rectangle(0,0,50,50);
569 Bitmap bmp = new Bitmap(sInFile);
571 Bitmap bmpNew = bmp.Clone (rect, PixelFormat.Format32bppArgb);
572 Color colororg0 = bmp.GetPixel(0,0);
573 Color colororg50 = bmp.GetPixel(49,49);
574 Color colornew0 = bmpNew.GetPixel(0,0);
575 Color colornew50 = bmpNew.GetPixel(49,49);
577 Assert.AreEqual (colororg0, colornew0);
578 Assert.AreEqual (colororg50, colornew50);
582 public void CloneImage()
584 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
585 Bitmap bmp = new Bitmap(sInFile);
587 Bitmap bmpNew = (Bitmap) bmp.Clone ();
589 Assert.AreEqual (bmp.Width, bmpNew.Width);
590 Assert.AreEqual (bmp.Height, bmpNew.Height);
591 Assert.AreEqual (bmp.PixelFormat, bmpNew.PixelFormat);
598 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
599 Bitmap bmp = new Bitmap(sInFile);
600 int cnt = bmp.GetFrameCount(FrameDimension.Page);
601 int active = bmp.SelectActiveFrame (FrameDimension.Page, 0);
603 Assert.AreEqual (1, cnt);
604 Assert.AreEqual (0, active);
608 [ExpectedException (typeof (ArgumentException))]
609 public void FileDoesNotExists ()
611 Bitmap bmp = new Bitmap ("FileDoesNotExists.jpg");
614 static string ByteArrayToString(byte[] arrInput)
617 StringBuilder sOutput = new StringBuilder(arrInput.Length);
618 for (i=0;i < arrInput.Length -1; i++)
620 sOutput.Append(arrInput[i].ToString("X2"));
622 return sOutput.ToString();
626 public string RotateBmp (Bitmap src, RotateFlipType rotate)
628 int width = 150, height = 150, index = 0;
629 byte[] pixels = new byte [width * height * 3];
634 bmp_rotate = src.Clone (new RectangleF (0,0, width, height), PixelFormat.Format32bppArgb);
635 bmp_rotate.RotateFlip (rotate);
637 for (int y = 0; y < height; y++) {
638 for (int x = 0; x < width; x++) {
639 clr = bmp_rotate.GetPixel (x,y);
640 pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++] = clr.B;
644 hash = new MD5CryptoServiceProvider().ComputeHash (pixels);
645 return ByteArrayToString (hash);
647 public string RotateIndexedBmp (Bitmap src, RotateFlipType type)
651 switch (src.PixelFormat)
653 case PixelFormat.Format1bppIndexed: pixels_per_byte = 8; break;
654 case PixelFormat.Format4bppIndexed: pixels_per_byte = 2; break;
655 case PixelFormat.Format8bppIndexed: pixels_per_byte = 1; break;
657 default: throw new Exception("Cannot pass a bitmap of format " + src.PixelFormat + " to RotateIndexedBmp");
660 Bitmap test = src.Clone () as Bitmap;
662 test.RotateFlip (type);
664 BitmapData data = null;
669 data = test.LockBits (new Rectangle (0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat);
671 int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte;
672 pixel_data = new byte[data.Height * scan_size];
674 for (int y=0; y < data.Height; y++) {
675 IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64 ());
676 int dest_offset = y * scan_size;
677 for (int x=0; x < scan_size; x++)
678 pixel_data[dest_offset + x] = Marshal.ReadByte (src_ptr, x);
685 try { test.UnlockBits(data); } catch {}
687 try { test.Dispose(); } catch {}
691 if (pixel_data == null)
694 byte[] hash = new MD5CryptoServiceProvider().ComputeHash (pixel_data);
695 return ByteArrayToString (hash);
700 Rotate bitmap in diffent ways, and check the result
706 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
707 Bitmap bmp = new Bitmap(sInFile);
709 Assert.AreEqual ("312958A3C67402E1299413794988A3", RotateBmp (bmp, RotateFlipType.Rotate90FlipNone));
710 Assert.AreEqual ("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp (bmp, RotateFlipType.Rotate180FlipNone));
711 Assert.AreEqual ("15AD2ADBDC7090C0EC744D0F7ACE2F", RotateBmp (bmp, RotateFlipType.Rotate270FlipNone));
712 Assert.AreEqual ("2E10FEC1F4FD64ECC51D7CE68AEB18", RotateBmp (bmp, RotateFlipType.RotateNoneFlipX));
713 Assert.AreEqual ("E63204779B566ED01162B90B49BD9E", RotateBmp (bmp, RotateFlipType.Rotate90FlipX));
714 Assert.AreEqual ("B1ECB17B5093E13D04FF55CFCF7763", RotateBmp (bmp, RotateFlipType.Rotate180FlipX));
715 Assert.AreEqual ("71A173882C16755D86F4BC26532374", RotateBmp (bmp, RotateFlipType.Rotate270FlipX));
720 Rotate 1- and 4-bit bitmaps in different ways and check the
721 resulting pixels using MD5
724 public void Rotate1bit4bit()
726 if ((Environment.OSVersion.Platform != (PlatformID)4)
727 && (Environment.OSVersion.Platform != (PlatformID)128))
728 Assert.Ignore("This does not work with Microsoft's GDIPLUS.DLL due to off-by-1 errors in their GdipBitmapRotateFlip function.");
731 getInFile ("bitmaps/1bit.png"),
732 getInFile ("bitmaps/4bit.png")
735 StringBuilder md5s = new StringBuilder();
737 foreach (string file in files)
738 using (Bitmap bmp = new Bitmap(file))
739 foreach (RotateFlipType type in Enum.GetValues (typeof(RotateFlipType)))
740 md5s.Append (RotateIndexedBmp (bmp, type));
742 using (StreamWriter writer = new StreamWriter("/tmp/md5s.txt"))
743 writer.WriteLine(md5s);
746 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit RotateNoneFlipNone
747 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit Rotate180FlipXY
748 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate90FlipNone
749 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate270FlipXY
750 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit Rotate180FlipNone
751 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit RotateNoneFlipXY
752 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate270FlipNone
753 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate90FlipXY
754 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit RotateNoneFlipX
755 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit Rotate180FlipY
756 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate90FlipX
757 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate270FlipY
758 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit Rotate180FlipX
759 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit RotateNoneFlipY
760 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate270FlipX
761 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate90FlipY
762 "3CC874B571902366AACED5D619E87D" + // 4-bit RotateNoneFlipNone
763 "3CC874B571902366AACED5D619E87D" + // 4-bit Rotate180FlipXY
764 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate90FlipNone
765 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate270FlipXY
766 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit Rotate180FlipNone
767 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit RotateNoneFlipXY
768 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate270FlipNone
769 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate90FlipXY
770 "545876C99ACF833E69FBFFBF436034" + // 4-bit RotateNoneFlipX
771 "545876C99ACF833E69FBFFBF436034" + // 4-bit Rotate180FlipY
772 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate90FlipX
773 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate270FlipY
774 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit Rotate180FlipX
775 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit RotateNoneFlipY
776 "B6B6245796C836923ABAABDF368B29" + // 4-bit Rotate270FlipX
777 "B6B6245796C836923ABAABDF368B29", // 4-bit Rotate90FlipY
781 private Bitmap CreateBitmap (int width, int height, PixelFormat fmt)
783 Bitmap bmp = new Bitmap (width, height, fmt);
784 using (Graphics gr = Graphics.FromImage (bmp)) {
785 Color c = Color.FromArgb (255, 100, 200, 250);
786 for (int x = 1; x < 80; x++) {
787 bmp.SetPixel (x, 1, c);
788 bmp.SetPixel (x, 2, c);
789 bmp.SetPixel (x, 78, c);
790 bmp.SetPixel (x, 79, c);
792 for (int y = 3; y < 78; y++) {
793 bmp.SetPixel (1, y, c);
794 bmp.SetPixel (2, y, c);
795 bmp.SetPixel (78, y, c);
796 bmp.SetPixel (79, y, c);
802 private byte[] HashPixels (Bitmap bmp)
804 int len = bmp.Width * bmp.Height * 4;
806 byte[] pixels = new byte [len];
808 for (int y = 0; y < bmp.Height; y++) {
809 for (int x = 0; x < bmp.Width; x++) {
810 Color clr = bmp.GetPixel (x, y);
811 pixels[index++] = clr.R;
812 pixels[index++] = clr.G;
813 pixels[index++] = clr.B;
816 return MD5.Create ().ComputeHash (pixels);
819 private byte[] HashLock (Bitmap bmp, int width, int height, PixelFormat fmt, ImageLockMode mode)
821 int len = bmp.Width * bmp.Height * 4;
822 byte[] pixels = new byte[len];
823 BitmapData bd = bmp.LockBits (new Rectangle (0, 0, width, height), mode, fmt);
826 int bbps = Image.GetPixelFormatSize (fmt);
827 long pos = bd.Scan0.ToInt64 ();
828 byte[] btv = new byte[1];
829 for (int y = 0; y < bd.Height; y++) {
830 for (int x = 0; x < bd.Width; x++) {
833 for (int bt = 0; bt < bbps / 8; bt++, index++) {
835 cur += y * bd.Stride;
838 Marshal.Copy ((IntPtr) cur, btv, 0, 1);
839 pixels[index] = btv[0];
841 /* Make change of all the colours = 250 to 10*/
844 Marshal.Copy (btv, 0, (IntPtr) cur, 1);
850 for (int i = index; i < len; i++)
856 return MD5.Create ().ComputeHash (pixels);
860 Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns
861 firsts, changes them, and then using GetPixel does another check of the changes.
862 The results match the .Net framework
864 private static byte[] DefaultBitmapHash = new byte[] { 0xD8, 0xD3, 0x68, 0x9C, 0x86, 0x7F, 0xB6, 0xA0, 0x76, 0xD6, 0x00, 0xEF, 0xFF, 0xE5, 0x8E, 0x1B };
865 private static byte[] FinalWholeBitmapHash = new byte[] { 0x5F, 0x52, 0x98, 0x37, 0xE3, 0x94, 0xE1, 0xA6, 0x06, 0x6C, 0x5B, 0xF1, 0xA9, 0xC2, 0xA9, 0x43 };
868 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Whole ()
870 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
871 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
872 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
873 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
874 Assert.AreEqual (expected, actual, "Full-Format32bppArgb");
875 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
880 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Whole ()
882 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
883 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
884 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
885 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
886 Assert.AreEqual (expected, actual, "Full-Format32bppPArgb");
887 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
892 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Whole ()
894 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
895 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
896 byte[] expected = { 0xC0, 0x28, 0xB5, 0x2E, 0x86, 0x90, 0x6F, 0x37, 0x09, 0x5F, 0x49, 0xA4, 0x91, 0xDA, 0xEE, 0xB9 };
897 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
898 Assert.AreEqual (expected, actual, "Full-Format32bppRgb");
899 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
904 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Whole ()
906 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
907 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
908 byte[] expected = { 0xA7, 0xB2, 0x50, 0x04, 0x11, 0x12, 0x64, 0x68, 0x6B, 0x7D, 0x2F, 0x6E, 0x69, 0x24, 0xCB, 0x14 };
909 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
910 Assert.AreEqual (expected, actual, "Full-Format24bppRgb");
911 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
915 private static byte[] FinalPartialBitmapHash = new byte[] { 0xED, 0xD8, 0xDC, 0x9B, 0x44, 0x00, 0x22, 0x9B, 0x07, 0x06, 0x4A, 0x21, 0x70, 0xA7, 0x31, 0x1D };
918 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Partial ()
920 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
921 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
922 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
923 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
924 Assert.AreEqual (expected, actual, "Partial-Format32bppArgb");
925 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
930 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Partial ()
932 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
933 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
934 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
935 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
936 Assert.AreEqual (expected, actual, "Partial-Format32bppPArgb");
937 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
942 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Partial ()
944 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
945 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
946 byte[] expected = { 0x72, 0x33, 0x09, 0x67, 0x53, 0x65, 0x38, 0xF9, 0xE4, 0x58, 0xE1, 0x0A, 0xAA, 0x6A, 0xCC, 0xB8 };
947 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
948 Assert.AreEqual (expected, actual, "Partial-Format32bppRgb");
949 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
954 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Partial ()
956 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
957 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
958 byte[] expected = { 0x4D, 0x39, 0x21, 0x88, 0xC2, 0x17, 0x14, 0x5F, 0x89, 0x9E, 0x02, 0x75, 0xF3, 0x64, 0xD8, 0xF0 };
959 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
960 Assert.AreEqual (expected, actual, "Partial-Format24bppRgb");
961 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
966 Tests the LockBitmap and UnlockBitmap functions, specifically the copying
967 of bitmap data in the directions indicated by the ImageLockMode.
970 public void LockUnlockBitmap ()
976 Color red = Color.FromArgb (Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B);
977 Color blue = Color.FromArgb (Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B);
979 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppRgb)) {
980 bmp.SetPixel (0, 0, red);
981 pixel_colour = bmp.GetPixel (0, 0);
982 Assert.AreEqual (red, pixel_colour, "Set/Get-Red");
984 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
986 pixel_value = Marshal.ReadByte (data.Scan0, 0);
987 pixel_value |= Marshal.ReadByte (data.Scan0, 1) << 8;
988 pixel_value |= Marshal.ReadByte (data.Scan0, 2) << 16;
989 pixel_value |= Marshal.ReadByte (data.Scan0, 3) << 24;
991 pixel_colour = Color.FromArgb (pixel_value);
992 // Disregard alpha information in the test
993 pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
994 Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Original");
996 // write blue but we're locked in read-only...
997 Marshal.WriteByte (data.Scan0, 0, blue.B);
998 Marshal.WriteByte (data.Scan0, 1, blue.G);
999 Marshal.WriteByte (data.Scan0, 2, blue.R);
1000 Marshal.WriteByte (data.Scan0, 3, blue.A);
1003 bmp.UnlockBits (data);
1004 pixel_colour = bmp.GetPixel (0, 0);
1005 // Disregard alpha information in the test
1006 pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
1007 // ...so we still read red after unlocking
1008 Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Unlocked");
1011 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
1014 Marshal.WriteByte (data.Scan0, 0, blue.B);
1015 Marshal.WriteByte (data.Scan0, 1, blue.G);
1016 Marshal.WriteByte (data.Scan0, 2, blue.R);
1017 Marshal.WriteByte (data.Scan0, 3, blue.A);
1020 bmp.UnlockBits (data);
1021 pixel_colour = bmp.GetPixel (0, 0);
1022 // Disregard alpha information in the test
1023 pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
1025 Assert.AreEqual (blue, pixel_colour, "32RGB/32ARGB-ReadWrite-Blue-Unlock");
1029 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppArgb)) {
1030 bmp.SetPixel (0, 0, red);
1032 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
1034 byte b = Marshal.ReadByte (data.Scan0, 0);
1035 byte g = Marshal.ReadByte (data.Scan0, 1);
1036 byte r = Marshal.ReadByte (data.Scan0, 2);
1037 pixel_colour = Color.FromArgb (red.A, r, g, b);
1038 Assert.AreEqual (red, pixel_colour, "32ARGB/24RGB-ReadOnly-Red-Original");
1039 // write blue but we're locked in read-only...
1040 Marshal.WriteByte (data.Scan0, 0, blue.B);
1041 Marshal.WriteByte (data.Scan0, 1, blue.G);
1042 Marshal.WriteByte (data.Scan0, 2, blue.R);
1045 bmp.UnlockBits (data);
1046 // ...so we still read red after unlocking
1047 Assert.AreEqual (red, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadOnly-Red-Unlock");
1050 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
1053 Marshal.WriteByte (data.Scan0, 0, blue.B);
1054 Marshal.WriteByte (data.Scan0, 1, blue.G);
1055 Marshal.WriteByte (data.Scan0, 2, blue.R);
1058 bmp.UnlockBits (data);
1060 Assert.AreEqual (blue, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadWrite-Blue-Unlock");
1065 public void DefaultFormat1 ()
1067 using (Bitmap bmp = new Bitmap (20, 20)) {
1068 Assert.AreEqual (ImageFormat.MemoryBmp, bmp.RawFormat);
1073 public void DefaultFormat2 ()
1075 string filename = Path.GetTempFileName ();
1076 using (Bitmap bmp = new Bitmap (20, 20)) {
1077 bmp.Save (filename);
1080 using (Bitmap other = new Bitmap (filename)) {
1081 Assert.AreEqual (ImageFormat.Png, other.RawFormat);
1083 File.Delete (filename);
1087 public void BmpDataStride1 ()
1089 Bitmap bmp = new Bitmap (184, 184, PixelFormat.Format1bppIndexed);
1090 BitmapData data = bmp.LockBits (new Rectangle (0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
1092 Assert.AreEqual (24, data.Stride);
1094 bmp.UnlockBits (data);
1099 private Stream Serialize (object o)
1101 MemoryStream ms = new MemoryStream ();
1102 IFormatter formatter = new BinaryFormatter ();
1103 formatter.Serialize (ms, o);
1108 private object Deserialize (Stream s)
1110 return new BinaryFormatter ().Deserialize (s);
1114 public void Serialize_Icon ()
1116 // this cause a problem with resgen, see http://bugzilla.ximian.com/show_bug.cgi?id=80565
1117 string filename = getInFile ("bitmaps/16x16x16.ico");
1118 using (Bitmap icon = new Bitmap (filename)) {
1119 using (Stream s = Serialize (icon)) {
1120 using (Bitmap copy = (Bitmap)Deserialize (s)) {
1121 Assert.AreEqual (icon.Height, copy.Height, "Height");
1122 Assert.AreEqual (icon.Width, copy.Width, "Width");
1123 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1124 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1125 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1131 private Stream SoapSerialize (object o)
1133 MemoryStream ms = new MemoryStream ();
1134 IFormatter formatter = new SoapFormatter ();
1135 formatter.Serialize (ms, o);
1140 private object SoapDeserialize (Stream s)
1142 return new SoapFormatter ().Deserialize (s);
1146 public void SoapSerialize_Icon ()
1148 string filename = getInFile ("bitmaps/16x16x16.ico");
1149 using (Bitmap icon = new Bitmap (filename)) {
1150 using (Stream s = SoapSerialize (icon)) {
1151 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1152 Assert.AreEqual (icon.Height, copy.Height, "Height");
1153 Assert.AreEqual (icon.Width, copy.Width, "Width");
1154 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1155 Assert.AreEqual (16, icon.Palette.Entries.Length, "icon Palette");
1156 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1157 Assert.AreEqual (0, copy.Palette.Entries.Length, "copy Palette");
1158 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1165 public void SoapSerialize_Bitmap8 ()
1167 string filename = getInFile ("bitmaps/almogaver8bits.bmp");
1168 using (Bitmap bmp = new Bitmap (filename)) {
1169 using (Stream s = SoapSerialize (bmp)) {
1170 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1171 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1172 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1173 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1174 Assert.AreEqual (256, copy.Palette.Entries.Length, "Palette");
1175 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1182 public void SoapSerialize_Bitmap24 ()
1184 string filename = getInFile ("bitmaps/almogaver24bits.bmp");
1185 using (Bitmap bmp = new Bitmap (filename)) {
1186 using (Stream s = SoapSerialize (bmp)) {
1187 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1188 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1189 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1190 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1191 Assert.AreEqual (bmp.Palette.Entries.Length, copy.Palette.Entries.Length, "Palette");
1192 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1200 [Category ("NotWorking")] // http://bugzilla.ximian.com/show_bug.cgi?id=80558
1202 [ExpectedException (typeof (InvalidOperationException))]
1204 public void XmlSerialize ()
1206 new XmlSerializer (typeof (Bitmap));
1209 static int[] palette1 = {
1215 public void Format1bppIndexed_Palette ()
1217 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
1218 ColorPalette pal = bmp.Palette;
1219 Assert.AreEqual (2, pal.Entries.Length, "Length");
1220 for (int i = 0; i < pal.Entries.Length; i++) {
1221 Assert.AreEqual (palette1[i], pal.Entries[i].ToArgb (), i.ToString ());
1223 Assert.AreEqual (2, pal.Flags, "Flags");
1227 static int[] palette16 = {
1247 public void Format4bppIndexed_Palette ()
1249 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
1250 ColorPalette pal = bmp.Palette;
1251 Assert.AreEqual (16, pal.Entries.Length, "Length");
1252 for (int i = 0; i < pal.Entries.Length; i++) {
1253 Assert.AreEqual (palette16 [i], pal.Entries[i].ToArgb (), i.ToString ());
1255 Assert.AreEqual (0, pal.Flags, "Flags");
1259 static int[] palette256 = {
1519 public void Format8bppIndexed_Palette ()
1521 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
1522 ColorPalette pal = bmp.Palette;
1523 Assert.AreEqual (256, pal.Entries.Length, "Length");
1524 for (int i = 0; i < pal.Entries.Length; i++) {
1525 Assert.AreEqual (palette256[i], pal.Entries[i].ToArgb (), i.ToString ());
1527 Assert.AreEqual (4, pal.Flags, "Flags");
1533 [ExpectedException (typeof (InvalidOperationException))]
1535 public void XmlSerialization ()
1537 new XmlSerializer (typeof (Bitmap));
1541 [ExpectedException (typeof (NullReferenceException))]
1542 public void BitmapImageCtor ()
1544 new Bitmap ((Image) null);
1548 [ExpectedException (typeof (ArgumentException))]
1549 public void BitmapImageSizeCtor ()
1551 new Bitmap ((Image) null, Size.Empty);
1555 [ExpectedException (typeof (ArgumentException))]
1556 public void BitmapImageIntIntCtor ()
1558 new Bitmap ((Image) null, Int32.MinValue, Int32.MaxValue);
1562 [ExpectedException (typeof (ArgumentException))]
1563 public void BitmapIntIntCtor ()
1565 new Bitmap (Int32.MinValue, Int32.MaxValue);
1569 [ExpectedException (typeof (ArgumentNullException))]
1570 public void BitmapIntIntGraphicCtor ()
1572 new Bitmap (1, 1, null);
1576 [ExpectedException (typeof (ArgumentException))]
1577 public void BitmapIntIntPixelFormatCtor ()
1579 new Bitmap (Int32.MinValue, Int32.MaxValue, PixelFormat.Format1bppIndexed);
1583 [ExpectedException (typeof (ArgumentException))]
1584 public void BitmapStreamCtor ()
1586 new Bitmap ((Stream) null);
1590 [ExpectedException (typeof (ArgumentException))]
1591 public void BitmapStreamBoolCtor ()
1593 new Bitmap ((Stream) null, true);
1597 [ExpectedException (typeof (ArgumentNullException))]
1598 public void BitmapStringCtor ()
1600 new Bitmap ((string) null);
1604 [ExpectedException (typeof (ArgumentNullException))]
1605 public void BitmapStringBoolCtor ()
1607 new Bitmap ((string) null, false);
1611 [ExpectedException (typeof (NullReferenceException))]
1612 public void BitmapTypeStringCtor1 ()
1614 new Bitmap ((Type) null, "mono");
1618 [ExpectedException (typeof (ArgumentException))]
1619 public void BitmapTypeStringCtor2 ()
1621 new Bitmap (typeof (Bitmap), null);
1624 private void SetResolution (float x, float y)
1626 using (Bitmap bmp = new Bitmap (1, 1)) {
1627 bmp.SetResolution (x, y);
1632 [ExpectedException (typeof (ArgumentException))]
1633 public void SetResolution_Zero ()
1635 SetResolution (0.0f, 0.0f);
1639 [ExpectedException (typeof (ArgumentException))]
1640 public void SetResolution_Negative_X ()
1642 SetResolution (-1.0f, 1.0f);
1646 [ExpectedException (typeof (ArgumentException))]
1647 public void SetResolution_Negative_Y ()
1649 SetResolution (1.0f, -1.0f);
1653 public void SetResolution_MaxValue ()
1655 SetResolution (Single.MaxValue, Single.MaxValue);
1659 public void SetResolution_PositiveInfinity ()
1661 SetResolution (Single.PositiveInfinity, Single.PositiveInfinity);
1665 [ExpectedException (typeof (ArgumentException))]
1666 public void SetResolution_NaN ()
1668 SetResolution (Single.NaN, Single.NaN);
1672 [ExpectedException (typeof (ArgumentException))]
1673 public void SetResolution_NegativeInfinity ()
1675 SetResolution (Single.NegativeInfinity, Single.NegativeInfinity);
1680 public class BitmapFullTrustTest {
1682 public void BitmapIntIntIntPixelFormatIntPtrCtor ()
1684 new Bitmap (1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero);
1687 // BitmapFromHicon## is *almost* the same as IconTest.Icon##ToBitmap except
1688 // for the Flags property
1690 private void HiconTest (string msg, Bitmap b, int size)
1692 Assert.AreEqual (PixelFormat.Format32bppArgb, b.PixelFormat, msg + ".PixelFormat");
1693 // unlike the GDI+ icon decoder the palette isn't kept
1694 Assert.AreEqual (0, b.Palette.Entries.Length, msg + ".Palette");
1695 Assert.AreEqual (size, b.Height, msg + ".Height");
1696 Assert.AreEqual (size, b.Width, msg + ".Width");
1697 Assert.IsTrue (b.RawFormat.Equals (ImageFormat.MemoryBmp), msg + ".RawFormat");
1698 Assert.AreEqual (335888, b.Flags, msg + ".Flags");
1702 public void Hicon16 ()
1706 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/16x16x16.ico"))) {
1708 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1709 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1710 hicon = bitmap.GetHicon ();
1713 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1714 // hicon survives bitmap and icon disposal
1715 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1720 public void Hicon32 ()
1724 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/32x32x16.ico"))) {
1726 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1727 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1728 hicon = bitmap.GetHicon ();
1731 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1732 // hicon survives bitmap and icon disposal
1733 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1738 [ExpectedException (typeof (ArgumentException))]
1739 [Category ("NotWorking")] // libgdiplus has lost track of the original 1bpp state
1740 public void Hicon48 ()
1742 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/48x48x1.ico"))) {
1743 // looks like 1bbp icons aren't welcome as bitmaps ;-)
1744 Bitmap.FromHicon (icon.Handle);
1749 public void Hicon64 ()
1753 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/64x64x256.ico"))) {
1755 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1756 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1757 hicon = bitmap.GetHicon ();
1760 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1761 // hicon survives bitmap and icon disposal
1762 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1767 public void Hicon96 ()
1771 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/96x96x256.ico"))) {
1773 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1774 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1775 hicon = bitmap.GetHicon ();
1778 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1779 // hicon survives bitmap and icon disposal
1780 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1785 public void HBitmap ()
1788 string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1789 using (Bitmap bitmap = new Bitmap (sInFile)) {
1790 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1791 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1792 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1793 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1794 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1795 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1796 hbitmap = bitmap.GetHbitmap ();
1798 // hbitmap survives original bitmap disposal
1799 using (Image image = Image.FromHbitmap (hbitmap)) {
1800 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "FromHbitmap.PixelFormat");
1801 Assert.AreEqual (0, image.Palette.Entries.Length, "FromHbitmap.Palette");
1802 Assert.AreEqual (183, image.Height, "FromHbitmap.Height");
1803 Assert.AreEqual (173, image.Width, "FromHbitmap.Width");
1804 Assert.AreEqual (335888, image.Flags, "FromHbitmap.Flags");
1805 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "FromHbitmap.RawFormat");
1810 public void CreateMultipleBitmapFromSameHBITMAP ()
1813 string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1814 using (Bitmap bitmap = new Bitmap (sInFile)) {
1815 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1816 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1817 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1818 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1819 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1820 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1821 hbitmap = bitmap.GetHbitmap ();
1823 // hbitmap survives original bitmap disposal
1824 using (Image image = Image.FromHbitmap (hbitmap)) {
1825 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "1.PixelFormat");
1826 Assert.AreEqual (0, image.Palette.Entries.Length, "1.Palette");
1827 Assert.AreEqual (183, image.Height, "1.Height");
1828 Assert.AreEqual (173, image.Width, "1.Width");
1829 Assert.AreEqual (335888, image.Flags, "1.Flags");
1830 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "1.RawFormat");
1832 using (Image image2 = Image.FromHbitmap (hbitmap)) {
1833 //Assert.AreEqual (PixelFormat.Format32bppRgb, image2.PixelFormat, "2.PixelFormat");
1834 Assert.AreEqual (0, image2.Palette.Entries.Length, "2.Palette");
1835 Assert.AreEqual (183, image2.Height, "2.Height");
1836 Assert.AreEqual (173, image2.Width, "2.Width");
1837 Assert.AreEqual (335888, image2.Flags, "2.Flags");
1838 Assert.IsTrue (image2.RawFormat.Equals (ImageFormat.MemoryBmp), "2.RawFormat");