LockBitmap tests for different pixel formats
[mono.git] / mcs / class / System.Drawing / Test / System.Drawing / TestBitmap.cs
1 //
2 // Bitmap class testing unit
3 //
4 // Author:
5 //
6 //       Jordi Mas i Hernàndez (jmas@softcatala.org>
7 //
8 // (C) 2004 Ximian, Inc.  http://www.ximian.com
9 //
10 using System;
11 using System.Drawing;
12 using System.Drawing.Imaging;
13 using NUnit.Framework;
14 using System.IO;
15 using System.Security.Cryptography;
16 using System.Text;
17 using System.Runtime.InteropServices;
18
19 namespace MonoTests.System.Drawing{
20
21         [TestFixture]   
22         public class TestBitmap : Assertion {
23                 
24                 [TearDown]
25                 public void Clean() {}
26                 
27                 [SetUp]
28                 public void GetReady()          
29                 {
30                 
31                 }
32                         
33                 [Test]
34                 public void TestPixels() 
35                 {               
36                         // Tests GetSetPixel/SetPixel                   
37                         Bitmap bmp= new Bitmap(100,100, PixelFormat.Format32bppRgb);                                                                                    
38                         bmp.SetPixel(0,0,Color.FromArgb(255,128,128,128));                                      
39                         Color color = bmp.GetPixel(0,0);                                
40                                                 
41                         AssertEquals (Color.FromArgb(255,128,128,128), color);
42                         
43                         bmp.SetPixel(99,99,Color.FromArgb(255,255,0,155));                                      
44                         Color color2 = bmp.GetPixel(99,99);                                                                             
45                         AssertEquals (Color.FromArgb(255,255,0,155), color2);                   
46                 }
47                 
48                 /* Get the output directory depending on the runtime and location*/
49                 internal string getOutSubDir()
50                 {                               
51                         string sSub, sRslt;                     
52                         
53                         if (Environment.GetEnvironmentVariable("MSNet")==null)
54                                 sSub = "mono/";
55                         else
56                                 sSub = "MSNet/";                        
57                         
58                         sRslt = Path.GetFullPath (sSub);
59                                 
60                         if (Directory.Exists(sRslt) ==  false) 
61                                 sRslt = "Test/System.Drawing/" + sSub;                                                  
62                         
63                         if (sRslt.Length > 0)
64                                 if (sRslt[sRslt.Length-1] != '\\' && sRslt[sRslt.Length-1] != '/')
65                                         sRslt += "/";                                   
66                         
67                         return sRslt;
68                 }
69                 
70                 /* Get the input directory depending on the runtime*/
71                 internal string getInFile(string file)
72                 {                               
73                         string sRslt;                                           
74                         
75                         sRslt = Path.GetFullPath (file);
76                                 
77                         if (File.Exists(file)==false) 
78                                 sRslt = "Test/System.Drawing/" + file;                                                  
79                         
80                         return sRslt;
81                 }
82                 
83                 [Test]
84                 public void BitmapLoadAndSave() 
85                 {                               
86                         string sOutFile =  getOutSubDir() + "linerect.bmp";
87                                                 
88                         // Save         
89                         Bitmap  bmp = new Bitmap(100,100, PixelFormat.Format32bppRgb);                                          
90                         Graphics gr = Graphics.FromImage(bmp);          
91                         
92                         Pen p = new Pen(Color.Red, 2);
93                         gr.DrawLine(p, 10.0F, 10.0F, 90.0F, 90.0F);
94                         gr.DrawRectangle(p, 10.0F, 10.0F, 80.0F, 80.0F);
95                         p.Dispose();                                    
96                         bmp.Save(sOutFile, ImageFormat.Bmp);
97                         gr.Dispose();
98                         bmp.Dispose();                                                  
99                         
100                         // Load                 
101                         Bitmap  bmpLoad = new Bitmap(sOutFile);
102                         if( bmpLoad == null) 
103                                 Console.WriteLine("Unable to load "+ sOutFile);                                         
104                         
105                         Color color = bmpLoad.GetPixel(10,10);          
106                         
107                         
108                         AssertEquals (Color.FromArgb(255,255,0,0), color);                                                                                      
109                 }
110
111                 //[Test]
112                 public void MakeTransparent() 
113                 {
114                         string sInFile =   getInFile("bitmaps/maketransparent.bmp");
115                         string sOutFile =  getOutSubDir() + "transparent.bmp";
116                                                 
117                         Bitmap  bmp = new Bitmap(sInFile);
118                         Console.WriteLine("Bitmap loaded OK", bmp != null);
119                                         
120                         bmp.MakeTransparent();
121                         bmp.Save(sOutFile);                                                     
122                         
123                         Color color = bmp.GetPixel(1,1);                                                        
124                         AssertEquals (Color.Black.R, color.R);                                                                                  
125                         AssertEquals (Color.Black.G, color.G);                                                                                  
126                         AssertEquals (Color.Black.B, color.B);                                                                          
127                 }
128                 
129                 [Test]
130                 public void Clone()
131                 {
132                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
133                         string sOutFile =  getOutSubDir() + "clone24.bmp";                      
134                         
135                         Rectangle rect = new Rectangle(0,0,50,50);                                              
136                         Bitmap  bmp = new Bitmap(sInFile);                      
137                         
138                         Bitmap bmpNew = bmp.Clone (rect, PixelFormat.Format32bppArgb);                  
139                         bmpNew.Save(sOutFile);                                                  
140                         
141                         Color colororg0 = bmp.GetPixel(0,0);            
142                         Color colororg50 = bmp.GetPixel(49,49);                                 
143                         Color colornew0 = bmpNew.GetPixel(0,0);         
144                         Color colornew50 = bmpNew.GetPixel(49,49);                              
145                         
146                         AssertEquals (colororg0, colornew0);                                                                                    
147                         AssertEquals (colororg50, colornew50);                          
148                 }       
149                 
150                 [Test]
151                 public void CloneImage()
152                 {
153                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
154                         Bitmap  bmp = new Bitmap(sInFile);                      
155                         
156                         Bitmap bmpNew = (Bitmap) bmp.Clone ();                  
157                         
158                         AssertEquals (bmp.Width, bmpNew.Width);
159                         AssertEquals (bmp.Height, bmpNew.Height);               
160                         AssertEquals (bmp.PixelFormat, bmpNew.PixelFormat);                     
161                         
162                 }       
163                 
164                 /* Check bitmap features on a know 24-bits bitmap*/
165                 [Test]
166                 public void BitmapFeatures()
167                 {
168                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");
169                         Bitmap  bmp = new Bitmap(sInFile);                                              
170                         RectangleF rect;
171                         GraphicsUnit unit = GraphicsUnit.World;
172                         
173                         rect = bmp.GetBounds(ref unit);
174                         
175                         AssertEquals (PixelFormat.Format24bppRgb, bmp.PixelFormat);
176                         AssertEquals (173, bmp.Width);
177                         AssertEquals (183, bmp.Height);         
178                         
179                         AssertEquals (0, rect.X);
180                         AssertEquals (0, rect.Y);               
181                         AssertEquals (173, rect.Width);
182                         AssertEquals (183, rect.Height);                                        
183                         
184                         AssertEquals (173, bmp.Size.Width);
185                         AssertEquals (183, bmp.Size.Height);                                    
186                 }
187                 
188                 [Test]
189                 public void Frames()
190                 {
191                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");                     
192                         Bitmap  bmp = new Bitmap(sInFile);                                              
193                         int cnt = bmp.GetFrameCount(FrameDimension.Page);                       
194                         int active = bmp.SelectActiveFrame (FrameDimension.Page, 0);
195                         
196                         AssertEquals (1, cnt);                                                          
197                         AssertEquals (0, active);                                                                                       
198                 }
199
200                 static string ByteArrayToString(byte[] arrInput)
201                 {
202                         int i;
203                         StringBuilder sOutput = new StringBuilder(arrInput.Length);
204                         for (i=0;i < arrInput.Length -1; i++) 
205                         {
206                                 sOutput.Append(arrInput[i].ToString("X2"));
207                         }
208                         return sOutput.ToString();
209                 }
210
211
212                 public string RotateBmp (Bitmap src, RotateFlipType rotate)
213                 {                       
214                         int witdh = 150, height = 150, index = 0;                       
215                         byte[] pixels = new byte [witdh * height * 3];
216                         Bitmap bmp_rotate;
217                         byte[] hash;
218                         Color clr;
219
220
221                         bmp_rotate = src.Clone (new RectangleF (0,0, witdh, height), PixelFormat.Format32bppArgb);      
222                         bmp_rotate.RotateFlip (rotate);                 
223
224                         for (int y = 0; y < height; y++) {
225                                 for (int x = 0; x < witdh; x++) {                               
226                                         clr = bmp_rotate.GetPixel (x,y);
227                                         pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++]  = clr.B;     
228                                 }                               
229                         }
230                 
231                         hash = new MD5CryptoServiceProvider().ComputeHash (pixels);
232                         return ByteArrayToString (hash);
233                 }
234                 
235                 
236                 /*
237                         Rotate bitmap in diffent ways, and check the result
238                         pixels using MD5
239                 */
240                 [Test]
241                 public void Rotate()
242                 {
243                         string sInFile = getInFile ("bitmaps/almogaver24bits.bmp");     
244                         Bitmap  bmp = new Bitmap(sInFile);              
245                         
246                         AssertEquals ("312958A3C67402E1299413794988A3", RotateBmp (bmp, RotateFlipType.Rotate90FlipNone));      
247                         AssertEquals ("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp (bmp, RotateFlipType.Rotate180FlipNone));
248                         AssertEquals ("15AD2ADBDC7090C0EC744D0F7ACE2F", RotateBmp (bmp, RotateFlipType.Rotate270FlipNone));
249                         AssertEquals ("2E10FEC1F4FD64ECC51D7CE68AEB18", RotateBmp (bmp, RotateFlipType.RotateNoneFlipX));
250                         AssertEquals ("E63204779B566ED01162B90B49BD9E", RotateBmp (bmp, RotateFlipType.Rotate90FlipX));
251                         AssertEquals ("B1ECB17B5093E13D04FF55CFCF7763", RotateBmp (bmp, RotateFlipType.Rotate180FlipX));
252                         AssertEquals ("71A173882C16755D86F4BC26532374", RotateBmp (bmp, RotateFlipType.Rotate270FlipX));
253
254                 }
255                 
256                 public void LockBmp (PixelFormat fmt, PixelFormat fmtlock, string output, 
257                         int lwidth , int lheight, ref string hash1, ref string hash2)
258                 {                       
259                         int width = 100, height = 100, bbps, cur, pos;
260                         Bitmap  bmp = new Bitmap (width, height, fmt);                                                                          
261                         Graphics gr = Graphics.FromImage (bmp);                 
262                         byte[] hash;
263                         Color clr;
264                         byte[] btv = new byte[1];                                               
265                         int y, x, len = width * height * 4, index = 0;                  
266                         byte[] pixels = new byte [len];
267                         hash1 = hash2 ="";
268                         
269                         bbps = Image.GetPixelFormatSize (fmt);                  
270                                  
271                         Pen p = new Pen (Color.FromArgb (255, 100, 200, 250), 2);                               
272                         gr.DrawRectangle(p, 1.0F, 1.0F, 80.0F, 80.0F);                          
273                         
274                         BitmapData bd = bmp.LockBits (new Rectangle (0, 0, lwidth, lheight), ImageLockMode.ReadOnly,  fmtlock);
275                         
276                         pos = bd.Scan0.ToInt32();                       
277                         for (y = 0; y < bd.Height; y++) {                       
278                                 for (x = 0; x < bd.Width; x++) {
279                                         
280                                         /* Read the pixels*/
281                                         for (int bt =0; bt < bbps/8; bt++, index++) {
282                                                 cur = pos;
283                                                 cur+= y * bd.Stride;
284                                                 cur+= x * bbps/8;                                       
285                                                 cur+= bt;                                       
286                                                 Marshal.Copy ((IntPtr)cur, btv, 0, 1);
287                                                 pixels[index] = btv[0];
288                                                 
289                                                 /* Make change of all the colours = 250 to 10*/                                         
290                                                 if (btv[0] == 250) {
291                                                         btv[0] = 10;
292                                                         Marshal.Copy (btv, 0, (IntPtr)cur, 1);
293                                                 }
294                                         }
295                                 }
296                         }                                       
297                         
298                         for (int i = index; i < len; i++)
299                                 pixels[index] = 0;
300                 
301                         hash = new MD5CryptoServiceProvider().ComputeHash (pixels);                     
302                         bmp.UnlockBits (bd);                                                    
303                                                 
304                         hash1 = ByteArrayToString (hash);
305                         
306                         /* MD5 of the changed bitmap*/
307                         for (y = 0, index = 0; y < height; y++) {
308                                 for (x = 0; x < width; x++) {                           
309                                         clr = bmp.GetPixel (x,y);
310                                         pixels[index++] = clr.R; pixels[index++] = clr.G; pixels[index++]  = clr.B;     
311                                 }                               
312                         }
313                         
314                         hash = new MD5CryptoServiceProvider().ComputeHash (pixels);                                             
315                         hash2 = ByteArrayToString (hash);
316                         
317                         /*bmp.Save (output, ImageFormat.Bmp);*/
318                 }
319                 /*
320                         Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns
321                         firsts, changes them, and then using GetPixel does another check of the changes.
322                         The results match the .Net framework
323                 */
324                 [Test]
325                 public void LockBitmap ()
326                 {       
327                         string hash = "";               
328                         string hashchg = "";                            
329                                                         
330                         /* Locks the whole bitmap*/                     
331                         LockBmp (PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, "output32bppArgb.bmp", 100, 100, ref hash, ref hashchg);                             
332                         AssertEquals ("AF5BFD4E98D6708FF4C9982CC9C68F", hash);                  
333                         AssertEquals ("BBEE27DC85563CB58EE11E8951230F", hashchg);                       
334                         
335                         LockBmp (PixelFormat.Format32bppPArgb, PixelFormat.Format32bppPArgb, "output32bppPArgb.bmp", 100, 100, ref hash, ref hashchg);                  
336                         AssertEquals ("AF5BFD4E98D6708FF4C9982CC9C68F", hash);                  
337                         AssertEquals ("BBEE27DC85563CB58EE11E8951230F", hashchg);                       
338                         
339                         LockBmp (PixelFormat.Format32bppRgb, PixelFormat.Format32bppRgb, "output32bppRgb.bmp", 100, 100, ref hash, ref hashchg);
340                         AssertEquals ("AF5BFD4E98D6708FF4C9982CC9C68F", hash);                  
341                         AssertEquals ("BBEE27DC85563CB58EE11E8951230F", hashchg);               
342                         
343                         LockBmp (PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, "output24bppRgb.bmp", 100, 100, ref hash, ref hashchg);
344                         AssertEquals ("A8A071D0B3A3743905B4E193A62769", hash);                  
345                         AssertEquals ("EEE846FA8F892339C64082DFF775CF", hashchg);                                       
346                         
347                         /* Locks a portion of the bitmap*/              
348                         LockBmp (PixelFormat.Format32bppArgb, PixelFormat.Format32bppArgb, "output32bppArgb.bmp", 50, 50, ref hash, ref hashchg);                               
349                         AssertEquals ("C361FBFD82A4F3C278605AE9EC5385", hash);                  
350                         AssertEquals ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                       
351                         
352                         LockBmp (PixelFormat.Format32bppPArgb, PixelFormat.Format32bppPArgb, "output32bppPArgb.bmp", 50, 50, ref hash, ref hashchg);                    
353                         AssertEquals ("C361FBFD82A4F3C278605AE9EC5385", hash);                  
354                         AssertEquals ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                       
355                 
356                         LockBmp (PixelFormat.Format32bppRgb, PixelFormat.Format32bppRgb, "output32bppRgb.bmp", 50, 50, ref hash, ref hashchg);
357                         AssertEquals ("C361FBFD82A4F3C278605AE9EC5385", hash);                  
358                         AssertEquals ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                       
359                         
360                         LockBmp (PixelFormat.Format24bppRgb, PixelFormat.Format24bppRgb, "output24bppRgb.bmp", 50, 50, ref hash, ref hashchg);
361                         AssertEquals ("FFE86628478591D1A1EB30E894C34F", hash);                  
362                         AssertEquals ("8C2C04B361E1D5875EE8ACF5073F4E", hashchg);                               
363                                                 
364                 }
365                 
366         }
367 }