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;
40 using System.Runtime.Serialization.Formatters.Soap;
42 using System.Security.Cryptography;
43 using System.Security.Permissions;
45 using System.Xml.Serialization;
46 using NUnit.Framework;
48 namespace MonoTests.System.Drawing {
51 public class TestBitmap {
54 public void TestPixels()
56 // Tests GetSetPixel/SetPixel
57 Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);
58 bmp.SetPixel(0,0,Color.FromArgb(255,128,128,128));
59 Color color = bmp.GetPixel(0,0);
61 Assert.AreEqual (Color.FromArgb(255,128,128,128), color);
63 bmp.SetPixel(99,99,Color.FromArgb(255,255,0,155));
64 Color color2 = bmp.GetPixel(99,99);
65 Assert.AreEqual (Color.FromArgb(255,255,0,155), color2);
69 public void LockBits_32_32_NonIndexedWrite ()
71 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
72 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
73 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
74 Assert.AreEqual (100, data.Height, "Height");
75 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
76 Assert.AreEqual (400, data.Stride, "Stride");
77 Assert.AreEqual (100, data.Width, "Width");
78 bmp.UnlockBits (data);
83 public void LockBits_32_24_NonIndexedWrite ()
85 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
86 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
87 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
88 Assert.AreEqual (100, data.Height, "Height");
89 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
90 Assert.AreEqual (300, data.Stride, "Stride");
91 Assert.AreEqual (100, data.Width, "Width");
92 bmp.UnlockBits (data);
97 public void LockBits_24_24_NonIndexedWrite ()
99 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
100 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
101 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
102 Assert.AreEqual (100, data.Height, "Height");
103 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
104 Assert.AreEqual (300, data.Stride, "Stride");
105 Assert.AreEqual (100, data.Width, "Width");
106 bmp.UnlockBits (data);
111 public void LockBits_24_32_NonIndexedWrite ()
113 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
114 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
115 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
116 Assert.AreEqual (100, data.Height, "Height");
117 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
118 Assert.AreEqual (400, data.Stride, "Stride");
119 Assert.AreEqual (100, data.Width, "Width");
120 bmp.UnlockBits (data);
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 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
134 public void LockBits_NonIndexedWrite_ToIndexed ()
136 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
137 BitmapData bd = new BitmapData ();
138 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
139 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, bd));
141 // test to see if there's a leak or not in this case
142 Assert.AreEqual (IntPtr.Zero, bd.Scan0, "Scan0");
147 public void LockBits_IndexedWrite_SameIndexedFormat ()
149 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format8bppIndexed)) {
150 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
151 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
152 Assert.AreEqual (100, data.Height, "Height");
153 Assert.AreEqual (PixelFormat.Format8bppIndexed, data.PixelFormat, "PixelFormat");
154 Assert.AreEqual (100, data.Stride, "Stride");
155 Assert.AreEqual (100, data.Width, "Width");
156 bmp.UnlockBits (data);
161 public void LockBits_ImageLockMode_Invalid ()
163 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
164 Rectangle r = new Rectangle (4, 4, 4, 4);
165 BitmapData data = bmp.LockBits (r, (ImageLockMode)0, PixelFormat.Format24bppRgb);
167 Assert.AreEqual (4, data.Height, "Height");
168 Assert.AreEqual (4, data.Width, "Width");
169 Assert.IsTrue (data.Stride >= 12, "Stride");
170 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
171 Assert.IsFalse (IntPtr.Zero.Equals (data.Scan0), "Scan0");
174 bmp.UnlockBits (data);
180 public void LockBits_Double ()
182 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format24bppRgb)) {
183 Rectangle r = new Rectangle (4, 4, 4, 4);
184 BitmapData data = bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
186 Assert.Throws<InvalidOperationException> (() => bmp.LockBits (r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb));
189 bmp.UnlockBits (data);
195 public void LockBits_Disposed ()
197 Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
198 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
200 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
204 [Category ("Valgrind")] // this test is known to leak memory (API design limitation)
205 public void UnlockBits_Disposed ()
207 Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb);
208 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
209 BitmapData data = bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
211 Assert.Throws<ArgumentException> (() => bmp.UnlockBits (data));
212 // and that results in something like this when executed under Valgrind
213 // "40,000 bytes in 1 blocks are possibly lost in loss record 88 of 92"
217 public void UnlockBits_Null ()
219 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
220 Assert.Throws<ArgumentException> (() => bmp.UnlockBits (null));
224 public void LockBits_BitmapData_Null ()
226 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
227 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
228 Assert.Throws<ArgumentException> (() => bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, null));
233 public void LockBits_32_32_BitmapData ()
235 BitmapData data = new BitmapData ();
236 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppRgb)) {
237 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
238 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
239 Assert.AreEqual (100, data.Height, "Height");
240 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
241 Assert.AreEqual (400, data.Stride, "Stride");
242 Assert.AreEqual (100, data.Width, "Width");
243 bmp.UnlockBits (data);
248 public void LockBits_32_24_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.Format24bppRgb, data);
254 Assert.AreEqual (100, data.Height, "Height");
255 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
256 Assert.AreEqual (300, data.Stride, "Stride");
257 Assert.AreEqual (100, data.Width, "Width");
258 bmp.UnlockBits (data);
263 public void LockBits_24_24_BitmapData ()
265 BitmapData data = new BitmapData ();
266 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format24bppRgb)) {
267 Rectangle rect = new Rectangle (0, 0, bmp.Width, bmp.Height);
268 bmp.LockBits (rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
269 Assert.AreEqual (100, data.Height, "Height");
270 Assert.AreEqual (PixelFormat.Format24bppRgb, data.PixelFormat, "PixelFormat");
271 Assert.AreEqual (300, data.Stride, "Stride");
272 Assert.AreEqual (100, data.Width, "Width");
273 bmp.UnlockBits (data);
278 public void LockBits_24_32_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.Format32bppRgb, data);
284 Assert.AreEqual (100, data.Height, "Height");
285 Assert.AreEqual (PixelFormat.Format32bppRgb, data.PixelFormat, "PixelFormat");
286 Assert.AreEqual (400, data.Stride, "Stride");
287 Assert.AreEqual (100, data.Width, "Width");
288 bmp.UnlockBits (data);
293 public void Format1bppIndexed ()
295 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
296 Color c = bmp.GetPixel (0, 0);
297 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
298 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
303 public void Format4bppIndexed ()
305 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
306 Color c = bmp.GetPixel (0, 0);
307 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
308 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
313 public void Format8bppIndexed ()
315 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
316 Color c = bmp.GetPixel (0, 0);
317 Assert.AreEqual (-16777216, c.ToArgb (), "Color");
318 Assert.Throws<InvalidOperationException> (() => bmp.SetPixel (0, 0, c));
323 [Category ("NotWorking")] // libgdiplus doesn't support this format
324 public void Format16bppGrayScale ()
326 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format16bppGrayScale)) {
327 // and MS GDI+ support seems quite limited too
328 Assert.Throws<ArgumentException> (() => bmp.GetPixel (0, 0));
332 private void FormatTest (PixelFormat format)
334 bool alpha = Image.IsAlphaPixelFormat (format);
335 int size = Image.GetPixelFormatSize (format) / 8 * 2;
336 using (Bitmap bmp = new Bitmap (2, 1, format)) {
337 Color a = Color.FromArgb (128, 64, 32, 16);
338 Color b = Color.FromArgb (192, 96, 48, 24);
339 bmp.SetPixel (0, 0, a);
340 bmp.SetPixel (1, 0, b);
341 Color c = bmp.GetPixel (0, 0);
342 Color d = bmp.GetPixel (1, 0);
344 Assert.AreEqual (255, c.A, "0,0-16bpp-A");
345 Assert.AreEqual (66, c.R, "0,0-16bpp-R");
346 if (format == PixelFormat.Format16bppRgb565) {
347 Assert.AreEqual (32, c.G, "0,0-16bpp-G");
349 Assert.AreEqual (33, c.G, "0,0-16bpp-G");
351 Assert.AreEqual (16, c.B, "0,0-16bpp-B");
353 Assert.AreEqual (255, d.A, "1,0-16bpp-A");
354 Assert.AreEqual (99, d.R, "1,0-16bpp-R");
355 if (format == PixelFormat.Format16bppRgb565) {
356 Assert.AreEqual (48, d.G, "1,0-16bpp-G");
358 Assert.AreEqual (49, d.G, "1,0-16bpp-G");
360 Assert.AreEqual (24, d.B, "1,0-16bpp-B");
362 if (format == PixelFormat.Format32bppPArgb) {
363 Assert.AreEqual (a.A, c.A, "0,0-alpha-A");
364 // note sure why the -1
365 Assert.AreEqual (a.R - 1, c.R, "0,0-alpha-premultiplied-R");
366 Assert.AreEqual (a.G - 1, c.G, "0,0-alpha-premultiplied-G");
367 Assert.AreEqual (a.B - 1, c.B, "0,0-alpha-premultiplied-B");
369 Assert.AreEqual (b.A, d.A, "1,0-alpha-A");
370 // note sure why the -1
371 Assert.AreEqual (b.R - 1, d.R, "1,0-alpha-premultiplied-R");
372 Assert.AreEqual (b.G - 1, d.G, "1,0-alpha-premultiplied-G");
373 Assert.AreEqual (b.B - 1, d.B, "1,0-alpha-premultiplied-B");
375 Assert.AreEqual (a, c, "0,0-alpha");
376 Assert.AreEqual (b, d, "1,0-alpha");
379 Assert.AreEqual (Color.FromArgb (255, 64, 32, 16), c, "0,0-non-alpha");
380 Assert.AreEqual (Color.FromArgb (255, 96, 48, 24), d, "1,0-non-alpha");
382 BitmapData bd = bmp.LockBits (new Rectangle (0, 0, 2, 1), ImageLockMode.ReadOnly, format);
384 byte[] data = new byte[size];
385 Marshal.Copy (bd.Scan0, data, 0, size);
386 if (format == PixelFormat.Format32bppPArgb) {
387 Assert.AreEqual (Math.Ceiling ((float)c.B * c.A / 255), data[0], "0.alpha-premultiplied-B");
388 Assert.AreEqual (Math.Ceiling ((float)c.G * c.A / 255), data[1], "0.alpha-premultiplied-R");
389 Assert.AreEqual (Math.Ceiling ((float)c.R * c.A / 255), data[2], "0.alpha-premultiplied-G");
390 Assert.AreEqual (c.A, data[3], "0.alpha-A");
391 Assert.AreEqual (Math.Ceiling ((float)d.B * d.A / 255), data[4], "1.alpha-premultiplied-B");
392 Assert.AreEqual (Math.Ceiling ((float)d.G * d.A / 255), data[5], "1.alpha-premultiplied-R");
393 Assert.AreEqual (Math.Ceiling ((float)d.R * d.A / 255), data[6], "1.alpha-premultiplied-G");
394 Assert.AreEqual (d.A, data[7], "1.alpha-A");
395 } else if (size == 4) {
398 case PixelFormat.Format16bppRgb565:
399 Assert.AreEqual (2, data[n++], "0");
400 Assert.AreEqual (65, data[n++], "1");
401 Assert.AreEqual (131, data[n++], "2");
402 Assert.AreEqual (97, data[n++], "3");
404 case PixelFormat.Format16bppArgb1555:
405 Assert.AreEqual (130, data[n++], "0");
406 Assert.AreEqual (160, data[n++], "1");
407 Assert.AreEqual (195, data[n++], "2");
408 Assert.AreEqual (176, data[n++], "3");
410 case PixelFormat.Format16bppRgb555:
411 Assert.AreEqual (130, data[n++], "0");
412 Assert.AreEqual (32, data[n++], "1");
413 Assert.AreEqual (195, data[n++], "2");
414 Assert.AreEqual (48, data[n++], "3");
419 Assert.AreEqual (c.B, data[n++], "0.B");
420 Assert.AreEqual (c.G, data[n++], "0.R");
421 Assert.AreEqual (c.R, data[n++], "0.G");
423 Assert.AreEqual (c.A, data[n++], "0.A");
424 Assert.AreEqual (d.B, data[n++], "1.B");
425 Assert.AreEqual (d.G, data[n++], "1.R");
426 Assert.AreEqual (d.R, data[n++], "1.G");
428 Assert.AreEqual (d.A, data[n++], "1.A");
438 [Category ("NotWorking")] // libgdiplus doesn't support this format
439 public void Format16bppArgb1555 ()
441 FormatTest (PixelFormat.Format16bppArgb1555);
445 [Category ("NotWorking")] // GetPixel is a few bits off
446 public void Format16bppRgb555 ()
448 FormatTest (PixelFormat.Format16bppRgb555);
452 [Category ("NotWorking")] // GetPixel is a few bits off
453 public void Format16bppRgb565 ()
455 FormatTest (PixelFormat.Format16bppRgb565);
459 public void Format32bppArgb ()
461 FormatTest (PixelFormat.Format32bppArgb);
465 [Category ("NotWorking")] // I'm not sure we're handling this format anywhere (Cairo itself use it)
466 public void Format32bppPArgb ()
468 FormatTest (PixelFormat.Format32bppPArgb);
472 public void Format32bppRgb ()
474 FormatTest (PixelFormat.Format32bppRgb);
478 public void Format24bppRgb ()
480 FormatTest (PixelFormat.Format24bppRgb);
483 /* Get the output directory depending on the runtime and location*/
484 public static string getOutSubDir()
488 if (Environment.GetEnvironmentVariable("MSNet")==null)
493 sRslt = Path.GetFullPath (sSub);
495 if (Directory.Exists(sRslt) == false)
496 sRslt = "Test/System.Drawing/" + sSub;
498 if (sRslt.Length > 0)
499 if (sRslt[sRslt.Length-1] != '\\' && sRslt[sRslt.Length-1] != '/')
505 /* Get the input directory depending on the runtime*/
506 public static string getInFile(string file)
508 string sRslt = Path.GetFullPath ("../System.Drawing/" + file);
509 if (!File.Exists (sRslt))
510 sRslt = "Test/System.Drawing/" + file;
514 // note: this test fails when saving (for the same reason) on Mono and MS.NET
516 public void MakeTransparent()
518 string sInFile = getInFile("bitmaps/maketransparent.bmp");
519 string sOutFile = getOutSubDir() + "transparent.bmp";
521 Bitmap bmp = new Bitmap(sInFile);
523 bmp.MakeTransparent();
526 Color color = bmp.GetPixel(1,1);
527 Assert.AreEqual (Color.Black.R, color.R);
528 Assert.AreEqual (Color.Black.G, color.G);
529 Assert.AreEqual (Color.Black.B, color.B);
535 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
536 Rectangle rect = new Rectangle(0,0,50,50);
537 Bitmap bmp = new Bitmap(sInFile);
539 Bitmap bmpNew = bmp.Clone (rect, PixelFormat.Format32bppArgb);
540 Color colororg0 = bmp.GetPixel(0,0);
541 Color colororg50 = bmp.GetPixel(49,49);
542 Color colornew0 = bmpNew.GetPixel(0,0);
543 Color colornew50 = bmpNew.GetPixel(49,49);
545 Assert.AreEqual (colororg0, colornew0);
546 Assert.AreEqual (colororg50, colornew50);
550 public void CloneImage()
552 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
553 Bitmap bmp = new Bitmap(sInFile);
555 Bitmap bmpNew = (Bitmap) bmp.Clone ();
557 Assert.AreEqual (bmp.Width, bmpNew.Width);
558 Assert.AreEqual (bmp.Height, bmpNew.Height);
559 Assert.AreEqual (bmp.PixelFormat, bmpNew.PixelFormat);
566 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
567 Bitmap bmp = new Bitmap(sInFile);
568 int cnt = bmp.GetFrameCount(FrameDimension.Page);
569 int active = bmp.SelectActiveFrame (FrameDimension.Page, 0);
571 Assert.AreEqual (1, cnt);
572 Assert.AreEqual (0, active);
576 public void FileDoesNotExists ()
578 Assert.Throws<ArgumentException> (() => new Bitmap ("FileDoesNotExists.jpg"));
581 static string ByteArrayToString(byte[] arrInput)
584 StringBuilder sOutput = new StringBuilder(arrInput.Length);
585 for (i=0;i < arrInput.Length -1; i++)
587 sOutput.Append(arrInput[i].ToString("X2"));
589 return sOutput.ToString();
593 public string RotateBmp (Bitmap src, RotateFlipType rotate)
595 int width = 150, height = 150, index = 0;
596 byte[] pixels = new byte [width * height * 3];
601 bmp_rotate = src.Clone (new RectangleF (0,0, width, height), PixelFormat.Format32bppArgb);
602 bmp_rotate.RotateFlip (rotate);
604 for (int y = 0; y < height; y++) {
605 for (int x = 0; x < width; x++) {
606 clr = bmp_rotate.GetPixel (x,y);
607 pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++] = clr.B;
611 hash = new MD5CryptoServiceProvider().ComputeHash (pixels);
612 return ByteArrayToString (hash);
614 public string RotateIndexedBmp (Bitmap src, RotateFlipType type)
618 switch (src.PixelFormat)
620 case PixelFormat.Format1bppIndexed: pixels_per_byte = 8; break;
621 case PixelFormat.Format4bppIndexed: pixels_per_byte = 2; break;
622 case PixelFormat.Format8bppIndexed: pixels_per_byte = 1; break;
624 default: throw new Exception("Cannot pass a bitmap of format " + src.PixelFormat + " to RotateIndexedBmp");
627 Bitmap test = src.Clone () as Bitmap;
629 test.RotateFlip (type);
631 BitmapData data = null;
636 data = test.LockBits (new Rectangle (0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat);
638 int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte;
639 pixel_data = new byte[data.Height * scan_size];
641 for (int y=0; y < data.Height; y++) {
642 IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64 ());
643 int dest_offset = y * scan_size;
644 for (int x=0; x < scan_size; x++)
645 pixel_data[dest_offset + x] = Marshal.ReadByte (src_ptr, x);
652 try { test.UnlockBits(data); } catch {}
654 try { test.Dispose(); } catch {}
658 if (pixel_data == null)
661 byte[] hash = new MD5CryptoServiceProvider().ComputeHash (pixel_data);
662 return ByteArrayToString (hash);
667 Rotate bitmap in diffent ways, and check the result
673 string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
674 Bitmap bmp = new Bitmap(sInFile);
676 Assert.AreEqual ("312958A3C67402E1299413794988A3", RotateBmp (bmp, RotateFlipType.Rotate90FlipNone));
677 Assert.AreEqual ("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp (bmp, RotateFlipType.Rotate180FlipNone));
678 Assert.AreEqual ("15AD2ADBDC7090C0EC744D0F7ACE2F", RotateBmp (bmp, RotateFlipType.Rotate270FlipNone));
679 Assert.AreEqual ("2E10FEC1F4FD64ECC51D7CE68AEB18", RotateBmp (bmp, RotateFlipType.RotateNoneFlipX));
680 Assert.AreEqual ("E63204779B566ED01162B90B49BD9E", RotateBmp (bmp, RotateFlipType.Rotate90FlipX));
681 Assert.AreEqual ("B1ECB17B5093E13D04FF55CFCF7763", RotateBmp (bmp, RotateFlipType.Rotate180FlipX));
682 Assert.AreEqual ("71A173882C16755D86F4BC26532374", RotateBmp (bmp, RotateFlipType.Rotate270FlipX));
687 Rotate 1- and 4-bit bitmaps in different ways and check the
688 resulting pixels using MD5
691 public void Rotate1bit4bit()
693 if ((Environment.OSVersion.Platform != (PlatformID)4)
694 && (Environment.OSVersion.Platform != (PlatformID)128))
695 Assert.Ignore("This does not work with Microsoft's GDIPLUS.DLL due to off-by-1 errors in their GdipBitmapRotateFlip function.");
698 getInFile ("bitmaps/1bit.png"),
699 getInFile ("bitmaps/4bit.png")
702 StringBuilder md5s = new StringBuilder();
704 foreach (string file in files)
705 using (Bitmap bmp = new Bitmap(file))
706 foreach (RotateFlipType type in Enum.GetValues (typeof(RotateFlipType)))
707 md5s.Append (RotateIndexedBmp (bmp, type));
709 using (StreamWriter writer = new StreamWriter("/tmp/md5s.txt"))
710 writer.WriteLine(md5s);
713 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit RotateNoneFlipNone
714 "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit Rotate180FlipXY
715 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate90FlipNone
716 "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate270FlipXY
717 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit Rotate180FlipNone
718 "64AE60858A02228F7B1B18C7812FB6" + // 1-bit RotateNoneFlipXY
719 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate270FlipNone
720 "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate90FlipXY
721 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit RotateNoneFlipX
722 "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit Rotate180FlipY
723 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate90FlipX
724 "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate270FlipY
725 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit Rotate180FlipX
726 "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit RotateNoneFlipY
727 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate270FlipX
728 "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate90FlipY
729 "3CC874B571902366AACED5D619E87D" + // 4-bit RotateNoneFlipNone
730 "3CC874B571902366AACED5D619E87D" + // 4-bit Rotate180FlipXY
731 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate90FlipNone
732 "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate270FlipXY
733 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit Rotate180FlipNone
734 "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit RotateNoneFlipXY
735 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate270FlipNone
736 "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate90FlipXY
737 "545876C99ACF833E69FBFFBF436034" + // 4-bit RotateNoneFlipX
738 "545876C99ACF833E69FBFFBF436034" + // 4-bit Rotate180FlipY
739 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate90FlipX
740 "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate270FlipY
741 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit Rotate180FlipX
742 "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit RotateNoneFlipY
743 "B6B6245796C836923ABAABDF368B29" + // 4-bit Rotate270FlipX
744 "B6B6245796C836923ABAABDF368B29", // 4-bit Rotate90FlipY
748 private Bitmap CreateBitmap (int width, int height, PixelFormat fmt)
750 Bitmap bmp = new Bitmap (width, height, fmt);
751 using (Graphics gr = Graphics.FromImage (bmp)) {
752 Color c = Color.FromArgb (255, 100, 200, 250);
753 for (int x = 1; x < 80; x++) {
754 bmp.SetPixel (x, 1, c);
755 bmp.SetPixel (x, 2, c);
756 bmp.SetPixel (x, 78, c);
757 bmp.SetPixel (x, 79, c);
759 for (int y = 3; y < 78; y++) {
760 bmp.SetPixel (1, y, c);
761 bmp.SetPixel (2, y, c);
762 bmp.SetPixel (78, y, c);
763 bmp.SetPixel (79, y, c);
769 private byte[] HashPixels (Bitmap bmp)
771 int len = bmp.Width * bmp.Height * 4;
773 byte[] pixels = new byte [len];
775 for (int y = 0; y < bmp.Height; y++) {
776 for (int x = 0; x < bmp.Width; x++) {
777 Color clr = bmp.GetPixel (x, y);
778 pixels[index++] = clr.R;
779 pixels[index++] = clr.G;
780 pixels[index++] = clr.B;
783 return MD5.Create ().ComputeHash (pixels);
786 private byte[] HashLock (Bitmap bmp, int width, int height, PixelFormat fmt, ImageLockMode mode)
788 int len = bmp.Width * bmp.Height * 4;
789 byte[] pixels = new byte[len];
790 BitmapData bd = bmp.LockBits (new Rectangle (0, 0, width, height), mode, fmt);
793 int bbps = Image.GetPixelFormatSize (fmt);
794 long pos = bd.Scan0.ToInt64 ();
795 byte[] btv = new byte[1];
796 for (int y = 0; y < bd.Height; y++) {
797 for (int x = 0; x < bd.Width; x++) {
800 for (int bt = 0; bt < bbps / 8; bt++, index++) {
802 cur += y * bd.Stride;
805 Marshal.Copy ((IntPtr) cur, btv, 0, 1);
806 pixels[index] = btv[0];
808 /* Make change of all the colours = 250 to 10*/
811 Marshal.Copy (btv, 0, (IntPtr) cur, 1);
817 for (int i = index; i < len; i++)
823 return MD5.Create ().ComputeHash (pixels);
827 Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns
828 firsts, changes them, and then using GetPixel does another check of the changes.
829 The results match the .Net framework
831 private static byte[] DefaultBitmapHash = new byte[] { 0xD8, 0xD3, 0x68, 0x9C, 0x86, 0x7F, 0xB6, 0xA0, 0x76, 0xD6, 0x00, 0xEF, 0xFF, 0xE5, 0x8E, 0x1B };
832 private static byte[] FinalWholeBitmapHash = new byte[] { 0x5F, 0x52, 0x98, 0x37, 0xE3, 0x94, 0xE1, 0xA6, 0x06, 0x6C, 0x5B, 0xF1, 0xA9, 0xC2, 0xA9, 0x43 };
835 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Whole ()
837 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
838 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
839 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
840 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
841 Assert.AreEqual (expected, actual, "Full-Format32bppArgb");
842 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
847 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Whole ()
849 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
850 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
851 byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
852 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
853 Assert.AreEqual (expected, actual, "Full-Format32bppPArgb");
854 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
859 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Whole ()
861 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
862 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
863 byte[] expected = { 0xC0, 0x28, 0xB5, 0x2E, 0x86, 0x90, 0x6F, 0x37, 0x09, 0x5F, 0x49, 0xA4, 0x91, 0xDA, 0xEE, 0xB9 };
864 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
865 Assert.AreEqual (expected, actual, "Full-Format32bppRgb");
866 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
871 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Whole ()
873 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
874 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
875 byte[] expected = { 0xA7, 0xB2, 0x50, 0x04, 0x11, 0x12, 0x64, 0x68, 0x6B, 0x7D, 0x2F, 0x6E, 0x69, 0x24, 0xCB, 0x14 };
876 byte[] actual = HashLock (bmp, bmp.Width, bmp.Height, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
877 Assert.AreEqual (expected, actual, "Full-Format24bppRgb");
878 Assert.AreEqual (FinalWholeBitmapHash, HashPixels (bmp), "Final");
882 private static byte[] FinalPartialBitmapHash = new byte[] { 0xED, 0xD8, 0xDC, 0x9B, 0x44, 0x00, 0x22, 0x9B, 0x07, 0x06, 0x4A, 0x21, 0x70, 0xA7, 0x31, 0x1D };
885 public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Partial ()
887 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
888 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
889 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
890 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
891 Assert.AreEqual (expected, actual, "Partial-Format32bppArgb");
892 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
897 public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Partial ()
899 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
900 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
901 byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
902 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
903 Assert.AreEqual (expected, actual, "Partial-Format32bppPArgb");
904 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
909 public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Partial ()
911 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
912 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
913 byte[] expected = { 0x72, 0x33, 0x09, 0x67, 0x53, 0x65, 0x38, 0xF9, 0xE4, 0x58, 0xE1, 0x0A, 0xAA, 0x6A, 0xCC, 0xB8 };
914 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
915 Assert.AreEqual (expected, actual, "Partial-Format32bppRgb");
916 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
921 public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Partial ()
923 using (Bitmap bmp = CreateBitmap (100, 100, PixelFormat.Format32bppArgb)) {
924 Assert.AreEqual (DefaultBitmapHash, HashPixels (bmp), "Initial");
925 byte[] expected = { 0x4D, 0x39, 0x21, 0x88, 0xC2, 0x17, 0x14, 0x5F, 0x89, 0x9E, 0x02, 0x75, 0xF3, 0x64, 0xD8, 0xF0 };
926 byte[] actual = HashLock (bmp, 50, 50, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
927 Assert.AreEqual (expected, actual, "Partial-Format24bppRgb");
928 Assert.AreEqual (FinalPartialBitmapHash, HashPixels (bmp), "Final");
933 Tests the LockBitmap and UnlockBitmap functions, specifically the copying
934 of bitmap data in the directions indicated by the ImageLockMode.
937 public void LockUnlockBitmap ()
943 Color red = Color.FromArgb (Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B);
944 Color blue = Color.FromArgb (Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B);
946 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppRgb)) {
947 bmp.SetPixel (0, 0, red);
948 pixel_colour = bmp.GetPixel (0, 0);
949 Assert.AreEqual (red, pixel_colour, "Set/Get-Red");
951 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
953 pixel_value = Marshal.ReadByte (data.Scan0, 0);
954 pixel_value |= Marshal.ReadByte (data.Scan0, 1) << 8;
955 pixel_value |= Marshal.ReadByte (data.Scan0, 2) << 16;
956 pixel_value |= Marshal.ReadByte (data.Scan0, 3) << 24;
958 pixel_colour = Color.FromArgb (pixel_value);
959 // Disregard alpha information in the test
960 pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
961 Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Original");
963 // write blue but we're locked in read-only...
964 Marshal.WriteByte (data.Scan0, 0, blue.B);
965 Marshal.WriteByte (data.Scan0, 1, blue.G);
966 Marshal.WriteByte (data.Scan0, 2, blue.R);
967 Marshal.WriteByte (data.Scan0, 3, blue.A);
970 bmp.UnlockBits (data);
971 pixel_colour = bmp.GetPixel (0, 0);
972 // Disregard alpha information in the test
973 pixel_colour = Color.FromArgb (red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
974 // ...so we still read red after unlocking
975 Assert.AreEqual (red, pixel_colour, "32RGB/32ARGB-ReadOnly-Red-Unlocked");
978 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
981 Marshal.WriteByte (data.Scan0, 0, blue.B);
982 Marshal.WriteByte (data.Scan0, 1, blue.G);
983 Marshal.WriteByte (data.Scan0, 2, blue.R);
984 Marshal.WriteByte (data.Scan0, 3, blue.A);
987 bmp.UnlockBits (data);
988 pixel_colour = bmp.GetPixel (0, 0);
989 // Disregard alpha information in the test
990 pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
992 Assert.AreEqual (blue, pixel_colour, "32RGB/32ARGB-ReadWrite-Blue-Unlock");
996 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format32bppArgb)) {
997 bmp.SetPixel (0, 0, red);
999 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
1001 byte b = Marshal.ReadByte (data.Scan0, 0);
1002 byte g = Marshal.ReadByte (data.Scan0, 1);
1003 byte r = Marshal.ReadByte (data.Scan0, 2);
1004 pixel_colour = Color.FromArgb (red.A, r, g, b);
1005 Assert.AreEqual (red, pixel_colour, "32ARGB/24RGB-ReadOnly-Red-Original");
1006 // write blue but we're locked in read-only...
1007 Marshal.WriteByte (data.Scan0, 0, blue.B);
1008 Marshal.WriteByte (data.Scan0, 1, blue.G);
1009 Marshal.WriteByte (data.Scan0, 2, blue.R);
1012 bmp.UnlockBits (data);
1013 // ...so we still read red after unlocking
1014 Assert.AreEqual (red, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadOnly-Red-Unlock");
1017 data = bmp.LockBits (new Rectangle (0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
1020 Marshal.WriteByte (data.Scan0, 0, blue.B);
1021 Marshal.WriteByte (data.Scan0, 1, blue.G);
1022 Marshal.WriteByte (data.Scan0, 2, blue.R);
1025 bmp.UnlockBits (data);
1027 Assert.AreEqual (blue, bmp.GetPixel (0, 0), "32ARGB/24RGB-ReadWrite-Blue-Unlock");
1032 public void DefaultFormat1 ()
1034 using (Bitmap bmp = new Bitmap (20, 20)) {
1035 Assert.AreEqual (ImageFormat.MemoryBmp, bmp.RawFormat);
1040 public void DefaultFormat2 ()
1042 string filename = Path.GetTempFileName ();
1043 using (Bitmap bmp = new Bitmap (20, 20)) {
1044 bmp.Save (filename);
1047 using (Bitmap other = new Bitmap (filename)) {
1048 Assert.AreEqual (ImageFormat.Png, other.RawFormat);
1050 File.Delete (filename);
1054 public void BmpDataStride1 ()
1056 Bitmap bmp = new Bitmap (184, 184, PixelFormat.Format1bppIndexed);
1057 BitmapData data = bmp.LockBits (new Rectangle (0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
1059 Assert.AreEqual (24, data.Stride);
1061 bmp.UnlockBits (data);
1066 private Stream Serialize (object o)
1068 MemoryStream ms = new MemoryStream ();
1069 IFormatter formatter = new BinaryFormatter ();
1070 formatter.Serialize (ms, o);
1075 private object Deserialize (Stream s)
1077 return new BinaryFormatter ().Deserialize (s);
1081 public void Serialize_Icon ()
1083 // this cause a problem with resgen, see http://bugzilla.ximian.com/show_bug.cgi?id=80565
1084 string filename = getInFile ("bitmaps/16x16x16.ico");
1085 using (Bitmap icon = new Bitmap (filename)) {
1086 using (Stream s = Serialize (icon)) {
1087 using (Bitmap copy = (Bitmap)Deserialize (s)) {
1088 Assert.AreEqual (icon.Height, copy.Height, "Height");
1089 Assert.AreEqual (icon.Width, copy.Width, "Width");
1090 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1091 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1092 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1099 private Stream SoapSerialize (object o)
1101 MemoryStream ms = new MemoryStream ();
1102 IFormatter formatter = new SoapFormatter ();
1103 formatter.Serialize (ms, o);
1108 private object SoapDeserialize (Stream s)
1110 return new SoapFormatter ().Deserialize (s);
1114 public void SoapSerialize_Icon ()
1116 string filename = getInFile ("bitmaps/16x16x16.ico");
1117 using (Bitmap icon = new Bitmap (filename)) {
1118 using (Stream s = SoapSerialize (icon)) {
1119 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1120 Assert.AreEqual (icon.Height, copy.Height, "Height");
1121 Assert.AreEqual (icon.Width, copy.Width, "Width");
1122 Assert.AreEqual (icon.PixelFormat, copy.PixelFormat, "PixelFormat");
1123 Assert.AreEqual (16, icon.Palette.Entries.Length, "icon Palette");
1124 Assert.IsTrue (icon.RawFormat.Equals (ImageFormat.Icon), "Icon");
1125 Assert.AreEqual (0, copy.Palette.Entries.Length, "copy Palette");
1126 Assert.IsTrue (copy.RawFormat.Equals (ImageFormat.Png), "Png");
1133 public void SoapSerialize_Bitmap8 ()
1135 string filename = getInFile ("bitmaps/almogaver8bits.bmp");
1136 using (Bitmap bmp = new Bitmap (filename)) {
1137 using (Stream s = SoapSerialize (bmp)) {
1138 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1139 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1140 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1141 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1142 Assert.AreEqual (256, copy.Palette.Entries.Length, "Palette");
1143 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1150 public void SoapSerialize_Bitmap24 ()
1152 string filename = getInFile ("bitmaps/almogaver24bits.bmp");
1153 using (Bitmap bmp = new Bitmap (filename)) {
1154 using (Stream s = SoapSerialize (bmp)) {
1155 using (Bitmap copy = (Bitmap) SoapDeserialize (s)) {
1156 Assert.AreEqual (bmp.Height, copy.Height, "Height");
1157 Assert.AreEqual (bmp.Width, copy.Width, "Width");
1158 Assert.AreEqual (bmp.PixelFormat, copy.PixelFormat, "PixelFormat");
1159 Assert.AreEqual (bmp.Palette.Entries.Length, copy.Palette.Entries.Length, "Palette");
1160 Assert.AreEqual (bmp.RawFormat, copy.RawFormat, "RawFormat");
1168 [Category ("NotWorking")] // http://bugzilla.ximian.com/show_bug.cgi?id=80558
1169 public void XmlSerialize ()
1171 new XmlSerializer (typeof (Bitmap));
1174 static int[] palette1 = {
1180 public void Format1bppIndexed_Palette ()
1182 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format1bppIndexed)) {
1183 ColorPalette pal = bmp.Palette;
1184 Assert.AreEqual (2, pal.Entries.Length, "Length");
1185 for (int i = 0; i < pal.Entries.Length; i++) {
1186 Assert.AreEqual (palette1[i], pal.Entries[i].ToArgb (), i.ToString ());
1188 Assert.AreEqual (2, pal.Flags, "Flags");
1192 static int[] palette16 = {
1212 public void Format4bppIndexed_Palette ()
1214 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format4bppIndexed)) {
1215 ColorPalette pal = bmp.Palette;
1216 Assert.AreEqual (16, pal.Entries.Length, "Length");
1217 for (int i = 0; i < pal.Entries.Length; i++) {
1218 Assert.AreEqual (palette16 [i], pal.Entries[i].ToArgb (), i.ToString ());
1220 Assert.AreEqual (0, pal.Flags, "Flags");
1224 static int[] palette256 = {
1484 public void Format8bppIndexed_Palette ()
1486 using (Bitmap bmp = new Bitmap (1, 1, PixelFormat.Format8bppIndexed)) {
1487 ColorPalette pal = bmp.Palette;
1488 Assert.AreEqual (256, pal.Entries.Length, "Length");
1489 for (int i = 0; i < pal.Entries.Length; i++) {
1490 Assert.AreEqual (palette256[i], pal.Entries[i].ToArgb (), i.ToString ());
1492 Assert.AreEqual (4, pal.Flags, "Flags");
1497 public void XmlSerialization ()
1499 new XmlSerializer (typeof (Bitmap));
1503 public void BitmapImageCtor ()
1505 Assert.Throws<NullReferenceException> (() => new Bitmap ((Image) null));
1509 public void BitmapImageSizeCtor ()
1511 Assert.Throws<ArgumentException> (() => new Bitmap ((Image) null, Size.Empty));
1515 public void BitmapImageIntIntCtor ()
1517 Assert.Throws<ArgumentException> (() => new Bitmap ((Image) null, Int32.MinValue, Int32.MaxValue));
1521 public void BitmapIntIntCtor ()
1523 Assert.Throws<ArgumentException> (() => new Bitmap (Int32.MinValue, Int32.MaxValue));
1527 public void BitmapIntIntGraphicCtor ()
1529 Assert.Throws<ArgumentNullException> (() => new Bitmap (1, 1, null));
1533 public void BitmapIntIntPixelFormatCtor ()
1535 Assert.Throws<ArgumentException> (() => new Bitmap (Int32.MinValue, Int32.MaxValue, PixelFormat.Format1bppIndexed));
1539 public void BitmapStreamCtor ()
1541 Assert.Throws<ArgumentException> (() => new Bitmap ((Stream) null));
1545 public void BitmapStreamBoolCtor ()
1547 Assert.Throws<ArgumentException> (() => new Bitmap ((Stream) null, true));
1551 public void BitmapStringCtor ()
1553 Assert.Throws<ArgumentNullException> (() => new Bitmap ((string) null));
1557 public void BitmapStringBoolCtor ()
1559 Assert.Throws<ArgumentNullException> (() => new Bitmap ((string) null, false));
1563 public void BitmapTypeStringCtor1 ()
1565 Assert.Throws<NullReferenceException> (() => new Bitmap ((Type) null, "mono"));
1569 public void BitmapTypeStringCtor2 ()
1571 Assert.Throws<ArgumentException> (() => new Bitmap (typeof (Bitmap), null));
1574 private void SetResolution (float x, float y)
1576 using (Bitmap bmp = new Bitmap (1, 1)) {
1577 bmp.SetResolution (x, y);
1582 public void SetResolution_Zero ()
1584 Assert.Throws<ArgumentException> (() => SetResolution (0.0f, 0.0f));
1588 public void SetResolution_Negative_X ()
1590 Assert.Throws<ArgumentException> (() => SetResolution (-1.0f, 1.0f));
1594 public void SetResolution_Negative_Y ()
1596 Assert.Throws<ArgumentException> (() => SetResolution (1.0f, -1.0f));
1600 public void SetResolution_MaxValue ()
1602 SetResolution (Single.MaxValue, Single.MaxValue);
1606 public void SetResolution_PositiveInfinity ()
1608 SetResolution (Single.PositiveInfinity, Single.PositiveInfinity);
1612 public void SetResolution_NaN ()
1614 Assert.Throws<ArgumentException> (() => SetResolution (Single.NaN, Single.NaN));
1618 public void SetResolution_NegativeInfinity ()
1620 Assert.Throws<ArgumentException> (() => SetResolution (Single.NegativeInfinity, Single.NegativeInfinity));
1625 public class BitmapFullTrustTest {
1627 public void BitmapIntIntIntPixelFormatIntPtrCtor ()
1629 new Bitmap (1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero);
1632 // BitmapFromHicon## is *almost* the same as IconTest.Icon##ToBitmap except
1633 // for the Flags property
1635 private void HiconTest (string msg, Bitmap b, int size)
1637 Assert.AreEqual (PixelFormat.Format32bppArgb, b.PixelFormat, msg + ".PixelFormat");
1638 // unlike the GDI+ icon decoder the palette isn't kept
1639 Assert.AreEqual (0, b.Palette.Entries.Length, msg + ".Palette");
1640 Assert.AreEqual (size, b.Height, msg + ".Height");
1641 Assert.AreEqual (size, b.Width, msg + ".Width");
1642 Assert.IsTrue (b.RawFormat.Equals (ImageFormat.MemoryBmp), msg + ".RawFormat");
1643 Assert.AreEqual (335888, b.Flags, msg + ".Flags");
1647 public void Hicon16 ()
1651 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/16x16x16.ico"))) {
1653 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1654 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1655 hicon = bitmap.GetHicon ();
1658 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1659 // hicon survives bitmap and icon disposal
1660 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1665 public void Hicon32 ()
1669 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/32x32x16.ico"))) {
1671 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1672 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1673 hicon = bitmap.GetHicon ();
1676 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1677 // hicon survives bitmap and icon disposal
1678 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1683 [Category ("NotWorking")] // libgdiplus has lost track of the original 1bpp state
1684 public void Hicon48 ()
1686 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/48x48x1.ico"))) {
1687 // looks like 1bbp icons aren't welcome as bitmaps ;-)
1688 Assert.Throws<ArgumentException> (() => Bitmap.FromHicon (icon.Handle));
1693 public void Hicon64 ()
1697 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/64x64x256.ico"))) {
1699 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1700 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1701 hicon = bitmap.GetHicon ();
1704 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1705 // hicon survives bitmap and icon disposal
1706 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1711 public void Hicon96 ()
1715 using (Icon icon = new Icon (TestBitmap.getInFile ("bitmaps/96x96x256.ico"))) {
1717 using (Bitmap bitmap = Bitmap.FromHicon (icon.Handle)) {
1718 HiconTest ("Icon.Handle/FromHicon", bitmap, size);
1719 hicon = bitmap.GetHicon ();
1722 using (Bitmap bitmap2 = Bitmap.FromHicon (hicon)) {
1723 // hicon survives bitmap and icon disposal
1724 HiconTest ("GetHicon/FromHicon", bitmap2, size);
1729 public void HBitmap ()
1732 string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1733 using (Bitmap bitmap = new Bitmap (sInFile)) {
1734 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1735 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1736 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1737 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1738 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1739 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1740 hbitmap = bitmap.GetHbitmap ();
1742 // hbitmap survives original bitmap disposal
1743 using (Image image = Image.FromHbitmap (hbitmap)) {
1744 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "FromHbitmap.PixelFormat");
1745 Assert.AreEqual (0, image.Palette.Entries.Length, "FromHbitmap.Palette");
1746 Assert.AreEqual (183, image.Height, "FromHbitmap.Height");
1747 Assert.AreEqual (173, image.Width, "FromHbitmap.Width");
1748 Assert.AreEqual (335888, image.Flags, "FromHbitmap.Flags");
1749 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "FromHbitmap.RawFormat");
1754 public void CreateMultipleBitmapFromSameHBITMAP ()
1757 string sInFile = TestBitmap.getInFile ("bitmaps/almogaver24bits.bmp");
1758 using (Bitmap bitmap = new Bitmap (sInFile)) {
1759 Assert.AreEqual (PixelFormat.Format24bppRgb, bitmap.PixelFormat, "Original.PixelFormat");
1760 Assert.AreEqual (0, bitmap.Palette.Entries.Length, "Original.Palette");
1761 Assert.AreEqual (183, bitmap.Height, "Original.Height");
1762 Assert.AreEqual (173, bitmap.Width, "Original.Width");
1763 Assert.AreEqual (73744, bitmap.Flags, "Original.Flags");
1764 Assert.IsTrue (bitmap.RawFormat.Equals (ImageFormat.Bmp), "Original.RawFormat");
1765 hbitmap = bitmap.GetHbitmap ();
1767 // hbitmap survives original bitmap disposal
1768 using (Image image = Image.FromHbitmap (hbitmap)) {
1769 //Assert.AreEqual (PixelFormat.Format32bppRgb, image.PixelFormat, "1.PixelFormat");
1770 Assert.AreEqual (0, image.Palette.Entries.Length, "1.Palette");
1771 Assert.AreEqual (183, image.Height, "1.Height");
1772 Assert.AreEqual (173, image.Width, "1.Width");
1773 Assert.AreEqual (335888, image.Flags, "1.Flags");
1774 Assert.IsTrue (image.RawFormat.Equals (ImageFormat.MemoryBmp), "1.RawFormat");
1776 using (Image image2 = Image.FromHbitmap (hbitmap)) {
1777 //Assert.AreEqual (PixelFormat.Format32bppRgb, image2.PixelFormat, "2.PixelFormat");
1778 Assert.AreEqual (0, image2.Palette.Entries.Length, "2.Palette");
1779 Assert.AreEqual (183, image2.Height, "2.Height");
1780 Assert.AreEqual (173, image2.Width, "2.Width");
1781 Assert.AreEqual (335888, image2.Flags, "2.Flags");
1782 Assert.IsTrue (image2.RawFormat.Equals (ImageFormat.MemoryBmp), "2.RawFormat");