Browse Source

In Test/System.Drawing:
2007-11-05 Sebastien Pouliot <[email protected]>

* Image.cs: Add test cases for the stream position when loading and
saving bitmaps and metafiles. Some of them are based on Gert Driesen
samples in #338779

In System.Drawing.Imaging:
2007-11-05 Sebastien Pouliot <[email protected]>

* Metafile.cs: Stream position is not moved for metafiles.

In System.Drawing:
2007-11-05 Sebastien Pouliot <[email protected]>

* gdipFunctions.cs: Add a bool parameter to GdiPlusStreamHelper ctor
to move, or not, the stream position to load/save images.
* Image.cs: Stream position is moved to 0 when loading images from
stream but isn't moved for saving an image to a stream. Fix part of
#338779 (except that Image.FromFile behave differently for metafiles)


svn path=/trunk/mcs/; revision=88916

Sebastien Pouliot 18 năm trước cách đây
mục cha
commit
5cef71746d

+ 4 - 0
mcs/class/System.Drawing/System.Drawing.Imaging/ChangeLog

@@ -1,3 +1,7 @@
+2007-11-05  Sebastien Pouliot  <[email protected]> 
+
+	* Metafile.cs: Stream position is not moved for metafiles.
+
 2007-05-30  Sebastien Pouliot  <[email protected]>
 
 	* ImageAttributes.cs: Remove TODO for ColorMatrixFlags and Gray 

+ 4 - 4
mcs/class/System.Drawing/System.Drawing.Imaging/Metafile.cs

@@ -60,7 +60,7 @@ namespace System.Drawing.Imaging {
 			if (GDIPlus.RunningOnUnix ()) {
 				// With libgdiplus we use a custom API for this, because there's no easy way
 				// to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates.
-				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream);
+				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream, false);
 				status = GDIPlus.GdipCreateMetafileFromDelegate_linux (sh.GetHeaderDelegate, sh.GetBytesDelegate, 
 					sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, out nativeObject);
 			} else {
@@ -268,7 +268,7 @@ namespace System.Drawing.Imaging {
 			if (GDIPlus.RunningOnUnix ()) {
 				// With libgdiplus we use a custom API for this, because there's no easy way
 				// to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates.
-				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream);
+				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream, false);
 				status = GDIPlus.GdipRecordMetafileFromDelegateI_linux (sh.GetHeaderDelegate, sh.GetBytesDelegate, 
 					sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, referenceHdc, 
 					type, ref frameRect, frameUnit, description, out nativeObject);
@@ -289,7 +289,7 @@ namespace System.Drawing.Imaging {
 			if (GDIPlus.RunningOnUnix ()) {
 				// With libgdiplus we use a custom API for this, because there's no easy way
 				// to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates.
-				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream);
+				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream, false);
 				status = GDIPlus.GdipRecordMetafileFromDelegate_linux (sh.GetHeaderDelegate, sh.GetBytesDelegate, 
 					sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, referenceHdc, 
 					type, ref frameRect, frameUnit, description, out nativeObject);
@@ -364,7 +364,7 @@ namespace System.Drawing.Imaging {
 				if (GDIPlus.RunningOnUnix ()) {
 					// With libgdiplus we use a custom API for this, because there's no easy way
 					// to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates.
-					GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream);
+					GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream, false);
 					status = GDIPlus.GdipGetMetafileHeaderFromDelegate_linux (sh.GetHeaderDelegate, 
 						sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, 
 						sh.SizeDelegate, header);

+ 8 - 0
mcs/class/System.Drawing/System.Drawing/ChangeLog

@@ -1,3 +1,11 @@
+2007-11-05  Sebastien Pouliot  <[email protected]>
+
+	* gdipFunctions.cs: Add a bool parameter to GdiPlusStreamHelper ctor
+	to move, or not, the stream position to load/save images.
+	* Image.cs: Stream position is moved to 0 when loading images from 
+	stream but isn't moved for saving an image to a stream. Fix part of
+	#338779 (except that Image.FromFile behave differently for metafiles)
+
 2007-11-05  Sebastien Pouliot  <[email protected]> 
 
 	* gdipFunctions.cs: Stream position shouldn't be changed when 

+ 2 - 2
mcs/class/System.Drawing/System.Drawing/Image.cs

@@ -287,7 +287,7 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer
 			// We use a custom API for this, because there's no easy way
 			// to get the Stream down to libgdiplus.  So, we wrap the stream
 			// with a set of delegates.
-			GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream);
+			GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream, true);
 
 			st = GDIPlus.GdipLoadImageFromDelegate_linux (sh.GetHeaderDelegate, sh.GetBytesDelegate,
 				sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, out imagePtr);
