X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Drawing%2FSystem.Drawing%2FImage.cs;h=0bfe5c94215db1102aa933a9f7fc273a76e13048;hb=c39145af2464b19374fac41b252e07480ae1a197;hp=41240fe6bb0cd8c13bd781054eea09de9135c2d0;hpb=2a1759993863ad6253d55b9a2db2d9f3d2447cd7;p=mono.git diff --git a/mcs/class/System.Drawing/System.Drawing/Image.cs b/mcs/class/System.Drawing/System.Drawing/Image.cs index 41240fe6bb0..0bfe5c94215 100644 --- a/mcs/class/System.Drawing/System.Drawing/Image.cs +++ b/mcs/class/System.Drawing/System.Drawing/Image.cs @@ -1,12 +1,38 @@ // // System.Drawing.Image.cs // -// (C) 2002 Ximian, Inc. http://www.ximian.com +// Copyright (C) 2002 Ximian, Inc. http://www.ximian.com +// Copyright (C) 2004 Novell, Inc. http://www.novell.com +// // Author: Christian Meyer (Christian.Meyer@cs.tum.edu) // Alexandre Pigolkine (pigolkine@gmx.de) // Jordi Mas i Hernandez (jordi@ximian.com) +// Sanjay Gupta (gsanjay@novell.com) +// Ravindra (rkumar@novell.com) +// + +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -namespace System.Drawing { using System; using System.Runtime.Remoting; @@ -16,6 +42,8 @@ using System.ComponentModel; using System.Drawing.Imaging; using System.IO; +namespace System.Drawing +{ [Serializable] [ComVisible (true)] [Editor ("System.Drawing.Design.ImageEditor, " + Consts.AssemblySystem_Drawing_Design, typeof (System.Drawing.Design.UITypeEditor))] @@ -26,8 +54,8 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer public delegate bool GetThumbnailImageAbort(); internal IntPtr nativeObject = IntPtr.Zero; - protected ColorPalette colorPalette; - protected ImageFormat raw_format; + ColorPalette colorPalette; + // constructor internal Image() @@ -35,15 +63,23 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer colorPalette = new ColorPalette(); } - [MonoTODO] private Image (SerializationInfo info, StreamingContext context) { - + foreach (SerializationEntry serEnum in info) { + if (String.Compare(serEnum.Name, "Data", true) == 0) { + byte[] bytes = (byte[]) serEnum.Value; + + if (bytes != null) { + InitFromStream(new MemoryStream(bytes)); + } + } + } } [MonoTODO] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { + throw new NotImplementedException(); } // public methods @@ -154,6 +190,32 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer return ((pixfmt & PixelFormat.Extended) != 0); } + internal void InitFromStream (Stream stream) + { + if (Environment.OSVersion.Platform == (PlatformID) 128) { + // Unix, 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); + IntPtr imagePtr; + + Status st = GDIPlus.GdipLoadImageFromDelegate_linux (sh.GetBytesDelegate, sh.PutBytesDelegate, + sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, + out imagePtr); + GDIPlus.CheckStatus (st); + nativeObject = imagePtr; + } else { + // this is MS-land + // FIXME + // We can't call the native gdip functions here, because they expect + // a COM IStream interface. So, a hack is to create a tmp file, read + // the stream, and then load from the tmp file. + // This is an ugly hack. + throw new NotImplementedException ("Bitmap.InitFromStream (win32)"); + } + } + // non-static public RectangleF GetBounds (ref GraphicsUnit pageUnit) { @@ -165,124 +227,225 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer return source; } - [MonoTODO] - public EncoderParameters GetEncoderParameterList(Guid encoder) + public EncoderParameters GetEncoderParameterList(Guid format) { - throw new NotImplementedException (); + Status status; + uint sz; + + status = GDIPlus.GdipGetEncoderParameterListSize (nativeObject, ref format, out sz); + GDIPlus.CheckStatus (status); + + IntPtr rawEPList = Marshal.AllocHGlobal ((int) sz); + EncoderParameters eps; + + try { + status = GDIPlus.GdipGetEncoderParameterList (nativeObject, ref format, sz, rawEPList); + eps = EncoderParameters.FromNativePtr (rawEPList); + GDIPlus.CheckStatus (status); + } catch { + Marshal.FreeHGlobal (rawEPList); + throw; + } + + Marshal.FreeHGlobal (rawEPList); + + return eps; } public int GetFrameCount(FrameDimension dimension) { int count; Guid guid = dimension.Guid; - - Status status = GDIPlus.GdipImageGetFrameCount (nativeObject, ref guid, out count); + Status status = GDIPlus.GdipImageGetFrameCount (nativeObject, ref guid, out count); + GDIPlus.CheckStatus (status); return count; } - [MonoTODO] public PropertyItem GetPropertyItem(int propid) { - throw new NotImplementedException (); + int propSize; + IntPtr property; + PropertyItem item = new PropertyItem (); + GdipPropertyItem gdipProperty = new GdipPropertyItem (); + Status status; + + status = GDIPlus.GdipGetPropertyItemSize (nativeObject, propid, + out propSize); + GDIPlus.CheckStatus (status); + + /* Get PropertyItem */ + property = Marshal.AllocHGlobal (propSize); + status = GDIPlus.GdipGetPropertyItem (nativeObject, propid, propSize, + property); + GDIPlus.CheckStatus (status); + gdipProperty = (GdipPropertyItem) Marshal.PtrToStructure ((IntPtr)property, + typeof (GdipPropertyItem)); + GdipPropertyItem.MarshalTo (gdipProperty, item); + + Marshal.FreeHGlobal (property); + return item; } - [MonoTODO] public Image GetThumbnailImage(int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort callback, IntPtr callbackData) { - throw new NotImplementedException (); + Status status; + Image ThumbNail; + Graphics g; + + ThumbNail=new Bitmap(thumbWidth, thumbHeight); + g=Graphics.FromImage(ThumbNail); + + status = GDIPlus.GdipDrawImageRectRectI(g.nativeObject, nativeObject, + 0, 0, thumbWidth, thumbHeight, + 0, 0, this.Width, this.Height, + GraphicsUnit.Pixel, IntPtr.Zero, null, IntPtr.Zero); + GDIPlus.CheckStatus (status); + g.Dispose(); + + return(ThumbNail); } - [MonoTODO] + public void RemovePropertyItem (int propid) { - throw new NotImplementedException (); - } + Status status = GDIPlus.GdipRemovePropertyItem (nativeObject, propid); + GDIPlus.CheckStatus (status); + } - [MonoTODO] public void RotateFlip (RotateFlipType rotateFlipType) - { - throw new NotImplementedException (); + { + Status status = GDIPlus.GdipImageRotateFlip (nativeObject, rotateFlipType); + GDIPlus.CheckStatus (status); } - public void Save (string filename) + internal ImageCodecInfo findEncoderForFormat (ImageFormat format) { - Save (filename, RawFormat); + ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); + ImageCodecInfo encoder = null; + + if (format.Guid.Equals (ImageFormat.MemoryBmp.Guid)) + format = ImageFormat.Bmp; + + /* Look for the right encoder for our format*/ + for (int i = 0; i < encoders.Length; i++) { + if (encoders[i].FormatID.Equals (format.Guid)) { + encoder = encoders[i]; + break; + } + } + + return encoder; } - public void Save (Stream stream, ImageFormat format) + public void Save (string filename) { - if (Environment.OSVersion.Platform == (PlatformID) 128) { - byte[] g = format.Guid.ToByteArray(); - GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream); - Status st = GDIPlus.GdipSaveImageToDelegate_linux (nativeObject, sh.PutBytesDelegate, g, IntPtr.Zero); - } else { - throw new NotImplementedException ("Image.Save(Stream) (win32)"); - } + Save (filename, RawFormat); } public void Save(string filename, ImageFormat format) { - byte[] g = format.Guid.ToByteArray(); - Status st = GDIPlus.GdipSaveImageToFile (nativeObject, filename, g, IntPtr.Zero); - GDIPlus.CheckStatus (st); + ImageCodecInfo encoder = findEncoderForFormat (format); + + if (encoder == null) + throw new ArgumentException ("No codec available for format:" + format.Guid); + + Save (filename, encoder, null); } - - internal void setGDIPalette() + + public void Save(string filename, ImageCodecInfo encoder, EncoderParameters encoderParams) { - IntPtr gdipalette; + Status st; + Guid guid = encoder.Clsid; - gdipalette = colorPalette.getGDIPalette (); - Status st = GDIPlus.GdipSetImagePalette (NativeObject, gdipalette); - Marshal.FreeHGlobal (gdipalette); + if (encoderParams == null) { + st = GDIPlus.GdipSaveImageToFile (nativeObject, filename, ref guid, IntPtr.Zero); + } else { + IntPtr nativeEncoderParams = encoderParams.ToNativePtr (); + st = GDIPlus.GdipSaveImageToFile (nativeObject, filename, ref guid, nativeEncoderParams); + Marshal.FreeHGlobal (nativeEncoderParams); + } GDIPlus.CheckStatus (st); } - [MonoTODO ("Ignoring EncoderParameters")] - public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) + public void Save (Stream stream, ImageFormat format) { - Save (stream, new ImageFormat (encoder.Clsid)); + ImageCodecInfo encoder = findEncoderForFormat (format); + + if (encoder == null) + throw new ArgumentException ("No codec available for format:" + format.Guid); + + Save (stream, encoder, null); } - - [MonoTODO ("Ignoring EncoderParameters")] - public void Save(string filename, ImageCodecInfo encoder, EncoderParameters encoderParams) + + public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) { - Save (filename, new ImageFormat (encoder.Clsid)); + Status st; + Guid guid = encoder.Clsid; + + if (Environment.OSVersion.Platform == (PlatformID) 128) { + GDIPlus.GdiPlusStreamHelper sh = new GDIPlus.GdiPlusStreamHelper (stream); + if (encoderParams == null) { + st = GDIPlus.GdipSaveImageToDelegate_linux (nativeObject, sh.GetBytesDelegate, sh.PutBytesDelegate, + sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, ref guid, IntPtr.Zero); + } else { + IntPtr nativeEncoderParams = encoderParams.ToNativePtr (); + st = GDIPlus.GdipSaveImageToDelegate_linux (nativeObject, sh.GetBytesDelegate, sh.PutBytesDelegate, + sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, ref guid, nativeEncoderParams); + Marshal.FreeHGlobal (nativeEncoderParams); + } + } else { + throw new NotImplementedException ("Image.Save(Stream) (win32)"); + } + GDIPlus.CheckStatus (st); } - [MonoTODO] - public void SaveAdd(EncoderParameters encoderParams) + public void SaveAdd (EncoderParameters encoderParams) { - throw new NotImplementedException (); + Status st; + + IntPtr nativeEncoderParams = encoderParams.ToNativePtr (); + st = GDIPlus.GdipSaveAdd (nativeObject, nativeEncoderParams); + Marshal.FreeHGlobal (nativeEncoderParams); + GDIPlus.CheckStatus (st); } - - [MonoTODO] - public void SaveAdd(Image image, EncoderParameters encoderParams) + + public void SaveAdd (Image image, EncoderParameters encoderParams) { - throw new NotImplementedException (); + Status st; + + IntPtr nativeEncoderParams = encoderParams.ToNativePtr (); + st = GDIPlus.GdipSaveAddImage (nativeObject, image.NativeObject, nativeEncoderParams); + Marshal.FreeHGlobal (nativeEncoderParams); + GDIPlus.CheckStatus (st); } - - + public int SelectActiveFrame(FrameDimension dimension, int frameIndex) { Guid guid = dimension.Guid; - - Status status = GDIPlus.GdipImageSelectActiveFrame (nativeObject, ref guid, frameIndex); - GDIPlus.CheckStatus (status); + Status st = GDIPlus.GdipImageSelectActiveFrame (nativeObject, ref guid, frameIndex); + + GDIPlus.CheckStatus (st); return frameIndex; } - [MonoTODO] public void SetPropertyItem(PropertyItem propitem) { - throw new NotImplementedException (); + IntPtr property; + int size = Marshal.SizeOf (typeof(GdipPropertyItem)); + property = Marshal.AllocHGlobal (size); + + Marshal.StructureToPtr (propitem, property, true); + Status status = GDIPlus.GdipSetPropertyItem (nativeObject, property); + GDIPlus.CheckStatus (status); } // properties + [Browsable (false)] public int Flags { get { int flags; @@ -293,13 +456,22 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer } } - [MonoTODO] + [Browsable (false)] public Guid[] FrameDimensionsList { get { - throw new NotImplementedException (); + uint found; + Status status = GDIPlus.GdipImageGetFrameDimensionsCount (nativeObject, out found); + GDIPlus.CheckStatus (status); + Guid [] guid = new Guid [found]; + status = GDIPlus.GdipImageGetFrameDimensionsList (nativeObject, guid, found); + GDIPlus.CheckStatus (status); + return guid; } } - + + [DefaultValue (false)] + [Browsable (false)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public int Height { get { int height; @@ -321,6 +493,7 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer } } + [Browsable (false)] public ColorPalette Palette { get { @@ -330,12 +503,10 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer colorPalette = value; } } - - + public SizeF PhysicalDimension { get { float width, height; - Status status = GDIPlus.GdipGetImageDimension (nativeObject, out width, out height); GDIPlus.CheckStatus (status); @@ -344,42 +515,82 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer } public PixelFormat PixelFormat { - get { - - PixelFormat value; - Status status = GDIPlus.GdipGetImagePixelFormat (nativeObject, out value); + get { + PixelFormat pixFormat; + Status status = GDIPlus.GdipGetImagePixelFormat (nativeObject, out pixFormat); GDIPlus.CheckStatus (status); - return value; + return pixFormat; } } - - [MonoTODO] + [Browsable (false)] public int[] PropertyIdList { get { - throw new NotImplementedException (); + uint propNumbers; + + Status status = GDIPlus.GdipGetPropertyCount (nativeObject, + out propNumbers); + GDIPlus.CheckStatus (status); + + int [] idList = new int [propNumbers]; + status = GDIPlus.GdipGetPropertyIdList (nativeObject, + propNumbers, idList); + GDIPlus.CheckStatus (status); + + return idList; } } - [MonoTODO] + [Browsable (false)] public PropertyItem[] PropertyItems { get { - throw new NotImplementedException (); + int propNums, propsSize, propSize; + IntPtr properties, propPtr; + PropertyItem[] items; + GdipPropertyItem gdipProperty = new GdipPropertyItem (); + Status status; + + status = GDIPlus.GdipGetPropertySize (nativeObject, out propsSize, out propNums); + GDIPlus.CheckStatus (status); + + items = new PropertyItem [propNums]; + + if (propNums == 0) + return items; + + /* Get PropertyItem list*/ + properties = Marshal.AllocHGlobal (propsSize); + status = GDIPlus.GdipGetAllPropertyItems (nativeObject, propsSize, + propNums, properties); + GDIPlus.CheckStatus (status); + + propSize = Marshal.SizeOf (gdipProperty); + propPtr = properties; + + for (int i = 0; i < propNums; i++, propPtr = new IntPtr (propPtr.ToInt64 () + propSize)) + { + gdipProperty = (GdipPropertyItem) Marshal.PtrToStructure + (propPtr, typeof (GdipPropertyItem)); + items [i] = new PropertyItem (); + GdipPropertyItem.MarshalTo (gdipProperty, items [i]); + } + + Marshal.FreeHGlobal (properties); + return items; } } public ImageFormat RawFormat { get { - return raw_format; + Guid guid; + Status st = GDIPlus.GdipGetImageRawFormat (nativeObject, out guid); + + GDIPlus.CheckStatus (st); + return new ImageFormat (guid); } } - - internal void SetRawFormat (ImageFormat format) - { - raw_format = format; - } - + public Size Size { get { return new Size(Width, Height); @@ -390,11 +601,16 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer get { float resolution; - GDIPlus.GdipGetImageVerticalResolution (nativeObject, out resolution); + Status status = GDIPlus.GdipGetImageVerticalResolution (nativeObject, out resolution); + GDIPlus.CheckStatus (status); + return resolution; } } - + + [DefaultValue (false)] + [Browsable (false)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public int Width { get { int width; @@ -417,6 +633,7 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer public void Dispose () { Dispose (true); + System.GC.SuppressFinalize (this); } ~Image () @@ -424,35 +641,46 @@ public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISer Dispose (false); } - protected virtual void DisposeResources () + private void DisposeResources () { - GDIPlus.GdipDisposeImage (nativeObject); + lock (this) + { + Status status = GDIPlus.GdipDisposeImage (nativeObject); + GDIPlus.CheckStatus (status); + } } protected virtual void Dispose (bool disposing) { - if (nativeObject != (IntPtr) 0){ + if (nativeObject != IntPtr.Zero){ DisposeResources (); - nativeObject=IntPtr.Zero; + nativeObject = IntPtr.Zero; } } - public virtual object Clone() { - IntPtr newimage = IntPtr.Zero; - - if (!(this is Bitmap)) + lock (this) + { + IntPtr newimage = IntPtr.Zero; + + if (!(this is Bitmap)) + throw new NotImplementedException (); + + Status status = GDIPlus.GdipCloneImage (NativeObject, out newimage); + GDIPlus.CheckStatus (status); + + if (this is Bitmap){ + Bitmap b = new Bitmap (newimage); + + if (colorPalette != null) + b.colorPalette = colorPalette.Clone (); + + return b; + } + throw new NotImplementedException (); - - Status status = GDIPlus.GdipCloneImage (NativeObject, out newimage); - - GDIPlus.CheckStatus (status); - - if (this is Bitmap) - return new Bitmap (newimage); - - throw new NotImplementedException (); + } } }