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 public void LockBits_IndexedWrite_NonIndexed ()
126 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
127 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
128 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
133 public void LockBits_NonIndexedWrite_ToIndexed ()
135 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
136 BitmapData bd = new BitmapData ();
137 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
138 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, bd));
140 // test to see if there's a leak or not in this case
141 Assert.AreEqual (IntPtr.Zero, bd.Scan0, "Scan0");
146 public void LockBits_IndexedWrite_SameIndexedFormat ()
148 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
149 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
150 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
151 Assert.AreEqual (100, data.Height, "Height");
152 Assert.AreEqual (PixelFormat.Format8bppIndexed, data.PixelFormat, "PixelFormat");
153 Assert.AreEqual (100, data.Stride, "Stride");
154 Assert.AreEqual (100, data.Width, "Width");
155 bmp.UnlockBits (data);
160 public void LockBits_ImageLockMode_Invalid ()
162 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
163 Rectangle r = new Rectangle (4, 4, 4, 4);
164 BitmapData data = bmp.LockBits (r, (ImageLockMode)0, PixelFormat.Format24bppRgb);
166 Assert.AreEqual (4, data.Height, "Height");
167 Assert.AreEqual (4, data.Width, "Width");
168 Assert.IsTrue (data.Stride >= 12, "Stride");
169 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
170 Assert.IsFalse (IntPtr.Zero.Equals (data.Scan0), "Scan0");
173 bmp.UnlockBits (data);
179 public void LockBits_Double ()
181 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
182 Rectangle r = new Rectangle (4, 4, 4, 4);
183 BitmapData data = bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
185 Assert.Throws<InvalidOperationException> (() => bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb));
188 bmp.UnlockBits (data);
194 public void LockBits_Disposed ()
196 Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
197 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
199 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
203 [Category ("Valgrind")] // this test is known to leak memory (API design limitation)
204 public void UnlockBits_Disposed ()
206 Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
207 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
208 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
210 Assert.Throws<ArgumentException> (() => bmp.UnlockBits (data));
211 // and that results in something like this when executed under Valgrind
212 // "40,000 bytes in 1 blocks are possibly lost in loss record 88 of 92"
216 public void UnlockBits_Null ()
218 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
219 Assert.Throws<ArgumentException> (() => bmp.UnlockBits (null));
223 public void LockBits_BitmapData_Null ()
225 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
226 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
227 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, null));
232 public void LockBits_32_32_BitmapData ()
234 BitmapData data = new BitmapData ();
235 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
236 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
237 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
238 Assert.AreEqual (100, data.Height, "Height");
239 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
240 Assert.AreEqual (400, data.Stride, "Stride");
241 Assert.AreEqual (100, data.Width, "Width");
242 bmp.UnlockBits (data);
247 public void LockBits_32_24_BitmapData ()
249 BitmapData data = new BitmapData ();
250 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
251 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
252 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
253 Assert.AreEqual (100, data.Height, "Height");
254 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
255 Assert.AreEqual (300, data.Stride, "Stride");
256 Assert.AreEqual (100, data.Width, "Width");
257 bmp.UnlockBits (data);
262 public void LockBits_24_24_BitmapData ()
264 BitmapData data = new BitmapData ();
265 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
266 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
267 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
268 Assert.AreEqual (100, data.Height, "Height");
269 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
270 Assert.AreEqual (300, data.Stride, "Stride");
271 Assert.AreEqual (100, data.Width, "Width");
272 bmp.UnlockBits (data);
277 public void LockBits_24_32_BitmapData ()
279 BitmapData data = new BitmapData ();
280 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
281 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
282 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
283 Assert.AreEqual (100, data.Height, "Height");
284 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
285 Assert.AreEqual (400, data.Stride, "Stride");
286 Assert.AreEqual (100, data.Width, "Width");
287 bmp.UnlockBits (data);
292 public void Format1bppIndexed ()
294 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
295 Color c = bmp.GetPixel (0, 0);
296 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
297 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
302 public void Format4bppIndexed ()
304 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
305 Color c = bmp.GetPixel (0, 0);
306 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
307 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
312 public void Format8bppIndexed ()
314 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
315 Color c = bmp.GetPixel (0, 0);
316 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
317 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
322 [Category ("NotWorking")] // libgdiplus doesn't support this format
323 public void Format16bppGrayScale ()
325 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format16bppGrayScale)) {
326 // and MS GDI+ support seems quite limited too
327 Assert.Throws<ArgumentException> (() => bmp.GetPixel (0, 0));
331 private void FormatTest (PixelFormat format)
333 bool alpha = Image.IsAlphaPixelFormat (format);
334 int size = Image.GetPixelFormatSize (format) / 8 * 2;
335 using (Bitmap bmp = new Bitmap (2, 1, format)) {
336 Color a = Color.FromArgb (128, 64, 32, 16);
337 Color b = Color.FromArgb (192, 96, 48, 24);
338 bmp.SetPixel (0, 0, a);
339 bmp.SetPixel (1, 0, b);
340 Color c = bmp.GetPixel (0, 0);
341 Color d = bmp.GetPixel (1, 0);
343 Assert.AreEqual (255, c.A, "0,0-16bpp-A");
344 Assert.AreEqual (66, c.R, "0,0-16bpp-R");
345 if (format == PixelFormat.Format16bppRgb565) {
346 Assert.AreEqual (32, c.G, "0,0-16bpp-G");
348 Assert.AreEqual (33, c.G, "0,0-16bpp-G");
350 Assert.AreEqual (16, c.B, "0,0-16bpp-B");
352 Assert.AreEqual (255, d.A, "1,0-16bpp-A");
353 Assert.AreEqual (99, d.R, "1,0-16bpp-R");
354 if (format == PixelFormat.Format16bppRgb565) {
355 Assert.AreEqual (48, d.G, "1,0-16bpp-G");
357 Assert.AreEqual (49, d.G, "1,0-16bpp-G");
359 Assert.AreEqual (24, d.B, "1,0-16bpp-B");
361 if (format == PixelFormat.Format32bppPArgb) {
362 Assert.AreEqual (a.A, c.A, "0,0-alpha-A");
363 // note sure why the -1
364 Assert.AreEqual (a.R - 1, c.R, "0,0-alpha-premultiplied-R");
365 Assert.AreEqual (a.G - 1, c.G, "0,0-alpha-premultiplied-G");
366 Assert.AreEqual (a.B - 1, c.B, "0,0-alpha-premultiplied-B");
368 Assert.AreEqual (b.A, d.A, "1,0-alpha-A");
369 // note sure why the -1
370 Assert.AreEqual (b.R - 1, d.R, "1,0-alpha-premultiplied-R");
371 Assert.AreEqual (b.G - 1, d.G, "1,0-alpha-premultiplied-G");
372 Assert.AreEqual (b.B - 1, d.B, "1,0-alpha-premultiplied-B");
374 Assert.AreEqual (a, c, "0,0-alpha");
375 Assert.AreEqual (b, d, "1,0-alpha");
378 Assert.AreEqual (Color.FromArgb (255, 64, 32, 16), c, "0,0-non-alpha");
379 Assert.AreEqual (Color.FromArgb (255, 96, 48, 24), d, "1,0-non-alpha");
381 BitmapData bd = bmp.LockBits (new Rectangle (0, 0, 2, 1), ImageLockMode.ReadOnly, format);
383 byte[] data = new byte[size];
384 Marshal.Copy (bd.Scan0, data, 0, size);
385 if (format == PixelFormat.Format32bppPArgb) {
386 Assert.AreEqual (Math.Ceiling ((float)c.B * c.A / 255), data[0], "0.alpha-premultiplied-B");
387 Assert.AreEqual (Math.Ceiling ((float)c.G * c.A / 255), data[1], "0.alpha-premultiplied-R");
388 Assert.AreEqual (Math.Ceiling ((float)c.R * c.A / 255), data[2], "0.alpha-premultiplied-G");
389 Assert.AreEqual (c.A, data[3], "0.alpha-A");
390 Assert.AreEqual (Math.Ceiling ((float)d.B * d.A / 255), data[4], "1.alpha-premultiplied-B");
391 Assert.AreEqual (Math.Ceiling ((float)d.G * d.A / 255), data[5], "1.alpha-premultiplied-R");
392 Assert.AreEqual (Math.Ceiling ((float)d.R * d.A / 255), data[6], "1.alpha-premultiplied-G");
393 Assert.AreEqual (d.A, data[7], "1.alpha-A");
394 } else if (size == 4) {
397 case PixelFormat.Format16bppRgb565:
398 Assert.AreEqual (2, data[n++], "0");
399 Assert.AreEqual (65, data[n++], "1");
400 Assert.AreEqual (131, data[n++], "2");
401 Assert.AreEqual (97, data[n++], "3");
403 case PixelFormat.Format16bppArgb1555:
404 Assert.AreEqual (130, data[n++], "0");
405 Assert.AreEqual (160, data[n++], "1");
406 Assert.AreEqual (195, data[n++], "2");
407 Assert.AreEqual (176, data[n++], "3");
409 case PixelFormat.Format16bppRgb555:
410 Assert.AreEqual (130, data[n++], "0");
411 Assert.AreEqual (32, data[n++], "1");
412 Assert.AreEqual (195, data[n++], "2");
413 Assert.AreEqual (48, data[n++], "3");
418 Assert.AreEqual (c.B, data[n++], "0.B");
419 Assert.AreEqual (c.G, data[n++], "0.R");
420 Assert.AreEqual (c.R, data[n++], "0.G");
422 Assert.AreEqual (c.A, data[n++], "0.A");
423 Assert.AreEqual (d.B, data[n++], "1.B");
424 Assert.AreEqual (d.G, data[n++], "1.R");
425 Assert.AreEqual (d.R, data[n++], "1.G");
427 Assert.AreEqual (d.A, data[n++], "1.A");
437 [Category ("NotWorking")] // libgdiplus doesn't support this format
438 public void Format16bppArgb1555 ()
440 FormatTest (PixelFormat.Format16bppArgb1555);
444 [Category ("NotWorking")] // GetPixel is a few bits off
445 public void Format16bppRgb555 ()
447 FormatTest (PixelFormat.Format16bppRgb555);
451 [Category ("NotWorking")] // GetPixel is a few bits off
452 public void Format16bppRgb565 ()
454 FormatTest (PixelFormat.Format16bppRgb565);
458 public void Format32bppArgb ()
460 FormatTest (PixelFormat.Format32bppArgb);
464 [Category ("NotWorking")] // I'm not sure we're handling this format anywhere (Cairo itself use it)
465 public void Format32bppPArgb ()
467 FormatTest (PixelFormat.Format32bppPArgb);
471 public void Format32bppRgb ()
473 FormatTest (PixelFormat.Format32bppRgb);
477 public void Format24bppRgb ()
479 FormatTest (PixelFormat.Format24bppRgb);
482 /* Get the output directory depending on the runtime and location*/
483 public static string getOutSubDir()
487 if (Environment.GetEnvironmentVariable("MSNet")==null)
492 sRslt = Path.GetFullPath (sSub);
494 if (Directory.Exists(sRslt) == false)
495 sRslt = "Test/System.Drawing/" + sSub;
497 if (sRslt.Length > 0)
498 if (sRslt[sRslt.Length-1] != '\\' && sRslt[sRslt.Length-1] != '/')
504 /* Get the input directory depending on the runtime*/
505 public static string getInFile(string file)
507 string sRslt = Path.GetFullPath ("../System.Drawing/" + file);
508 if (!File.Exists (sRslt))
509 sRslt = "Test/System.Drawing/" + file;
513 // note: this test fails when saving (for the same reason) on Mono and MS.NET
515 public void MakeTransparent()
517 string sInFile = getInFile("bitmaps/maketransparent.bmp");
518 string sOutFile = getOutSubDir() + "transparent.bmp";
520 Bitmap bmp = new Bitmap(sInFile);
522 bmp.MakeTransparent();
525 Color color = bmp.GetPixel(1,1);
526 Assert.AreEqual (Color.Black.R, color.R);
527 Assert.AreEqual (Color.Black.G, color.G);
528 Assert.AreEqual (Color.Black.B, color.B);
534 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
535 Rectangle rect = new Rectangle(0,0,50,50);
536 Bitmap bmp = new Bitmap(sInFile);
538 Bitmap bmpNew = bmp.Clone (rect, PixelFormat.Format32bppArgb);
539 Color colororg0 = bmp.GetPixel(0,0);
540 Color colororg50 = bmp.GetPixel(49,49);
541 Color colornew0 = bmpNew.GetPixel(0,0);
542 Color colornew50 = bmpNew.GetPixel(49,49);
544 Assert.AreEqual (colororg0, colornew0);
545 Assert.AreEqual (colororg50, colornew50);
549 public void CloneImage()
551 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
552 Bitmap bmp = new Bitmap(sInFile);
554 Bitmap bmpNew = (Bitmap) bmp.Clone ();
556 Assert.AreEqual (bmp.Width, bmpNew.Width);
557 Assert.AreEqual (bmp.Height, bmpNew.Height);
558 Assert.AreEqual (bmp.PixelFormat, bmpNew.PixelFormat);
565 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
566 Bitmap bmp = new Bitmap(sInFile);
567 int cnt = bmp.GetFrameCount(FrameDimension.Page);
568 int active = bmp.SelectActiveFrame (FrameDimension.Page, 0);
570 Assert.AreEqual (1, cnt);
571 Assert.AreEqual (0, active);
575 public void FileDoesNotExists ()
577 Assert.Throws<ArgumentException> (() => new Bitmap ("FileDoesNotExists.jpg"));
580 static string ByteArrayToString(byte[] arrInput)
583 StringBuilder sOutput = new StringBuilder(arrInput.Length);
584 for (i=0;i < arrInput.Length -1; i++)
586 sOutput.Append(arrInput[i].ToString("X2"));
588 return sOutput.ToString();
592 public string RotateBmp (Bitmap src, RotateFlipType rotate)
594 int width = 150, height = 150, index = 0;
595 byte[] pixels = new byte [width * height * 3];
600 bmp_rotate = src.Clone (new RectangleF (0,0, width, height), PixelFormat.Format32bppArgb);
601 bmp_rotate.RotateFlip (rotate);
603 for (int y = 0; y < height; y++) {
604 for (int x = 0; x < width; x++) {
605 clr = bmp_rotate.GetPixel (x,y);
606 pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++] = clr.B;
610 hash = new MD5CryptoServiceProvider().ComputeHash (pixels);
611 return ByteArrayToString (hash);
613 public string RotateIndexedBmp (Bitmap src, RotateFlipType type)
617 switch (src.PixelFormat)
619 case PixelFormat.Format1bppIndexed: pixels_per_byte = 8; break;
620 case PixelFormat.Format4bppIndexed: pixels_per_byte = 2; break;
621 case PixelFormat.Format8bppIndexed: pixels_per_byte = 1; break;
623 default: throw new Exception("Cannot pass a bitmap of format " + src.PixelFormat + " to RotateIndexedBmp");
626 Bitmap test = src.Clone () as Bitmap;
628 test.RotateFlip (type);
630 BitmapData data = null;
635 data = test.LockBits (new Rectangle (0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat);
637 int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte;
638 pixel_data = new byte[data.Height * scan_size];
640 for (int y=0; y < data.Height; y++) {
641 IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64 ());
642 int dest_offset = y * scan_size;
643 for (int x=0; x < scan_size; x++)
644 pixel_data[dest_offset + x] = Marshal.ReadByte (src_ptr, x);
651 try { test.UnlockBits(data); } catch {}
653 try { test.Dispose(); } catch {}
657 if (pixel_data == null)
660 byte[] hash = new MD5CryptoServiceProvider().ComputeHash (pixel_data);
661 return ByteArrayToString (hash);
666 Rotate bitmap in diffent ways, and check the result
672 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
673 Bitmap bmp = new Bitmap(sInFile);
675 Assert.AreEqual ("312958A3C67402E1299413794988A3", RotateBmp (bmp, RotateFlipType.Rotate90FlipNone));
676 Assert.AreEqual ("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp (bmp, RotateFlipType.Rotate180FlipNone));
677 Assert.AreEqual ("15AD2ADBDC7090C0EC744D0F7ACE2F", RotateBmp (bmp, RotateFlipType.Rotate270FlipNone));
678 Assert.AreEqual ("2E10FEC1F4FD64ECC51D7CE68AEB18", RotateBmp (bmp, RotateFlipType.RotateNoneFlipX));
679 Assert.AreEqual ("E63204779B566ED01162B90B49BD9E", RotateBmp (bmp, RotateFlipType.Rotate90FlipX));
680 Assert.AreEqual ("B1ECB17B5093E13D04FF55CFCF7763", RotateBmp (bmp, RotateFlipType.Rotate180FlipX));
681 Assert.AreEqual ("71A173882C16755D86F4BC26532374", RotateBmp (bmp, RotateFlipType.Rotate270FlipX));
686 Rotate 1- and 4-bit bitmaps in different ways and check the
687 resulting pixels using MD5
690 public void Rotate1bit4bit()
692 if ((Environment.OSVersion.Platform != (PlatformID)4)
693 && (Environment.OSVersion.Platform != (PlatformID)128))
694 Assert.Ignore("This does not work with Microsoft's GDIPLUS.DLL due to off-by-1 errors in their GdipBitmapRotateFlip function.");
697 getInFile ("bitmaps/1bit.png"),
698 getInFile ("bitmaps/4bit.png")
701 StringBuilder md5s = new StringBuilder();
703 foreach (string file in files)
704 using (Bitmap bmp = new Bitmap(file))
705 foreach (RotateFlipType type in Enum.GetValues (typeof(RotateFlipType)))
706 md5s.Append (RotateIndexedBmp (bmp, type));
708 using (StreamWriter writer = new StreamWriter("/tmp/md5s.txt"))
709 writer.WriteLine(md5s);
712 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit RotateNoneFlipNone
713 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit Rotate180FlipXY
714 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate90FlipNone
715 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate270FlipXY
716 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit Rotate180FlipNone
717 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit RotateNoneFlipXY
718 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate270FlipNone
719 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate90FlipXY
720 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit RotateNoneFlipX
721 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit Rotate180FlipY
722 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate90FlipX
723 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate270FlipY
724 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit Rotate180FlipX
725 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit RotateNoneFlipY
726 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate270FlipX
727 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate90FlipY
728 "3CC874B571902366AACED5D619E87D" + // 4-bit RotateNoneFlipNone
729 "3CC874B571902366AACED5D619E87D" + // 4-bit Rotate180FlipXY
730 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate90FlipNone
731 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate270FlipXY
732 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit Rotate180FlipNone
733 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit RotateNoneFlipXY
734 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate270FlipNone
735 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate90FlipXY
736 "545876C99ACF833E69FBFFBF436034" + // 4-bit RotateNoneFlipX
737 "545876C99ACF833E69FBFFBF436034" + // 4-bit Rotate180FlipY
738 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate90FlipX
739 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate270FlipY
740 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit Rotate180FlipX
741 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit RotateNoneFlipY
742 "B6B6245796C836923ABAABDF368B29" + // 4-bit Rotate270FlipX
743 "B6B6245796C836923ABAABDF368B29", // 4-bit Rotate90FlipY
747 private Bitmap CreateBitmap (int width, int height, PixelFormat fmt)
749 Bitmap bmp = new Bitmap (width, height, fmt);
750 using (Graphics gr = Graphics.FromImage (bmp)) {
751 Color c = Color.FromArgb (255, 100, 200, 250);
752 for (int x = 1; x < 80; x++) {
753 bmp.SetPixel (x, 1, c);
754 bmp.SetPixel (x, 2, c);
755 bmp.SetPixel (x, 78, c);
756 bmp.SetPixel (x, 79, c);
758 for (int y = 3; y < 78; y++) {
759 bmp.SetPixel (1, y, c);
760 bmp.SetPixel (2, y, c);
761 bmp.SetPixel (78, y, c);
762 bmp.SetPixel (79, y, c);
768 private byte[] HashPixels (Bitmap bmp)
770 int len = bmp.Width * bmp.Height * 4;
772 byte[] pixels = new byte [len];
774 for (int y = 0; y < bmp.Height; y++) {
775 for (int x = 0; x < bmp.Width; x++) {
776 Color clr = bmp.GetPixel (x, y);
777 pixels[index++] = clr.R;
778 pixels[index++] = clr.G;
779 pixels[index++] = clr.B;
782 return MD5.Create ().ComputeHash (pixels);
785 private byte[] HashLock (Bitmap bmp, int width, int height, PixelFormat fmt, ImageLockMode mode)
787 int len = bmp.Width * bmp.Height * 4;
788 byte[] pixels = new byte[len];
789 BitmapData bd = bmp.LockBits (new Rectangle (0, 0, width, height), mode, fmt);
792 int bbps = Image.GetPixelFormatSize (fmt);
793 long pos = bd.Scan0.ToInt64 ();
794 byte[] btv = new byte[1];
795 for (int y = 0; y < bd.Height; y++) {
796 for (int x = 0; x < bd.Width; x++) {
799 for (int bt = 0; bt < bbps / 8; bt++, index++) {
801 cur += y * bd.Stride;
804 Marshal.Copy ((IntPtr) cur, btv, 0, 1);
805 pixels[index] = btv[0];
807 /* Make change of all the colours = 250 to 10*/
810 Marshal.Copy (btv, 0, (IntPtr) cur, 1);
816 for (int i = index; i < len; i++)
822 return MD5.Create ().ComputeHash (pixels);
826 Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns
827 firsts, changes them, and then using GetPixel does another check of the changes.
828 The results match the .Net framework
830 private static byte[] DefaultBitmapHash = new byte[] { 0xD8, 0xD3, 0x68, 0x9C, 0x86, 0x7F, 0xB6, 0xA0, 0x76, 0xD6, 0x00, 0xEF, 0xFF, 0xE5, 0x8E, 0x1B };
831 private static byte[] FinalWholeBitmapHash = new byte[] { 0x5F, 0x52, 0x98, 0x37, 0xE3, 0x94, 0xE1, 0xA6, 0x06, 0x6C, 0x5B, 0xF1, 0xA9, 0xC2, 0xA9, 0x43 };
834 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Whole ()
836 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
837 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
838 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
839 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
840 Assert.AreEqual (expected, actual, "Full-Format32bppArgb");
841 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
846 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Whole ()
848 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
849 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
850 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
851 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
852 Assert.AreEqual (expected, actual, "Full-Format32bppPArgb");
853 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
858 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Whole ()
860 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
861 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
862 byte[] expected = { 0xC0, 0x28, 0xB5, 0x2E, 0x86, 0x90, 0x6F, 0x37, 0x09, 0x5F, 0x49, 0xA4, 0x91, 0xDA, 0xEE, 0xB9 };
863 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
864 Assert.AreEqual (expected, actual, "Full-Format32bppRgb");
865 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
870 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Whole ()
872 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
873 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
874 byte[] expected = { 0xA7, 0xB2, 0x50, 0x04, 0x11, 0x12, 0x64, 0x68, 0x6B, 0x7D, 0x2F, 0x6E, 0x69, 0x24, 0xCB, 0x14 };
875 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
876 Assert.AreEqual (expected, actual, "Full-Format24bppRgb");
877 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
881 private static byte[] FinalPartialBitmapHash = new byte[] { 0xED, 0xD8, 0xDC, 0x9B, 0x44, 0x00, 0x22, 0x9B, 0x07, 0x06, 0x4A, 0x21, 0x70, 0xA7, 0x31, 0x1D };
884 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Partial ()
886 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
887 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
888 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
889 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
890 Assert.AreEqual (expected, actual, "Partial-Format32bppArgb");
891 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
896 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Partial ()
898 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
899 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
900 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
901 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
902 Assert.AreEqual (expected, actual, "Partial-Format32bppPArgb");
903 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
908 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Partial ()
910 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
911 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
912 byte[] expected = { 0x72, 0x33, 0x09, 0x67, 0x53, 0x65, 0x38, 0xF9, 0xE4, 0x58, 0xE1, 0x0A, 0xAA, 0x6A, 0xCC, 0xB8 };
913 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
914 Assert.AreEqual (expected, actual, "Partial-Format32bppRgb");
915 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
920 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Partial ()
922 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
923 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
924 byte[] expected = { 0x4D, 0x39, 0x21, 0x88, 0xC2, 0x17, 0x14, 0x5F, 0x89, 0x9E, 0x02, 0x75, 0xF3, 0x64, 0xD8, 0xF0 };
925 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
926 Assert.AreEqual (expected, actual, "Partial-Format24bppRgb");
927 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
932 Tests the LockBitmap and UnlockBitmap functions, specifically the copying
933 of bitmap data in the directions indicated by the ImageLockMode.
936 public void LockUnlockBitmap ()
942 Color red = Color.FromArgb (Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B);
943 Color blue = Color.FromArgb (Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B);
945 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppRgb)) {
946 bmp.SetPixel (0, 0, red);
947 pixel_colour = bmp.GetPixel (0, 0);
948 Assert.AreEqual (red, pixel_colour, "Set/Get-Red");
950 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
952 pixel_value = Marshal.ReadByte (data.Scan0, 0);
953 pixel_value |= Marshal.ReadByte (data.Scan0, 1) << 8;
954 pixel_value |= Marshal.ReadByte (data.Scan0, 2) << 16;
955 pixel_value |= Marshal.ReadByte (data.Scan0, 3) << 24;
957 pixel_colour = Color.FromArgb (pixel_value);
958 // Disregard alpha information in the test
959 pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
960 Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Original");
962 // write blue but we're locked in read-only...
963 Marshal.WriteByte (data.Scan0, 0, blue.B);
964 Marshal.WriteByte (data.Scan0, 1, blue.G);
965 Marshal.WriteByte (data.Scan0, 2, blue.R);
966 Marshal.WriteByte (data.Scan0, 3, blue.A);
969 bmp.UnlockBits (data);
970 pixel_colour = bmp.GetPixel (0, 0);
971 // Disregard alpha information in the test
972 pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
973 // ...so we still read red after unlocking
974 Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Unlocked");
977 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
980 Marshal.WriteByte (data.Scan0, 0, blue.B);
981 Marshal.WriteByte (data.Scan0, 1, blue.G);
982 Marshal.WriteByte (data.Scan0, 2, blue.R);
983 Marshal.WriteByte (data.Scan0, 3, blue.A);
986 bmp.UnlockBits (data);
987 pixel_colour = bmp.GetPixel (0, 0);
988 // Disregard alpha information in the test
989 pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
991 Assert.AreEqual (blue, pixel_colour, "32RGB/32ARGB-ReadWrite-Blue-Unlock");
995 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppArgb)) {
996 bmp.SetPixel (0, 0, red);
998 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
1000 byte b = Marshal.ReadByte (data.Scan0, 0);
1001 byte g = Marshal.ReadByte (data.Scan0, 1);
1002 byte r = Marshal.ReadByte (data.Scan0, 2);
1003 pixel_colour = Color.FromArgb (red.A, r, g, b);
1004 Assert.AreEqual (red, pixel_colour, "32ARGB/24RGB-ReadOnly-Red-Original");
1005 // write blue but we're locked in read-only...
1006 Marshal.WriteByte (data.Scan0, 0, blue.B);
1007 Marshal.WriteByte (data.Scan0, 1, blue.G);
1008 Marshal.WriteByte (data.Scan0, 2, blue.R);
1011 bmp.UnlockBits (data);
1012 // ...so we still read red after unlocking
1013 Assert.AreEqual (red, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadOnly-Red-Unlock");
1016 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
1019 Marshal.WriteByte (data.Scan0, 0, blue.B);
1020 Marshal.WriteByte (data.Scan0, 1, blue.G);
1021 Marshal.WriteByte (data.Scan0, 2, blue.R);
1024 bmp.UnlockBits (data);
1026 Assert.AreEqual (blue, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadWrite-Blue-Unlock");
1031 public void DefaultFormat1 ()
1033 using (Bitmap bmp = new Bitmap (20, 20)) {
1034 Assert.AreEqual (ImageFormat.MemoryBmp, bmp.RawFormat);
1039 public void DefaultFormat2 ()
1041 string filename = Path.GetTempFileName ();
1042 using (Bitmap bmp = new Bitmap (20, 20)) {
1043 bmp.Save (filename);
1046 using (Bitmap other = new Bitmap (filename)) {
1047 Assert.AreEqual (ImageFormat.Png, other.RawFormat);
1049 File.Delete (filename);
1053 public void BmpDataStride1 ()
1055 Bitmap bmp = new Bitmap (184, 184, PixelFormat.Format1bppIndexed);
1056 BitmapData data = bmp.LockBits (new Rectangle (0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
1058 Assert.AreEqual (24, data.Stride);
1060 bmp.UnlockBits (data);
1065 private Stream Serialize (object o)
1067 MemoryStream ms = new MemoryStream ();
1068 IFormatter formatter = new BinaryFormatter ();
1069 formatter.Serialize (ms, o);
1074 private object Deserialize (Stream s)
1076 return new BinaryFormatter ().Deserialize (s);
1080 public void Serialize_Icon ()
1082 // this cause a problem with resgen, see http://bugzilla.ximian.com/show_bug.cgi?id=80565
1083 string filename = getInFile ("bitmaps/16x16x16.ico");
1084 using (Bitmap icon = new Bitmap (filename)) {
1085 using (Stream s = Serialize (icon)) {
1086 using (Bitmap copy = (Bitmap)Deserialize (s)) {
1087 Assert.AreEqual (icon.Height, copy.Height, "Height");
1088 Assert.AreEqual (icon.Width, copy.Width, "Width");
1089 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1090 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1091 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1097 private Stream SoapSerialize (object o)
1099 MemoryStream ms = new MemoryStream ();
1100 IFormatter formatter = new SoapFormatter ();
1101 formatter.Serialize (ms, o);
1106 private object SoapDeserialize (Stream s)
1108 return new SoapFormatter ().Deserialize (s);
1112 public void SoapSerialize_Icon ()
1114 string filename = getInFile ("bitmaps/16x16x16.ico");
1115 using (Bitmap icon = new Bitmap (filename)) {
1116 using (Stream s = SoapSerialize (icon)) {
1117 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1118 Assert.AreEqual (icon.Height, copy.Height, "Height");
1119 Assert.AreEqual (icon.Width, copy.Width, "Width");
1120 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1121 Assert.AreEqual (16, icon.Palette.Entries.Length, "icon Palette");
1122 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1123 Assert.AreEqual (0, copy.Palette.Entries.Length, "copy Palette");
1124 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1131 public void SoapSerialize_Bitmap8 ()
1133 string filename = getInFile ("bitmaps/almogaver8bits.bmp");
1134 using (Bitmap bmp = new Bitmap (filename)) {
1135 using (Stream s = SoapSerialize (bmp)) {
1136 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1137 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1138 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1139 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1140 Assert.AreEqual (256, copy.Palette.Entries.Length, "Palette");
1141 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1148 public void SoapSerialize_Bitmap24 ()
1150 string filename = getInFile ("bitmaps/almogaver24bits.bmp");
1151 using (Bitmap bmp = new Bitmap (filename)) {
1152 using (Stream s = SoapSerialize (bmp)) {
1153 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1154 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1155 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1156 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1157 Assert.AreEqual (bmp.Palette.Entries.Length, copy.Palette.Entries.Length, "Palette");
1158 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1165 [Category ("NotWorking")] // http://bugzilla.ximian.com/show_bug.cgi?id=80558
1166 public void XmlSerialize ()
1168 new XmlSerializer (typeof (Bitmap));
1171 static int[] palette1 = {
1177 public void Format1bppIndexed_Palette ()
1179 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
1180 ColorPalette pal = bmp.Palette;
1181 Assert.AreEqual (2, pal.Entries.Length, "Length");
1182 for (int i = 0; i < pal.Entries.Length; i++) {
1183 Assert.AreEqual (palette1[i], pal.Entries[i].ToArgb (), i.ToString ());
1185 Assert.AreEqual (2, pal.Flags, "Flags");
1189 static int[] palette16 = {
1209 public void Format4bppIndexed_Palette ()
1211 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
1212 ColorPalette pal = bmp.Palette;
1213 Assert.AreEqual (16, pal.Entries.Length, "Length");
1214 for (int i = 0; i < pal.Entries.Length; i++) {
1215 Assert.AreEqual (palette16 [i], pal.Entries[i].ToArgb (), i.ToString ());
1217 Assert.AreEqual (0, pal.Flags, "Flags");
1221 static int[] palette256 = {
1481 public void Format8bppIndexed_Palette ()
1483 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
1484 ColorPalette pal = bmp.Palette;
1485 Assert.AreEqual (256, pal.Entries.Length, "Length");
1486 for (int i = 0; i < pal.Entries.Length; i++) {
1487 Assert.AreEqual (palette256[i], pal.Entries[i].ToArgb (), i.ToString ());
1489 Assert.AreEqual (4, pal.Flags, "Flags");
1494 public void XmlSerialization ()
1496 new XmlSerializer (typeof (Bitmap));
1500 public void BitmapImageCtor ()
1502 Assert.Throws<NullReferenceException> (() => new Bitmap ((Image) null));
1506 public void BitmapImageSizeCtor ()
1508 Assert.Throws<ArgumentException> (() => new Bitmap ((Image) null, Size.Empty));
1512 public void BitmapImageIntIntCtor ()
1514 Assert.Throws<ArgumentException> (() => new Bitmap ((Image) null, Int32.MinValue, Int32.MaxValue));
1518 public void BitmapIntIntCtor ()
1520 Assert.Throws<ArgumentException> (() => new Bitmap (Int32.MinValue, Int32.MaxValue));
1524 public void BitmapIntIntGraphicCtor ()
1526 Assert.Throws<ArgumentNullException> (() => new Bitmap (1, 1, null));
1530 public void BitmapIntIntPixelFormatCtor ()
1532 Assert.Throws<ArgumentException> (() => new Bitmap (Int32.MinValue, Int32.MaxValue, PixelFormat.Format1bppIndexed));
1536 public void BitmapStreamCtor ()
1538 Assert.Throws<ArgumentException> (() => new Bitmap ((Stream) null));
1542 public void BitmapStreamBoolCtor ()
1544 Assert.Throws<ArgumentException> (() => new Bitmap ((Stream) null, true));
1548 public void BitmapStringCtor ()
1550 Assert.Throws<ArgumentNullException> (() => new Bitmap ((string) null));
1554 public void BitmapStringBoolCtor ()
1556 Assert.Throws<ArgumentNullException> (() => new Bitmap ((string) null, false));
1560 public void BitmapTypeStringCtor1 ()
1562 Assert.Throws<NullReferenceException> (() => new Bitmap ((Type) null, "mono"));
1566 public void BitmapTypeStringCtor2 ()
1568 Assert.Throws<ArgumentException> (() => new Bitmap (typeof (Bitmap), null));
1571 private void SetResolution (float x, float y)
1573 using (Bitmap bmp = new Bitmap (1, 1)) {
1574 bmp.SetResolution (x, y);
1579 public void SetResolution_Zero ()
1581 Assert.Throws<ArgumentException> (() => SetResolution (0.0f, 0.0f));
1585 public void SetResolution_Negative_X ()
1587 Assert.Throws<ArgumentException> (() => SetResolution (-1.0f, 1.0f));
1591 public void SetResolution_Negative_Y ()
1593 Assert.Throws<ArgumentException> (() => SetResolution (1.0f, -1.0f));
1597 public void SetResolution_MaxValue ()
1599 SetResolution (Single.MaxValue, Single.MaxValue);
1603 public void SetResolution_PositiveInfinity ()
1605 SetResolution (Single.PositiveInfinity, Single.PositiveInfinity);
1609 public void SetResolution_NaN ()
1611 Assert.Throws<ArgumentException> (() => SetResolution (Single.NaN, Single.NaN));
1615 public void SetResolution_NegativeInfinity ()
1617 Assert.Throws<ArgumentException> (() => SetResolution (Single.NegativeInfinity, Single.NegativeInfinity));
1622 public class BitmapFullTrustTest {
1624 public void BitmapIntIntIntPixelFormatIntPtrCtor ()
1626 new Bitmap (1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero);
1629 // BitmapFromHicon## is *almost* the same as IconTest.Icon##ToBitmap except
1630 // for the Flags property
1632 private void HiconTest (string msg, Bitmap b, int size)
1634 Assert.AreEqual (PixelFormat.Format32bppArgb, b.PixelFormat, msg + ".PixelFormat");
1635 // unlike the GDI+ icon decoder the palette isn't kept
1636 Assert.AreEqual (0, b.Palette.Entries.Length, msg + ".Palette");
1637 Assert.AreEqual (size, b.Height, msg + ".Height");
1638 Assert.AreEqual (size, b.Width, msg + ".Width");
1639 Assert.IsTrue (b.RawFormat.Equals (ImageFormat.MemoryBmp), msg + ".RawFormat");
1640 Assert.AreEqual (335888, b.Flags, msg + ".Flags");
1644 public void Hicon16 ()
1648 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/16x16x16.ico"))) {
1650 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1651 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1652 hicon = bitmap.GetHicon ();
1655 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1656 // hicon survives bitmap and icon disposal
1657 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1662 public void Hicon32 ()
1666 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/32x32x16.ico"))) {
1668 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1669 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1670 hicon = bitmap.GetHicon ();
1673 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1674 // hicon survives bitmap and icon disposal
1675 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1680 [Category ("NotWorking")] // libgdiplus has lost track of the original 1bpp state
1681 public void Hicon48 ()
1683 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/48x48x1.ico"))) {
1684 // looks like 1bbp icons aren't welcome as bitmaps ;-)
1685 Assert.Throws<ArgumentException> (() => Bitmap.FromHicon (icon.Handle));
1690 public void Hicon64 ()
1694 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/64x64x256.ico"))) {
1696 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1697 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1698 hicon = bitmap.GetHicon ();
1701 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1702 // hicon survives bitmap and icon disposal
1703 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1708 public void Hicon96 ()
1712 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/96x96x256.ico"))) {
1714 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1715 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1716 hicon = bitmap.GetHicon ();
1719 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1720 // hicon survives bitmap and icon disposal
1721 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1726 public void HBitmap ()
1729 string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1730 using (Bitmap bitmap = new Bitmap (sInFile)) {
1731 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1732 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1733 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1734 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1735 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1736 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1737 hbitmap = bitmap.GetHbitmap ();
1739 // hbitmap survives original bitmap disposal
1740 using (Image image = Image.FromHbitmap (hbitmap)) {
1741 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "FromHbitmap.PixelFormat");
1742 Assert.AreEqual (0, image.Palette.Entries.Length, "FromHbitmap.Palette");
1743 Assert.AreEqual (183, image.Height, "FromHbitmap.Height");
1744 Assert.AreEqual (173, image.Width, "FromHbitmap.Width");
1745 Assert.AreEqual (335888, image.Flags, "FromHbitmap.Flags");
1746 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "FromHbitmap.RawFormat");
1751 public void CreateMultipleBitmapFromSameHBITMAP ()
1754 string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1755 using (Bitmap bitmap = new Bitmap (sInFile)) {
1756 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1757 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1758 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1759 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1760 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1761 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1762 hbitmap = bitmap.GetHbitmap ();
1764 // hbitmap survives original bitmap disposal
1765 using (Image image = Image.FromHbitmap (hbitmap)) {
1766 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "1.PixelFormat");
1767 Assert.AreEqual (0, image.Palette.Entries.Length, "1.Palette");
1768 Assert.AreEqual (183, image.Height, "1.Height");
1769 Assert.AreEqual (173, image.Width, "1.Width");
1770 Assert.AreEqual (335888, image.Flags, "1.Flags");
1771 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "1.RawFormat");
1773 using (Image image2 = Image.FromHbitmap (hbitmap)) {
1774 //Assert.AreEqual (PixelFormat.Format32bppRgb, image2.PixelFormat, "2.PixelFormat");
1775 Assert.AreEqual (0, image2.Palette.Entries.Length, "2.Palette");
1776 Assert.AreEqual (183, image2.Height, "2.Height");
1777 Assert.AreEqual (173, image2.Width, "2.Width");
1778 Assert.AreEqual (335888, image2.Flags, "2.Flags");
1779 Assert.IsTrue (image2.RawFormat.Equals (ImageFormat.MemoryBmp), "2.RawFormat");