@@ -480,7 +480,7 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer
 
 		try {
 			if (GDIPlus.RunningOnUnix ()) {
-				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream);
+				GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream, false);
 				st = GDIPlus.GdipSaveImageToDelegate_linux (nativeObject, sh.GetBytesDelegate, sh.PutBytesDelegate,
 					sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, ref guid, nativeEncoderParams);
 			} else {

+ 5 - 1
mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs

@@ -1697,10 +1697,14 @@ namespace System.Drawing
 			private byte[]  managedBuf;
 			private const int default_bufsize = 4096;
 			
-			public GdiPlusStreamHelper (Stream s) 
+			public GdiPlusStreamHelper (Stream s, bool seekToOrigin) 
 			{ 
 				managedBuf = new byte [default_bufsize];
+				
 				stream = s;
+				if (stream != null && stream.CanSeek && seekToOrigin) {
+					stream.Seek (0, SeekOrigin.Begin);
+				}
 			}
 
 			public int StreamGetHeaderImpl (IntPtr buf, int bufsz)  {

+ 6 - 0
mcs/class/System.Drawing/Test/System.Drawing/ChangeLog

@@ -1,3 +1,9 @@
+2007-11-05  Sebastien Pouliot  <[email protected]> 
+
+	* Image.cs: Add test cases for the stream position when loading and
+	saving bitmaps and metafiles. Some of them are based on Gert Driesen
+	samples in #338779
+
 2007-08-13  Sebastien Pouliot  <[email protected]>
 
 	* TestGraphics.cs: Test against NRE in MultiplyTransform

+ 77 - 0
mcs/class/System.Drawing/Test/System.Drawing/TestImage.cs

@@ -255,6 +255,18 @@ namespace MonoTests.System.Drawing{
 			}
 		}
 
+		[Test]
+		[Category ("NotWorking")] // https://bugzilla.novell.com/show_bug.cgi?id=338779
+		[ExpectedException (typeof (ArgumentException))]
+		public void FromStream_Metafile_Wmf_NotOrigin ()
+		{
+			string filename = TestBitmap.getInFile ("bitmaps/telescope_01.wmf");
+			using (FileStream fs = File.OpenRead (filename)) {
+				fs.Position = fs.Length / 2;
+				Image.FromStream (fs);
+			}
+		}
+
 		private void Emf (Image img)
 		{
 			Assert.IsFalse (img is Bitmap, "Bitmap");
@@ -287,6 +299,18 @@ namespace MonoTests.System.Drawing{
 			}
 		}
 
+		[Test]
+		[Category ("NotWorking")] // https://bugzilla.novell.com/show_bug.cgi?id=338779
+		[ExpectedException (typeof (ArgumentException))]
+		public void FromStream_Metafile_Emf_NotOrigin ()
+		{
+			string filename = TestBitmap.getInFile ("bitmaps/milkmateya01.emf");
+			using (FileStream fs = File.OpenRead (filename)) {
+				fs.Position = fs.Length / 2;
+				Image.FromStream (fs);
+			}
+		}
+
 		[Test]
 		[ExpectedException (typeof (OutOfMemoryException))]
 		public void FromFile_Invalid ()
@@ -304,5 +328,58 @@ namespace MonoTests.System.Drawing{
 				Image.FromStream (fs);
 			}
 		}
+
+		private Bitmap GetBitmap ()
+		{
+			Bitmap bmp = new Bitmap (20, 10, PixelFormat.Format24bppRgb);
+			using (Graphics g = Graphics.FromImage (bmp))
+			{
+				Pen pen = new Pen (Color.Black, 3);
+				g.DrawRectangle (pen, 0, 0, 5, 10);
+			}
+			return bmp;
+		}
+
+		[Test]
+		public void StreamSaveLoad ()
+		{
+			using (MemoryStream ms = new MemoryStream ()) {
+				using (Bitmap bmp = GetBitmap ()) {
+					Assert.AreEqual (0, ms.Position, "Position-1");
+					bmp.Save (ms, ImageFormat.Bmp);
+					Assert.IsTrue (ms.Position > 0, "Position-2");
+
+					ms.Position = ms.Length;
+					Assert.AreEqual (ms.Length, ms.Position, "Position-3");
+
+					Bitmap bmp2 = (Bitmap)Image.FromStream (ms);
+					Assert.IsTrue (ms.Position > 20, "Position-4");
+
+					Assert.IsTrue (bmp2.RawFormat.Equals (ImageFormat.Bmp), "Bmp");
+
+					Assert.AreEqual (bmp.GetPixel (0, 0), bmp2.GetPixel (0, 0), "0,0");
+					Assert.AreEqual (bmp.GetPixel (10, 0), bmp2.GetPixel (10, 0), "10,0");
+				}
+			}
+		}
+
+		[Test]
+		[ExpectedException (typeof (ArgumentException))]
+		public void StreamJunkSaveLoad ()
+		{
+			using (MemoryStream ms = new MemoryStream ()) {
+				// junk
+				ms.WriteByte (0xff);
+				ms.WriteByte (0xef);
+				Assert.AreEqual (2, ms.Position, "Position-1");
+
+				using (Bitmap bmp = GetBitmap ()) {
+					bmp.Save (ms, ImageFormat.Bmp);
+					Assert.IsTrue (ms.Position > 2, "Position-2");
+					// exception here
+					Image.FromStream (ms);
+				}
+			}
+		}
 	}
 }