Image.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / CommonUI / System / Drawing / Image.cs / 1 / Image.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Drawing { 
    using System.Runtime.Serialization.Formatters; 
    using System.Threading;
    using System.Runtime.InteropServices; 
    using System.Runtime.Serialization;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System; 
    using System.Drawing.Design;
    using System.IO; 
    using System.Reflection; 
    using System.ComponentModel;
    using ArrayList = System.Collections.ArrayList; 
    using Microsoft.Win32;
    using System.Drawing.Imaging;
    using System.Drawing.Internal;
    using System.Security; 
    using System.Security.Permissions;
    using System.Globalization; 
 
    /**
     * Represent an image object (could be bitmap or vector) 
     */
    /// 
    /// 
    ///    An abstract base class that provides 
    ///    functionality for 'Bitmap', 'Icon', 'Cursor', and 'Metafile' descended classes.
    ///  
    [ 
    TypeConverterAttribute(typeof(ImageConverter)),
    Editor("System.Drawing.Design.ImageEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor)), 
    ImmutableObject(true)
    ]
    [Serializable]
    [ComVisible(true)] 
    public abstract class Image : MarshalByRefObject, ISerializable, ICloneable, IDisposable {
 
#if FINALIZATION_WATCH 
        private string allocationSite = Graphics.GetAllocationStack();
#endif 


        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public delegate bool GetThumbnailImageAbort(); 

        /* 
         * Handle to native image object
         */
        internal IntPtr nativeImage;
 
        // used to work around lack of animated gif encoder... rarely set...
        // 
        byte[] rawData; 

        //userData : so that user can use TAGS with IMAGES.. 
        private object userData;

        /**
         * Constructor can't be invoked directly 
         */
        internal Image() { 
        } 

        /** 
         * Constructor used in deserialization
         */
        internal Image(SerializationInfo info, StreamingContext context) {
            SerializationInfoEnumerator sie = info.GetEnumerator(); 
            if (sie == null) {
                return; 
            } 
            for (; sie.MoveNext();) {
                if (String.Equals(sie.Name, "Data", StringComparison.OrdinalIgnoreCase)) 
                {
                    try {
                        byte[] dat = (byte[])sie.Value;
                        if (dat != null) { 
                            InitializeFromStream(new MemoryStream(dat));
                        } 
 
                    }
                    catch (ExternalException e) { 
                        Debug.Fail("failure: " + e.ToString());
                    }
                    catch (ArgumentException e) {
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                    catch (OutOfMemoryException e) { 
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                    catch (InvalidOperationException e) { 
                        Debug.Fail("failure: " + e.ToString());
                    }
                    catch (NotImplementedException e) {
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                    catch (FileNotFoundException e) { 
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                } 
            }
        }

        ///  
        [
        Localizable(false), 
        Bindable(true), 
        DefaultValue(null),
        TypeConverter(typeof(StringConverter)) 
        ]
        public object Tag {
            get {
                return userData; 
            }
            set { 
                userData = value; 
            }
        } 

        /**
        * Create an image object from a URL
        */ 
        /// 
        ///  
        ///    Creates an  from the specified file. 
        /// 
        // [Obsolete("Use Image.FromFile(string, useEmbeddedColorManagement)")] 
        public static Image FromFile(String filename) {
            return Image.FromFile(filename, false);
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static Image FromFile(String filename, 
                                     bool useEmbeddedColorManagement) {

            // SECREVIEW : The File.Exists() below will do the demand for the FileIOPermission
            //             for us. So, we do not need an additional demand anymore. 
            //
            if (!File.Exists(filename)) { 
                // I have to do this so I can give a meaningful 
                // error back to the user. File.Exists() cal fail because of either
                // a failure to demand security or because the file does not exist. 
                // Always telling the user that the file does not exist is not a good
                // choice. So, we demand the permission again. This means that we are
                // going to demand the permission twice for the failure case, but that's
                // better than always demanding the permission twice. 
                //
                IntSecurity.DemandReadFileIO(filename); 
 
                throw new FileNotFoundException(filename);
            } 

            //GDI+ will read this file multiple times.  Get the fully qualified path
            //so if our app changes default directory we won't get an error
            // SECREVIEW : If path does exist, the caller must have FileIOPermissionAccess.PathDiscovery permission. 
            //             Note that unlike most members of the Path class, this method accesses the file system.
            // 
            filename = Path.GetFullPath(filename); 

            IntPtr image = IntPtr.Zero; 
            int status;

            if (useEmbeddedColorManagement) {
                status = SafeNativeMethods.Gdip.GdipLoadImageFromFileICM(filename, out image); 
            }
            else { 
                status = SafeNativeMethods.Gdip.GdipLoadImageFromFile(filename, out image); 
            }
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, image)); 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, image)); 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 

            Image img = CreateImageObject(image);

            EnsureSave(img, filename, null); 

            return img; 
        } 

 
        /**
         * Create an image object from a data stream
         */
        ///  
        /// 
        ///    Creates an  from the specified data 
        ///    stream. 
        /// 
        // [Obsolete("Use Image.FromStream(stream, useEmbeddedColorManagement)")] 
        public static Image FromStream(Stream stream) {
            return Image.FromStream(stream, false);
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static Image FromStream(Stream stream, 
                                       bool useEmbeddedColorManagement)
        {
            return FromStream( stream, useEmbeddedColorManagement, true );
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public static Image FromStream(Stream stream, bool useEmbeddedColorManagement, bool validateImageData ) {
            if( !validateImageData ) {
                IntSecurity.UnmanagedCode.Demand();
            } 

            if (stream == null){ 
                throw new ArgumentException(SR.GetString(SR.InvalidArgument, "stream", "null")); 
            }
 
            IntPtr image = IntPtr.Zero;
            int status;

            if (useEmbeddedColorManagement) { 
                status = SafeNativeMethods.Gdip.GdipLoadImageFromStreamICM(new GPStream(stream), out image);
            } 
            else { 
                status = SafeNativeMethods.Gdip.GdipLoadImageFromStream(new GPStream(stream), out image);
            } 

            if (status != SafeNativeMethods.Gdip.Ok){
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 

            if( validateImageData ) { 
                status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, image)); 

                if (status != SafeNativeMethods.Gdip.Ok) { 
                    SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, image));
                    throw SafeNativeMethods.Gdip.StatusException(status);
                }
            } 

            Image img = CreateImageObject(image); 
 
            EnsureSave(img, null, stream);
 
            return img;
        }

        // Used for serialization 
        private void InitializeFromStream(Stream stream) {
            IntPtr image = IntPtr.Zero; 
 
            int status = SafeNativeMethods.Gdip.GdipLoadImageFromStream(new GPStream(stream), out image);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, image)); 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, image)); 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 

            this.nativeImage = image;

            int type = -1; 

            status = SafeNativeMethods.Gdip.GdipGetImageType(new HandleRef(this, nativeImage), out type); 
 
            EnsureSave(this, null, stream);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        }
 
        internal Image(IntPtr nativeImage) {
            SetNativeImage(nativeImage); 
        } 

        /** 
         * Make a copy of the image object
         */
        /// 
        ///  
        ///    Creates an exact copy of this .
        ///  
        public object Clone() { 
            IntPtr cloneImage = IntPtr.Zero;
 
            int status = SafeNativeMethods.Gdip.GdipCloneImage(new HandleRef(this, nativeImage), out cloneImage);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 

            status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, cloneImage)); 
 
            if (status != SafeNativeMethods.Gdip.Ok) {
                SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, cloneImage)); 
                throw SafeNativeMethods.Gdip.StatusException(status);
            }

            return CreateImageObject(cloneImage); 
        }
 
        /** 
         * Dispose of resources associated with the Image object
         */ 
        /// 
        /// 
        ///    Cleans up Windows resources for this
        /// . 
        /// 
        public void Dispose() { 
            Dispose(true); 
            GC.SuppressFinalize(this);
        } 

        /// 
        protected virtual void Dispose(bool disposing) {
#if FINALIZATION_WATCH 
            if (!disposing && nativeImage != IntPtr.Zero)
                Debug.WriteLine("**********************\nDisposed through finalization:\n" + allocationSite); 
#endif 
            if (nativeImage != IntPtr.Zero) {
                try{ 
#if DEBUG
                    int status =
#endif
                    SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(this, nativeImage)); 
#if DEBUG
                    Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture)); 
#endif 
                }
                catch( Exception ex ){ 
                    if( ClientUtils.IsSecurityOrCriticalException( ex ) ) {
                        throw;
                    }
 
                    Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() );
                } 
                finally{ 
                    nativeImage = IntPtr.Zero;
                } 
            }
        }

        ///  
        /// 
        ///    Cleans up Windows resources for this 
        /// . 
        /// 
        ~Image() { 
            Dispose(false);
        }

        internal static void EnsureSave(Image image, string filename, Stream dataStream) { 

            if (image.RawFormat.Equals(ImageFormat.Gif)) { 
                bool animatedGif = false; 

                Guid[] dimensions = image.FrameDimensionsList; 
                foreach (Guid guid in dimensions) {
                    FrameDimension dimension = new FrameDimension(guid);
                    if (dimension.Equals(FrameDimension.Time)) {
                        animatedGif = image.GetFrameCount(FrameDimension.Time) > 1; 
                        break;
                    } 
                } 

 
                if (animatedGif) {
                    try {
                        Stream created = null;
                        long lastPos = 0; 
                        if (dataStream != null) {
                            lastPos = dataStream.Position; 
                            dataStream.Position = 0; 
                        }
 
                        try {
                            if (dataStream == null) {
                                created = dataStream = File.OpenRead(filename);
                            } 

                            image.rawData = new byte[(int)dataStream.Length]; 
                            dataStream.Read(image.rawData, 0, (int)dataStream.Length); 
                        }
                        finally { 
                            if (created != null) {
                                created.Close();
                            }
                            else { 
                                dataStream.Position = lastPos;
                            } 
                        } 
                    }
                    // possible exceptions for reading the filename 
                    catch (UnauthorizedAccessException) {
                    }
                    catch (DirectoryNotFoundException) {
                    } 
                    catch (IOException) {
                    } 
                    // possible exceptions for setting/getting the position inside dataStream 
                    catch (NotSupportedException) {
                    } 
                    catch (ObjectDisposedException) {
                    }
                    // possible exception when reading stuff into dataStream
                    catch (ArgumentException) { 
                    }
                } 
            } 
        }
 
        private enum ImageTypeEnum  {
            Bitmap = 1,
            Metafile = 2,
        } 

        /* FxCop rule 'AvoidBuildingNonCallableCode' - Left here in case it is needed in the future. 
        private ImageTypeEnum ImageType 
        {
            get { 
                int type = -1;

                int status = SafeNativeMethods.Gdip.GdipGetImageType(new HandleRef(this, nativeImage), out type);
 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
 
                return(ImageTypeEnum) type;
            } 
        }
        */

        internal static Image CreateImageObject(IntPtr nativeImage) { 
            Image image;
 
            int type = -1; 

            int status = SafeNativeMethods.Gdip.GdipGetImageType(new HandleRef(null, nativeImage), out type); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            switch ((ImageTypeEnum)type) {
                case ImageTypeEnum.Bitmap: 
                    image = Bitmap.FromGDIplus(nativeImage); 
                    break;
 
                case ImageTypeEnum.Metafile:
                    image = Metafile.FromGDIplus(nativeImage);
                    break;
 
                default:
                    throw new ArgumentException(SR.GetString(SR.InvalidImage)); 
            } 

            return image; 
        }

        /// 
        ///  
        ///     ISerializable private implementation
        ///  
        ///  
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
        [SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly")] 
        void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) {
            using( MemoryStream stream = new MemoryStream() ) {
                Save( stream );
                si.AddValue("Data", stream.ToArray(), typeof(byte[])); 
            }
        } 
 
        /// 
        ///  
        ///    Returns information about the codecs used
        ///    for this .
        /// 
        public EncoderParameters GetEncoderParameterList(Guid encoder) { 
            EncoderParameters p;
            int size; 
 
            int status = SafeNativeMethods.Gdip.GdipGetEncoderParameterListSize(new HandleRef(this, nativeImage),
                                                                 ref encoder, 
                                                                 out size);
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            if (size <= 0)
                return null; 
 
            IntPtr buffer = Marshal.AllocHGlobal(size);
 
            status = SafeNativeMethods.Gdip.GdipGetEncoderParameterList(new HandleRef(this, nativeImage),
                                                         ref encoder,
                                                         size,
                                                         buffer); 

            try{ 
                if (status != SafeNativeMethods.Gdip.Ok) { 
                    throw SafeNativeMethods.Gdip.StatusException(status);
                } 

                p = EncoderParameters.ConvertFromMemory(buffer);
            }
            finally{ 
                Marshal.FreeHGlobal(buffer);
            } 
 
            return p;
        } 

        /// 
        /// 
        ///    Saves this  to the specified file. 
        /// 
        public void Save(string filename) { 
            Save( filename, RawFormat ); 
        }
 
        /// 
        /// 
        ///    Saves this  to the specified file in the
        ///    specified format. 
        /// 
        public void Save(string filename, ImageFormat format) { 
            if (format == null) 
                throw new ArgumentNullException("format");
 
            ImageCodecInfo codec = format.FindEncoder();

            if (codec == null)
                codec = ImageFormat.Png.FindEncoder(); 

            Save(filename, codec, null); 
        } 

        ///  
        /// 
        ///    
        ///       Saves this  to the specified file in the specified format
        ///       and with the specified encoder parameters. 
        ///    
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Save(string filename, ImageCodecInfo encoder, EncoderParameters encoderParams) {
            if (filename == null) 
                throw new ArgumentNullException("filename");
            if (encoder == null)
                throw new ArgumentNullException("encoder");
 
            IntSecurity.DemandWriteFileIO(filename);
 
            IntPtr encoderParamsMemory = IntPtr.Zero; 

            if (encoderParams != null) { 
                rawData = null;
                encoderParamsMemory = encoderParams.ConvertToMemory();
            }
            int status = SafeNativeMethods.Gdip.Ok; 

            try { 
                Guid g = encoder.Clsid; 
                bool saved = false;
 
                if (rawData != null) {
                    ImageCodecInfo rawEncoder = RawFormat.FindEncoder();
                    if (rawEncoder != null && rawEncoder.Clsid == g) {
                        using (FileStream fs = File.OpenWrite(filename)) { 
                            fs.Write(rawData, 0, rawData.Length);
                            saved = true; 
                        } 
                    }
                } 

                if (!saved) {
                    status = SafeNativeMethods.Gdip.GdipSaveImageToFile(new HandleRef(this, nativeImage),
                                                             filename, 
                                                             ref g,
                                                             new HandleRef(encoderParams, encoderParamsMemory)); 
                } 
            }
            finally { 
                if (encoderParamsMemory != IntPtr.Zero) {
                    Marshal.FreeHGlobal(encoderParamsMemory);
                }
            } 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status); 
            }
        } 

        internal void Save(MemoryStream stream) {
            // Jpeg loses data, so we don't want to use it to serialize...
            // 
            ImageFormat dest = RawFormat;
            if (dest == ImageFormat.Jpeg) { 
                dest = ImageFormat.Png; 
            }
            ImageCodecInfo codec = dest.FindEncoder(); 

            // If we don't find an Encoder (for things like Icon), we
            // just switch back to PNG...
            // 
            if (codec == null) {
                codec = ImageFormat.Png.FindEncoder(); 
            } 
            Save(stream, codec, null);
        } 

        /// 
        /// 
        ///     
        ///       Saves this  to the specified stream in the specified
        ///       format. 
        ///     
        /// 
        public void Save(Stream stream, ImageFormat format) { 
            if (format == null)
                throw new ArgumentNullException("format");

            ImageCodecInfo codec = format.FindEncoder(); 
            Save(stream, codec, null);
        } 
 
        /// 
        ///  
        ///    
        ///       Saves this  to the specified stream in the specified
        ///       format.
        ///     
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) { 
            if (stream == null){
                throw new ArgumentNullException("stream"); 
            }
            if (encoder == null) {
                throw new ArgumentNullException("encoder");
            } 

            IntPtr encoderParamsMemory = IntPtr.Zero; 
 
            if (encoderParams != null) {
                rawData = null; 
                encoderParamsMemory = encoderParams.ConvertToMemory();
            }

            int status = SafeNativeMethods.Gdip.Ok; 

            try { 
                Guid g = encoder.Clsid; 
                bool saved = false;
 
                if (rawData != null) {
                    ImageCodecInfo rawEncoder = RawFormat.FindEncoder();
                    if (rawEncoder != null && rawEncoder.Clsid == g) {
                        stream.Write(rawData, 0, rawData.Length); 
                        saved = true;
                    } 
                } 

                if (!saved) { 
                    status = SafeNativeMethods.Gdip.GdipSaveImageToStream(new HandleRef(this, nativeImage),
                                                                     new UnsafeNativeMethods.ComStreamFromDataStream(stream),
                                                                     ref g,
                                                                     new HandleRef(encoderParams, encoderParamsMemory)); 
                }
            } 
            finally { 
                if (encoderParamsMemory != IntPtr.Zero) {
                    Marshal.FreeHGlobal(encoderParamsMemory); 
                }
            }

            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        } 

        ///  
        /// 
        ///    
        ///       Adds an  to this
        ///    . 
        ///    
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void SaveAdd(EncoderParameters encoderParams) {
            IntPtr encoder = IntPtr.Zero; 
            if (encoderParams != null) {
                encoder = encoderParams.ConvertToMemory();
            }
 
            rawData = null;
            int status = SafeNativeMethods.Gdip.GdipSaveAdd(new HandleRef(this, nativeImage), new HandleRef(encoderParams, encoder)); 
 
            if (encoder != IntPtr.Zero) {
                Marshal.FreeHGlobal(encoder); 
            }
            if (status != SafeNativeMethods.Gdip.Ok) {
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Adds an  to the
        ///       specified .
        ///    
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public void SaveAdd(Image image, EncoderParameters encoderParams) { 
            IntPtr encoder = IntPtr.Zero; 

            if (image == null) { 
                throw new ArgumentNullException("image");
            }
            if (encoderParams != null) {
                encoder = encoderParams.ConvertToMemory(); 
            }
 
            rawData = null; 
            int status = SafeNativeMethods.Gdip.GdipSaveAddImage(new HandleRef(this, nativeImage), new HandleRef(image, image.nativeImage), new HandleRef(encoderParams, encoder));
 
            if (encoder != IntPtr.Zero){
                Marshal.FreeHGlobal(encoder);
            }
            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        } 

        /** 
         * Return; image size information
         */
        private SizeF _GetPhysicalDimension() {
            float width; 
            float height;
 
            int status = SafeNativeMethods.Gdip.GdipGetImageDimension(new HandleRef(this, nativeImage), out width, out height); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);

            return new SizeF(width, height);
        } 

        ///  
        ///  
        ///    
        ///       Gets the width and height of this 
        ///    .
        ///    
        /// 
        public SizeF PhysicalDimension { 
            get { return _GetPhysicalDimension();}
        } 
 
        /// 
        ///  
        ///    
        ///       Gets the width and height of this .
        ///    
        ///  
        public Size Size {
            get { 
                return new Size(Width, Height); 
            }
        } 

        /// 
        /// 
        ///    Gets the width of this . 
        /// 
        [ 
        DefaultValue(false), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public int Width {
            get {
                int width; 

                int status = SafeNativeMethods.Gdip.GdipGetImageWidth(new HandleRef(this, nativeImage), out width); 
 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return width;
            }
        } 

        ///  
        ///  
        ///    Gets the height of this .
        ///  
        [
        DefaultValue(false),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public int Height { 
            get { 
                int height;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageHeight(new HandleRef(this, nativeImage), out height);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return height; 
            } 
        }
 
        /// 
        /// 
        ///    Gets the horizontal resolution, in
        ///    pixels-per-inch, of this . 
        /// 
        public float HorizontalResolution { 
            get { 
                float horzRes;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageHorizontalResolution(new HandleRef(this, nativeImage), out horzRes);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return horzRes; 
            } 
        }
 
        /// 
        /// 
        ///    Gets the vertical resolution, in
        ///    pixels-per-inch, of this . 
        /// 
        public float VerticalResolution { 
            get { 
                float vertRes;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageVerticalResolution(new HandleRef(this, nativeImage), out vertRes);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return vertRes; 
            } 
        }
 
        /// 
        /// 
        ///    Gets attribute flags for this .
        ///  
        [Browsable(false)]
        public int Flags { 
            get { 
                int flags;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageFlags(new HandleRef(this, nativeImage), out flags);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return flags; 
            } 
        }
 
        /// 
        /// 
        ///    Gets the format of this .
        ///  
        public ImageFormat RawFormat {
            get { 
                Guid guid = new Guid(); 

                int status = SafeNativeMethods.Gdip.GdipGetImageRawFormat(new HandleRef(this, nativeImage), ref guid); 

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
 

                return new ImageFormat(guid); 
            } 
        }
 
        /// 
        /// 
        ///    Gets the pixel format for this .
        ///  
        public PixelFormat PixelFormat {
            get { 
                int format; 

                int status = SafeNativeMethods.Gdip.GdipGetImagePixelFormat(new HandleRef(this, nativeImage), out format); 

                if (status != SafeNativeMethods.Gdip.Ok)
                    return PixelFormat.Undefined;
                else 
                    return(PixelFormat)format;
            } 
        } 

        ///  
        /// 
        ///    Gets a bounding rectangle in
        ///    the specified units for this .
        ///  
        [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
        public RectangleF GetBounds(ref GraphicsUnit pageUnit) { 
            GPRECTF gprectf = new GPRECTF(); 

            int status = SafeNativeMethods.Gdip.GdipGetImageBounds(new HandleRef(this, nativeImage), ref gprectf, out pageUnit); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return gprectf.ToRectangleF();
        } 
 
        private ColorPalette _GetColorPalette() {
            int size = -1; 

            int status = SafeNativeMethods.Gdip.GdipGetImagePaletteSize(new HandleRef(this, nativeImage), out size);
            // "size" is total byte size:
            // sizeof(ColorPalette) + (pal->Count-1)*sizeof(ARGB) 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status); 
            }
 
            ColorPalette palette = new ColorPalette(size);

            // Memory layout is:
            //    UINT Flags 
            //    UINT Count
            //    ARGB Entries[size] 
 
            IntPtr memory = Marshal.AllocHGlobal(size);
 
            status = SafeNativeMethods.Gdip.GdipGetImagePalette(new HandleRef(this, nativeImage), memory, size);

            try {
                if (status != SafeNativeMethods.Gdip.Ok) { 
                    throw SafeNativeMethods.Gdip.StatusException(status);
                } 
 
                palette.ConvertFromMemory(memory);
            } 
            finally {
                Marshal.FreeHGlobal(memory);
            }
 
            return palette;
        } 
 
        private void _SetColorPalette(ColorPalette palette) {
            IntPtr memory = palette.ConvertToMemory(); 

            int status = SafeNativeMethods.Gdip.GdipSetImagePalette(new HandleRef(this, nativeImage), memory);

            if (memory != IntPtr.Zero) { 
                Marshal.FreeHGlobal(memory);
            } 
            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        }

        /// 
        ///  
        ///    Gets or sets the color
        ///    palette used for this . 
        ///  
        [Browsable(false)]
        public ColorPalette Palette 
        {
            get {
                return _GetColorPalette();
            } 
            set {
                _SetColorPalette(value); 
            } 
        }
 
        // Thumbnail support

        /// 
        ///  
        ///    Returns the thumbnail for this .
        ///  
        public Image GetThumbnailImage(int thumbWidth, int thumbHeight, 
                                       GetThumbnailImageAbort callback, IntPtr callbackData) {
            IntPtr thumbImage = IntPtr.Zero; 

            int status = SafeNativeMethods.Gdip.GdipGetImageThumbnail(new HandleRef(this, nativeImage), thumbWidth, thumbHeight, out thumbImage,
                                                       callback, callbackData);
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return CreateImageObject(thumbImage); 
        }
 
        // Multi-frame support

        /// 
        ///  
        ///    
        ///       Gets an array of GUIDs that represent the 
        ///       dimensions of frames within this . 
        ///    
        ///  
        [Browsable(false)]
        public Guid[] FrameDimensionsList {
            [SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")]
            get { 
                int count;
 
                int status = SafeNativeMethods.Gdip.GdipImageGetFrameDimensionsCount(new HandleRef(this, nativeImage), out count); 

                if (status != SafeNativeMethods.Gdip.Ok) { 
                    throw SafeNativeMethods.Gdip.StatusException(status);
                }

                Debug.Assert(count >= 0, "FrameDimensionsList returns bad count"); 
                if (count <= 0) {
                    return new Guid[0]; 
                } 

                int size = (int) Marshal.SizeOf(typeof(Guid)); 

                IntPtr buffer = Marshal.AllocHGlobal(size*count);
                if (buffer == IntPtr.Zero) {
                    throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory); 
                }
 
                status = SafeNativeMethods.Gdip.GdipImageGetFrameDimensionsList(new HandleRef(this, nativeImage), buffer, count); 

                if (status != SafeNativeMethods.Gdip.Ok) { 
                    Marshal.FreeHGlobal(buffer);
                    throw SafeNativeMethods.Gdip.StatusException(status);
                }
 
                Guid[] guids = new Guid[count];
 
                try { 
                    for (int i=0; i
        /// 
        ///     
        ///       Returns the number of frames of the given
        ///       dimension. 
        ///     
        /// 
        public int GetFrameCount(FrameDimension dimension) { 
            int[] count = new int[] { 0};

            Guid dimensionID = dimension.Guid;
            int status = SafeNativeMethods.Gdip.GdipImageGetFrameCount(new HandleRef(this, nativeImage), ref dimensionID, count); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            return count[0]; 
        }

        /// 
        ///  
        ///    
        ///       Selects the frame specified by the given 
        ///       dimension and index. 
        ///    
        ///  
        public int SelectActiveFrame(FrameDimension dimension, int frameIndex) {
            int[] count = new int[] { 0};

            Guid dimensionID = dimension.Guid; 
            int status = SafeNativeMethods.Gdip.GdipImageSelectActiveFrame(new HandleRef(this, nativeImage), ref dimensionID, frameIndex);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return count[0];
        }

        ///  
        /// 
        ///     
        ///     
        /// 
        public void RotateFlip(RotateFlipType rotateFlipType) { 

            int status = SafeNativeMethods.Gdip.GdipImageRotateFlip(new HandleRef(this, nativeImage), (int) rotateFlipType);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
        } 

        ///  
        /// 
        ///    Gets an array of the property IDs stored in
        ///    this .
        ///  
        [Browsable(false)]
        public int[] PropertyIdList 
        { 
            get {
                int count; 

                int status = SafeNativeMethods.Gdip.GdipGetPropertyCount(new HandleRef(this, nativeImage), out count);

                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
 
                int[] propid = new int[count]; 

                //if we have a 0 count, just return our empty array 
                if (count == 0)
                    return propid;

                status = SafeNativeMethods.Gdip.GdipGetPropertyIdList(new HandleRef(this, nativeImage), count, propid); 

                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return propid; 
            }
        }

        ///  
        /// 
        ///    Gets the specified property item from this 
        /// . 
        /// 
        public PropertyItem GetPropertyItem(int propid) { 
            PropertyItem propitem;
            int size;

            int status = SafeNativeMethods.Gdip.GdipGetPropertyItemSize(new HandleRef(this, nativeImage), propid, out size); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            if (size == 0) 
                return null;

            IntPtr propdata = Marshal.AllocHGlobal(size);
 
            if (propdata == IntPtr.Zero)
                throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory); 
 
            status = SafeNativeMethods.Gdip.GdipGetPropertyItem(new HandleRef(this, nativeImage), propid, size, propdata);
 
            try {
                if (status != SafeNativeMethods.Gdip.Ok) {
                    throw SafeNativeMethods.Gdip.StatusException(status);
                } 

                propitem = PropertyItemInternal.ConvertFromMemory(propdata, 1)[0]; 
            } 
            finally {
                Marshal.FreeHGlobal(propdata); 
            }

            return propitem;
        } 

        ///  
        ///  
        ///    Removes the specified property item from
        ///    this . 
        /// 
        public void RemovePropertyItem(int propid) {
            int status = SafeNativeMethods.Gdip.GdipRemovePropertyItem(new HandleRef(this, nativeImage), propid);
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Sets the specified property item to the
        ///       specified value.
        ///     
        /// 
        public void SetPropertyItem(PropertyItem propitem) { 
            PropertyItemInternal propItemInternal = PropertyItemInternal.ConvertFromPropertyItem(propitem); 

            using (propItemInternal) { 
                int status = SafeNativeMethods.Gdip.GdipSetPropertyItem(new HandleRef(this, nativeImage), propItemInternal);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        }
 
        ///  
        /// 
        ///    Gets an array of  objects that describe this . 
        /// 
        [Browsable(false)]
        public PropertyItem[] PropertyItems
        { 
            get {
                int size; 
                int count; 

                int status = SafeNativeMethods.Gdip.GdipGetPropertyCount(new HandleRef(this, nativeImage), out count); 

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
 
                status = SafeNativeMethods.Gdip.GdipGetPropertySize(new HandleRef(this, nativeImage), out size, ref count);
 
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
 
                if (size == 0 || count == 0)
                    return new PropertyItem[0];

                IntPtr propdata = Marshal.AllocHGlobal(size); 

                status = SafeNativeMethods.Gdip.GdipGetAllPropertyItems(new HandleRef(this, nativeImage), size, count, propdata); 
 
                PropertyItem[] props = null;
 
                try {
                    if (status != SafeNativeMethods.Gdip.Ok) {
                        throw SafeNativeMethods.Gdip.StatusException(status);
                    } 

                    props = PropertyItemInternal.ConvertFromMemory(propdata, count); 
                } 
                finally {
                    Marshal.FreeHGlobal(propdata); 
                }

                return props;
            } 
        }
 
        internal void SetNativeImage(IntPtr handle) { 
            if (handle == IntPtr.Zero)
                throw new ArgumentException(SR.GetString(SR.NativeHandle0), "handle"); 

            nativeImage = handle;
        }
 
        // !! Ambiguous to offer constructor for 'FromHbitmap'
        ///  
        ///  
        ///    Creates a  from a Windows handle.
        ///  
        public static Bitmap FromHbitmap(IntPtr hbitmap) {
            IntSecurity.ObjectFromWin32Handle.Demand();

            return FromHbitmap(hbitmap, IntPtr.Zero); 
        }
 
        ///  
        /// 
        ///     
        ///       Creates a  from the specified Windows
        ///       handle with the specified color palette.
        ///    
        ///  
        public static Bitmap FromHbitmap(IntPtr hbitmap, IntPtr hpalette) {
            IntSecurity.ObjectFromWin32Handle.Demand(); 
 
            IntPtr bitmap = IntPtr.Zero;
            int status = SafeNativeMethods.Gdip.GdipCreateBitmapFromHBITMAP(new HandleRef(null, hbitmap), new HandleRef(null, hpalette), out bitmap); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return Bitmap.FromGDIplus(bitmap);
        } 
 
        /*
         * Return the pixel size for the specified format (in bits) 
         */
        /// 
        /// 
        ///    Returns the size of the specified pixel 
        ///    format.
        ///  
        public static int GetPixelFormatSize(PixelFormat pixfmt) { 
            return((int)pixfmt >> 8) & 0xFF;
        } 

        /*
         * Determine if the pixel format can have alpha channel
         */ 
        /// 
        ///  
        ///     
        ///       Returns a value indicating whether the
        ///       pixel format contains alpha information. 
        ///    
        /// 
        public static bool IsAlphaPixelFormat(PixelFormat pixfmt) {
            return(pixfmt & PixelFormat.Alpha) != 0; 
        }
 
        /* 
         * Determine if the pixel format is an extended format,
         * i.e. supports 16-bit per channel 
         */
        /// 
        /// 
        ///     
        ///       Returns a value indicating whether the pixel format is extended.
        ///     
        ///  
        public static bool IsExtendedPixelFormat(PixelFormat pixfmt) {
            return(pixfmt & PixelFormat.Extended) != 0; 
        }

        /*
         * Determine if the pixel format is canonical format: 
         *   PixelFormat32bppARGB
         *   PixelFormat32bppPARGB 
         *   PixelFormat64bppARGB 
         *   PixelFormat64bppPARGB
         */ 
        /// 
        /// 
        ///    
        ///       Returns a value indicating whether the pixel format is canonical. 
        ///    
        ///  
        public static bool IsCanonicalPixelFormat(PixelFormat pixfmt) { 
            return(pixfmt & PixelFormat.Canonical) != 0;
        } 
    }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Drawing { 
    using System.Runtime.Serialization.Formatters; 
    using System.Threading;
    using System.Runtime.InteropServices; 
    using System.Runtime.Serialization;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System; 
    using System.Drawing.Design;
    using System.IO; 
    using System.Reflection; 
    using System.ComponentModel;
    using ArrayList = System.Collections.ArrayList; 
    using Microsoft.Win32;
    using System.Drawing.Imaging;
    using System.Drawing.Internal;
    using System.Security; 
    using System.Security.Permissions;
    using System.Globalization; 
 
    /**
     * Represent an image object (could be bitmap or vector) 
     */
    /// 
    /// 
    ///    An abstract base class that provides 
    ///    functionality for 'Bitmap', 'Icon', 'Cursor', and 'Metafile' descended classes.
    ///  
    [ 
    TypeConverterAttribute(typeof(ImageConverter)),
    Editor("System.Drawing.Design.ImageEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor)), 
    ImmutableObject(true)
    ]
    [Serializable]
    [ComVisible(true)] 
    public abstract class Image : MarshalByRefObject, ISerializable, ICloneable, IDisposable {
 
#if FINALIZATION_WATCH 
        private string allocationSite = Graphics.GetAllocationStack();
#endif 


        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public delegate bool GetThumbnailImageAbort(); 

        /* 
         * Handle to native image object
         */
        internal IntPtr nativeImage;
 
        // used to work around lack of animated gif encoder... rarely set...
        // 
        byte[] rawData; 

        //userData : so that user can use TAGS with IMAGES.. 
        private object userData;

        /**
         * Constructor can't be invoked directly 
         */
        internal Image() { 
        } 

        /** 
         * Constructor used in deserialization
         */
        internal Image(SerializationInfo info, StreamingContext context) {
            SerializationInfoEnumerator sie = info.GetEnumerator(); 
            if (sie == null) {
                return; 
            } 
            for (; sie.MoveNext();) {
                if (String.Equals(sie.Name, "Data", StringComparison.OrdinalIgnoreCase)) 
                {
                    try {
                        byte[] dat = (byte[])sie.Value;
                        if (dat != null) { 
                            InitializeFromStream(new MemoryStream(dat));
                        } 
 
                    }
                    catch (ExternalException e) { 
                        Debug.Fail("failure: " + e.ToString());
                    }
                    catch (ArgumentException e) {
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                    catch (OutOfMemoryException e) { 
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                    catch (InvalidOperationException e) { 
                        Debug.Fail("failure: " + e.ToString());
                    }
                    catch (NotImplementedException e) {
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                    catch (FileNotFoundException e) { 
                        Debug.Fail("failure: " + e.ToString()); 
                    }
                } 
            }
        }

        ///  
        [
        Localizable(false), 
        Bindable(true), 
        DefaultValue(null),
        TypeConverter(typeof(StringConverter)) 
        ]
        public object Tag {
            get {
                return userData; 
            }
            set { 
                userData = value; 
            }
        } 

        /**
        * Create an image object from a URL
        */ 
        /// 
        ///  
        ///    Creates an  from the specified file. 
        /// 
        // [Obsolete("Use Image.FromFile(string, useEmbeddedColorManagement)")] 
        public static Image FromFile(String filename) {
            return Image.FromFile(filename, false);
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static Image FromFile(String filename, 
                                     bool useEmbeddedColorManagement) {

            // SECREVIEW : The File.Exists() below will do the demand for the FileIOPermission
            //             for us. So, we do not need an additional demand anymore. 
            //
            if (!File.Exists(filename)) { 
                // I have to do this so I can give a meaningful 
                // error back to the user. File.Exists() cal fail because of either
                // a failure to demand security or because the file does not exist. 
                // Always telling the user that the file does not exist is not a good
                // choice. So, we demand the permission again. This means that we are
                // going to demand the permission twice for the failure case, but that's
                // better than always demanding the permission twice. 
                //
                IntSecurity.DemandReadFileIO(filename); 
 
                throw new FileNotFoundException(filename);
            } 

            //GDI+ will read this file multiple times.  Get the fully qualified path
            //so if our app changes default directory we won't get an error
            // SECREVIEW : If path does exist, the caller must have FileIOPermissionAccess.PathDiscovery permission. 
            //             Note that unlike most members of the Path class, this method accesses the file system.
            // 
            filename = Path.GetFullPath(filename); 

            IntPtr image = IntPtr.Zero; 
            int status;

            if (useEmbeddedColorManagement) {
                status = SafeNativeMethods.Gdip.GdipLoadImageFromFileICM(filename, out image); 
            }
            else { 
                status = SafeNativeMethods.Gdip.GdipLoadImageFromFile(filename, out image); 
            }
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, image)); 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, image)); 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 

            Image img = CreateImageObject(image);

            EnsureSave(img, filename, null); 

            return img; 
        } 

 
        /**
         * Create an image object from a data stream
         */
        ///  
        /// 
        ///    Creates an  from the specified data 
        ///    stream. 
        /// 
        // [Obsolete("Use Image.FromStream(stream, useEmbeddedColorManagement)")] 
        public static Image FromStream(Stream stream) {
            return Image.FromStream(stream, false);
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static Image FromStream(Stream stream, 
                                       bool useEmbeddedColorManagement)
        {
            return FromStream( stream, useEmbeddedColorManagement, true );
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public static Image FromStream(Stream stream, bool useEmbeddedColorManagement, bool validateImageData ) {
            if( !validateImageData ) {
                IntSecurity.UnmanagedCode.Demand();
            } 

            if (stream == null){ 
                throw new ArgumentException(SR.GetString(SR.InvalidArgument, "stream", "null")); 
            }
 
            IntPtr image = IntPtr.Zero;
            int status;

            if (useEmbeddedColorManagement) { 
                status = SafeNativeMethods.Gdip.GdipLoadImageFromStreamICM(new GPStream(stream), out image);
            } 
            else { 
                status = SafeNativeMethods.Gdip.GdipLoadImageFromStream(new GPStream(stream), out image);
            } 

            if (status != SafeNativeMethods.Gdip.Ok){
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 

            if( validateImageData ) { 
                status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, image)); 

                if (status != SafeNativeMethods.Gdip.Ok) { 
                    SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, image));
                    throw SafeNativeMethods.Gdip.StatusException(status);
                }
            } 

            Image img = CreateImageObject(image); 
 
            EnsureSave(img, null, stream);
 
            return img;
        }

        // Used for serialization 
        private void InitializeFromStream(Stream stream) {
            IntPtr image = IntPtr.Zero; 
 
            int status = SafeNativeMethods.Gdip.GdipLoadImageFromStream(new GPStream(stream), out image);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, image)); 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, image)); 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 

            this.nativeImage = image;

            int type = -1; 

            status = SafeNativeMethods.Gdip.GdipGetImageType(new HandleRef(this, nativeImage), out type); 
 
            EnsureSave(this, null, stream);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        }
 
        internal Image(IntPtr nativeImage) {
            SetNativeImage(nativeImage); 
        } 

        /** 
         * Make a copy of the image object
         */
        /// 
        ///  
        ///    Creates an exact copy of this .
        ///  
        public object Clone() { 
            IntPtr cloneImage = IntPtr.Zero;
 
            int status = SafeNativeMethods.Gdip.GdipCloneImage(new HandleRef(this, nativeImage), out cloneImage);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 

            status = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, cloneImage)); 
 
            if (status != SafeNativeMethods.Gdip.Ok) {
                SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, cloneImage)); 
                throw SafeNativeMethods.Gdip.StatusException(status);
            }

            return CreateImageObject(cloneImage); 
        }
 
        /** 
         * Dispose of resources associated with the Image object
         */ 
        /// 
        /// 
        ///    Cleans up Windows resources for this
        /// . 
        /// 
        public void Dispose() { 
            Dispose(true); 
            GC.SuppressFinalize(this);
        } 

        /// 
        protected virtual void Dispose(bool disposing) {
#if FINALIZATION_WATCH 
            if (!disposing && nativeImage != IntPtr.Zero)
                Debug.WriteLine("**********************\nDisposed through finalization:\n" + allocationSite); 
#endif 
            if (nativeImage != IntPtr.Zero) {
                try{ 
#if DEBUG
                    int status =
#endif
                    SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(this, nativeImage)); 
#if DEBUG
                    Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture)); 
#endif 
                }
                catch( Exception ex ){ 
                    if( ClientUtils.IsSecurityOrCriticalException( ex ) ) {
                        throw;
                    }
 
                    Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() );
                } 
                finally{ 
                    nativeImage = IntPtr.Zero;
                } 
            }
        }

        ///  
        /// 
        ///    Cleans up Windows resources for this 
        /// . 
        /// 
        ~Image() { 
            Dispose(false);
        }

        internal static void EnsureSave(Image image, string filename, Stream dataStream) { 

            if (image.RawFormat.Equals(ImageFormat.Gif)) { 
                bool animatedGif = false; 

                Guid[] dimensions = image.FrameDimensionsList; 
                foreach (Guid guid in dimensions) {
                    FrameDimension dimension = new FrameDimension(guid);
                    if (dimension.Equals(FrameDimension.Time)) {
                        animatedGif = image.GetFrameCount(FrameDimension.Time) > 1; 
                        break;
                    } 
                } 

 
                if (animatedGif) {
                    try {
                        Stream created = null;
                        long lastPos = 0; 
                        if (dataStream != null) {
                            lastPos = dataStream.Position; 
                            dataStream.Position = 0; 
                        }
 
                        try {
                            if (dataStream == null) {
                                created = dataStream = File.OpenRead(filename);
                            } 

                            image.rawData = new byte[(int)dataStream.Length]; 
                            dataStream.Read(image.rawData, 0, (int)dataStream.Length); 
                        }
                        finally { 
                            if (created != null) {
                                created.Close();
                            }
                            else { 
                                dataStream.Position = lastPos;
                            } 
                        } 
                    }
                    // possible exceptions for reading the filename 
                    catch (UnauthorizedAccessException) {
                    }
                    catch (DirectoryNotFoundException) {
                    } 
                    catch (IOException) {
                    } 
                    // possible exceptions for setting/getting the position inside dataStream 
                    catch (NotSupportedException) {
                    } 
                    catch (ObjectDisposedException) {
                    }
                    // possible exception when reading stuff into dataStream
                    catch (ArgumentException) { 
                    }
                } 
            } 
        }
 
        private enum ImageTypeEnum  {
            Bitmap = 1,
            Metafile = 2,
        } 

        /* FxCop rule 'AvoidBuildingNonCallableCode' - Left here in case it is needed in the future. 
        private ImageTypeEnum ImageType 
        {
            get { 
                int type = -1;

                int status = SafeNativeMethods.Gdip.GdipGetImageType(new HandleRef(this, nativeImage), out type);
 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
 
                return(ImageTypeEnum) type;
            } 
        }
        */

        internal static Image CreateImageObject(IntPtr nativeImage) { 
            Image image;
 
            int type = -1; 

            int status = SafeNativeMethods.Gdip.GdipGetImageType(new HandleRef(null, nativeImage), out type); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            switch ((ImageTypeEnum)type) {
                case ImageTypeEnum.Bitmap: 
                    image = Bitmap.FromGDIplus(nativeImage); 
                    break;
 
                case ImageTypeEnum.Metafile:
                    image = Metafile.FromGDIplus(nativeImage);
                    break;
 
                default:
                    throw new ArgumentException(SR.GetString(SR.InvalidImage)); 
            } 

            return image; 
        }

        /// 
        ///  
        ///     ISerializable private implementation
        ///  
        ///  
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
        [SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly")] 
        void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) {
            using( MemoryStream stream = new MemoryStream() ) {
                Save( stream );
                si.AddValue("Data", stream.ToArray(), typeof(byte[])); 
            }
        } 
 
        /// 
        ///  
        ///    Returns information about the codecs used
        ///    for this .
        /// 
        public EncoderParameters GetEncoderParameterList(Guid encoder) { 
            EncoderParameters p;
            int size; 
 
            int status = SafeNativeMethods.Gdip.GdipGetEncoderParameterListSize(new HandleRef(this, nativeImage),
                                                                 ref encoder, 
                                                                 out size);
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            if (size <= 0)
                return null; 
 
            IntPtr buffer = Marshal.AllocHGlobal(size);
 
            status = SafeNativeMethods.Gdip.GdipGetEncoderParameterList(new HandleRef(this, nativeImage),
                                                         ref encoder,
                                                         size,
                                                         buffer); 

            try{ 
                if (status != SafeNativeMethods.Gdip.Ok) { 
                    throw SafeNativeMethods.Gdip.StatusException(status);
                } 

                p = EncoderParameters.ConvertFromMemory(buffer);
            }
            finally{ 
                Marshal.FreeHGlobal(buffer);
            } 
 
            return p;
        } 

        /// 
        /// 
        ///    Saves this  to the specified file. 
        /// 
        public void Save(string filename) { 
            Save( filename, RawFormat ); 
        }
 
        /// 
        /// 
        ///    Saves this  to the specified file in the
        ///    specified format. 
        /// 
        public void Save(string filename, ImageFormat format) { 
            if (format == null) 
                throw new ArgumentNullException("format");
 
            ImageCodecInfo codec = format.FindEncoder();

            if (codec == null)
                codec = ImageFormat.Png.FindEncoder(); 

            Save(filename, codec, null); 
        } 

        ///  
        /// 
        ///    
        ///       Saves this  to the specified file in the specified format
        ///       and with the specified encoder parameters. 
        ///    
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Save(string filename, ImageCodecInfo encoder, EncoderParameters encoderParams) {
            if (filename == null) 
                throw new ArgumentNullException("filename");
            if (encoder == null)
                throw new ArgumentNullException("encoder");
 
            IntSecurity.DemandWriteFileIO(filename);
 
            IntPtr encoderParamsMemory = IntPtr.Zero; 

            if (encoderParams != null) { 
                rawData = null;
                encoderParamsMemory = encoderParams.ConvertToMemory();
            }
            int status = SafeNativeMethods.Gdip.Ok; 

            try { 
                Guid g = encoder.Clsid; 
                bool saved = false;
 
                if (rawData != null) {
                    ImageCodecInfo rawEncoder = RawFormat.FindEncoder();
                    if (rawEncoder != null && rawEncoder.Clsid == g) {
                        using (FileStream fs = File.OpenWrite(filename)) { 
                            fs.Write(rawData, 0, rawData.Length);
                            saved = true; 
                        } 
                    }
                } 

                if (!saved) {
                    status = SafeNativeMethods.Gdip.GdipSaveImageToFile(new HandleRef(this, nativeImage),
                                                             filename, 
                                                             ref g,
                                                             new HandleRef(encoderParams, encoderParamsMemory)); 
                } 
            }
            finally { 
                if (encoderParamsMemory != IntPtr.Zero) {
                    Marshal.FreeHGlobal(encoderParamsMemory);
                }
            } 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status); 
            }
        } 

        internal void Save(MemoryStream stream) {
            // Jpeg loses data, so we don't want to use it to serialize...
            // 
            ImageFormat dest = RawFormat;
            if (dest == ImageFormat.Jpeg) { 
                dest = ImageFormat.Png; 
            }
            ImageCodecInfo codec = dest.FindEncoder(); 

            // If we don't find an Encoder (for things like Icon), we
            // just switch back to PNG...
            // 
            if (codec == null) {
                codec = ImageFormat.Png.FindEncoder(); 
            } 
            Save(stream, codec, null);
        } 

        /// 
        /// 
        ///     
        ///       Saves this  to the specified stream in the specified
        ///       format. 
        ///     
        /// 
        public void Save(Stream stream, ImageFormat format) { 
            if (format == null)
                throw new ArgumentNullException("format");

            ImageCodecInfo codec = format.FindEncoder(); 
            Save(stream, codec, null);
        } 
 
        /// 
        ///  
        ///    
        ///       Saves this  to the specified stream in the specified
        ///       format.
        ///     
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) { 
            if (stream == null){
                throw new ArgumentNullException("stream"); 
            }
            if (encoder == null) {
                throw new ArgumentNullException("encoder");
            } 

            IntPtr encoderParamsMemory = IntPtr.Zero; 
 
            if (encoderParams != null) {
                rawData = null; 
                encoderParamsMemory = encoderParams.ConvertToMemory();
            }

            int status = SafeNativeMethods.Gdip.Ok; 

            try { 
                Guid g = encoder.Clsid; 
                bool saved = false;
 
                if (rawData != null) {
                    ImageCodecInfo rawEncoder = RawFormat.FindEncoder();
                    if (rawEncoder != null && rawEncoder.Clsid == g) {
                        stream.Write(rawData, 0, rawData.Length); 
                        saved = true;
                    } 
                } 

                if (!saved) { 
                    status = SafeNativeMethods.Gdip.GdipSaveImageToStream(new HandleRef(this, nativeImage),
                                                                     new UnsafeNativeMethods.ComStreamFromDataStream(stream),
                                                                     ref g,
                                                                     new HandleRef(encoderParams, encoderParamsMemory)); 
                }
            } 
            finally { 
                if (encoderParamsMemory != IntPtr.Zero) {
                    Marshal.FreeHGlobal(encoderParamsMemory); 
                }
            }

            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        } 

        ///  
        /// 
        ///    
        ///       Adds an  to this
        ///    . 
        ///    
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void SaveAdd(EncoderParameters encoderParams) {
            IntPtr encoder = IntPtr.Zero; 
            if (encoderParams != null) {
                encoder = encoderParams.ConvertToMemory();
            }
 
            rawData = null;
            int status = SafeNativeMethods.Gdip.GdipSaveAdd(new HandleRef(this, nativeImage), new HandleRef(encoderParams, encoder)); 
 
            if (encoder != IntPtr.Zero) {
                Marshal.FreeHGlobal(encoder); 
            }
            if (status != SafeNativeMethods.Gdip.Ok) {
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Adds an  to the
        ///       specified .
        ///    
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public void SaveAdd(Image image, EncoderParameters encoderParams) { 
            IntPtr encoder = IntPtr.Zero; 

            if (image == null) { 
                throw new ArgumentNullException("image");
            }
            if (encoderParams != null) {
                encoder = encoderParams.ConvertToMemory(); 
            }
 
            rawData = null; 
            int status = SafeNativeMethods.Gdip.GdipSaveAddImage(new HandleRef(this, nativeImage), new HandleRef(image, image.nativeImage), new HandleRef(encoderParams, encoder));
 
            if (encoder != IntPtr.Zero){
                Marshal.FreeHGlobal(encoder);
            }
            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        } 

        /** 
         * Return; image size information
         */
        private SizeF _GetPhysicalDimension() {
            float width; 
            float height;
 
            int status = SafeNativeMethods.Gdip.GdipGetImageDimension(new HandleRef(this, nativeImage), out width, out height); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);

            return new SizeF(width, height);
        } 

        ///  
        ///  
        ///    
        ///       Gets the width and height of this 
        ///    .
        ///    
        /// 
        public SizeF PhysicalDimension { 
            get { return _GetPhysicalDimension();}
        } 
 
        /// 
        ///  
        ///    
        ///       Gets the width and height of this .
        ///    
        ///  
        public Size Size {
            get { 
                return new Size(Width, Height); 
            }
        } 

        /// 
        /// 
        ///    Gets the width of this . 
        /// 
        [ 
        DefaultValue(false), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public int Width {
            get {
                int width; 

                int status = SafeNativeMethods.Gdip.GdipGetImageWidth(new HandleRef(this, nativeImage), out width); 
 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return width;
            }
        } 

        ///  
        ///  
        ///    Gets the height of this .
        ///  
        [
        DefaultValue(false),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public int Height { 
            get { 
                int height;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageHeight(new HandleRef(this, nativeImage), out height);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return height; 
            } 
        }
 
        /// 
        /// 
        ///    Gets the horizontal resolution, in
        ///    pixels-per-inch, of this . 
        /// 
        public float HorizontalResolution { 
            get { 
                float horzRes;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageHorizontalResolution(new HandleRef(this, nativeImage), out horzRes);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return horzRes; 
            } 
        }
 
        /// 
        /// 
        ///    Gets the vertical resolution, in
        ///    pixels-per-inch, of this . 
        /// 
        public float VerticalResolution { 
            get { 
                float vertRes;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageVerticalResolution(new HandleRef(this, nativeImage), out vertRes);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return vertRes; 
            } 
        }
 
        /// 
        /// 
        ///    Gets attribute flags for this .
        ///  
        [Browsable(false)]
        public int Flags { 
            get { 
                int flags;
 
                int status = SafeNativeMethods.Gdip.GdipGetImageFlags(new HandleRef(this, nativeImage), out flags);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return flags; 
            } 
        }
 
        /// 
        /// 
        ///    Gets the format of this .
        ///  
        public ImageFormat RawFormat {
            get { 
                Guid guid = new Guid(); 

                int status = SafeNativeMethods.Gdip.GdipGetImageRawFormat(new HandleRef(this, nativeImage), ref guid); 

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
 

                return new ImageFormat(guid); 
            } 
        }
 
        /// 
        /// 
        ///    Gets the pixel format for this .
        ///  
        public PixelFormat PixelFormat {
            get { 
                int format; 

                int status = SafeNativeMethods.Gdip.GdipGetImagePixelFormat(new HandleRef(this, nativeImage), out format); 

                if (status != SafeNativeMethods.Gdip.Ok)
                    return PixelFormat.Undefined;
                else 
                    return(PixelFormat)format;
            } 
        } 

        ///  
        /// 
        ///    Gets a bounding rectangle in
        ///    the specified units for this .
        ///  
        [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
        public RectangleF GetBounds(ref GraphicsUnit pageUnit) { 
            GPRECTF gprectf = new GPRECTF(); 

            int status = SafeNativeMethods.Gdip.GdipGetImageBounds(new HandleRef(this, nativeImage), ref gprectf, out pageUnit); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return gprectf.ToRectangleF();
        } 
 
        private ColorPalette _GetColorPalette() {
            int size = -1; 

            int status = SafeNativeMethods.Gdip.GdipGetImagePaletteSize(new HandleRef(this, nativeImage), out size);
            // "size" is total byte size:
            // sizeof(ColorPalette) + (pal->Count-1)*sizeof(ARGB) 

            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status); 
            }
 
            ColorPalette palette = new ColorPalette(size);

            // Memory layout is:
            //    UINT Flags 
            //    UINT Count
            //    ARGB Entries[size] 
 
            IntPtr memory = Marshal.AllocHGlobal(size);
 
            status = SafeNativeMethods.Gdip.GdipGetImagePalette(new HandleRef(this, nativeImage), memory, size);

            try {
                if (status != SafeNativeMethods.Gdip.Ok) { 
                    throw SafeNativeMethods.Gdip.StatusException(status);
                } 
 
                palette.ConvertFromMemory(memory);
            } 
            finally {
                Marshal.FreeHGlobal(memory);
            }
 
            return palette;
        } 
 
        private void _SetColorPalette(ColorPalette palette) {
            IntPtr memory = palette.ConvertToMemory(); 

            int status = SafeNativeMethods.Gdip.GdipSetImagePalette(new HandleRef(this, nativeImage), memory);

            if (memory != IntPtr.Zero) { 
                Marshal.FreeHGlobal(memory);
            } 
            if (status != SafeNativeMethods.Gdip.Ok) { 
                throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        }

        /// 
        ///  
        ///    Gets or sets the color
        ///    palette used for this . 
        ///  
        [Browsable(false)]
        public ColorPalette Palette 
        {
            get {
                return _GetColorPalette();
            } 
            set {
                _SetColorPalette(value); 
            } 
        }
 
        // Thumbnail support

        /// 
        ///  
        ///    Returns the thumbnail for this .
        ///  
        public Image GetThumbnailImage(int thumbWidth, int thumbHeight, 
                                       GetThumbnailImageAbort callback, IntPtr callbackData) {
            IntPtr thumbImage = IntPtr.Zero; 

            int status = SafeNativeMethods.Gdip.GdipGetImageThumbnail(new HandleRef(this, nativeImage), thumbWidth, thumbHeight, out thumbImage,
                                                       callback, callbackData);
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return CreateImageObject(thumbImage); 
        }
 
        // Multi-frame support

        /// 
        ///  
        ///    
        ///       Gets an array of GUIDs that represent the 
        ///       dimensions of frames within this . 
        ///    
        ///  
        [Browsable(false)]
        public Guid[] FrameDimensionsList {
            [SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")]
            get { 
                int count;
 
                int status = SafeNativeMethods.Gdip.GdipImageGetFrameDimensionsCount(new HandleRef(this, nativeImage), out count); 

                if (status != SafeNativeMethods.Gdip.Ok) { 
                    throw SafeNativeMethods.Gdip.StatusException(status);
                }

                Debug.Assert(count >= 0, "FrameDimensionsList returns bad count"); 
                if (count <= 0) {
                    return new Guid[0]; 
                } 

                int size = (int) Marshal.SizeOf(typeof(Guid)); 

                IntPtr buffer = Marshal.AllocHGlobal(size*count);
                if (buffer == IntPtr.Zero) {
                    throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory); 
                }
 
                status = SafeNativeMethods.Gdip.GdipImageGetFrameDimensionsList(new HandleRef(this, nativeImage), buffer, count); 

                if (status != SafeNativeMethods.Gdip.Ok) { 
                    Marshal.FreeHGlobal(buffer);
                    throw SafeNativeMethods.Gdip.StatusException(status);
                }
 
                Guid[] guids = new Guid[count];
 
                try { 
                    for (int i=0; i
        /// 
        ///     
        ///       Returns the number of frames of the given
        ///       dimension. 
        ///     
        /// 
        public int GetFrameCount(FrameDimension dimension) { 
            int[] count = new int[] { 0};

            Guid dimensionID = dimension.Guid;
            int status = SafeNativeMethods.Gdip.GdipImageGetFrameCount(new HandleRef(this, nativeImage), ref dimensionID, count); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            return count[0]; 
        }

        /// 
        ///  
        ///    
        ///       Selects the frame specified by the given 
        ///       dimension and index. 
        ///    
        ///  
        public int SelectActiveFrame(FrameDimension dimension, int frameIndex) {
            int[] count = new int[] { 0};

            Guid dimensionID = dimension.Guid; 
            int status = SafeNativeMethods.Gdip.GdipImageSelectActiveFrame(new HandleRef(this, nativeImage), ref dimensionID, frameIndex);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return count[0];
        }

        ///  
        /// 
        ///     
        ///     
        /// 
        public void RotateFlip(RotateFlipType rotateFlipType) { 

            int status = SafeNativeMethods.Gdip.GdipImageRotateFlip(new HandleRef(this, nativeImage), (int) rotateFlipType);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
        } 

        ///  
        /// 
        ///    Gets an array of the property IDs stored in
        ///    this .
        ///  
        [Browsable(false)]
        public int[] PropertyIdList 
        { 
            get {
                int count; 

                int status = SafeNativeMethods.Gdip.GdipGetPropertyCount(new HandleRef(this, nativeImage), out count);

                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
 
                int[] propid = new int[count]; 

                //if we have a 0 count, just return our empty array 
                if (count == 0)
                    return propid;

                status = SafeNativeMethods.Gdip.GdipGetPropertyIdList(new HandleRef(this, nativeImage), count, propid); 

                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return propid; 
            }
        }

        ///  
        /// 
        ///    Gets the specified property item from this 
        /// . 
        /// 
        public PropertyItem GetPropertyItem(int propid) { 
            PropertyItem propitem;
            int size;

            int status = SafeNativeMethods.Gdip.GdipGetPropertyItemSize(new HandleRef(this, nativeImage), propid, out size); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            if (size == 0) 
                return null;

            IntPtr propdata = Marshal.AllocHGlobal(size);
 
            if (propdata == IntPtr.Zero)
                throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory); 
 
            status = SafeNativeMethods.Gdip.GdipGetPropertyItem(new HandleRef(this, nativeImage), propid, size, propdata);
 
            try {
                if (status != SafeNativeMethods.Gdip.Ok) {
                    throw SafeNativeMethods.Gdip.StatusException(status);
                } 

                propitem = PropertyItemInternal.ConvertFromMemory(propdata, 1)[0]; 
            } 
            finally {
                Marshal.FreeHGlobal(propdata); 
            }

            return propitem;
        } 

        ///  
        ///  
        ///    Removes the specified property item from
        ///    this . 
        /// 
        public void RemovePropertyItem(int propid) {
            int status = SafeNativeMethods.Gdip.GdipRemovePropertyItem(new HandleRef(this, nativeImage), propid);
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Sets the specified property item to the
        ///       specified value.
        ///     
        /// 
        public void SetPropertyItem(PropertyItem propitem) { 
            PropertyItemInternal propItemInternal = PropertyItemInternal.ConvertFromPropertyItem(propitem); 

            using (propItemInternal) { 
                int status = SafeNativeMethods.Gdip.GdipSetPropertyItem(new HandleRef(this, nativeImage), propItemInternal);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } 
        }
 
        ///  
        /// 
        ///    Gets an array of  objects that describe this . 
        /// 
        [Browsable(false)]
        public PropertyItem[] PropertyItems
        { 
            get {
                int size; 
                int count; 

                int status = SafeNativeMethods.Gdip.GdipGetPropertyCount(new HandleRef(this, nativeImage), out count); 

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
 
                status = SafeNativeMethods.Gdip.GdipGetPropertySize(new HandleRef(this, nativeImage), out size, ref count);
 
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
 
                if (size == 0 || count == 0)
                    return new PropertyItem[0];

                IntPtr propdata = Marshal.AllocHGlobal(size); 

                status = SafeNativeMethods.Gdip.GdipGetAllPropertyItems(new HandleRef(this, nativeImage), size, count, propdata); 
 
                PropertyItem[] props = null;
 
                try {
                    if (status != SafeNativeMethods.Gdip.Ok) {
                        throw SafeNativeMethods.Gdip.StatusException(status);
                    } 

                    props = PropertyItemInternal.ConvertFromMemory(propdata, count); 
                } 
                finally {
                    Marshal.FreeHGlobal(propdata); 
                }

                return props;
            } 
        }
 
        internal void SetNativeImage(IntPtr handle) { 
            if (handle == IntPtr.Zero)
                throw new ArgumentException(SR.GetString(SR.NativeHandle0), "handle"); 

            nativeImage = handle;
        }
 
        // !! Ambiguous to offer constructor for 'FromHbitmap'
        ///  
        ///  
        ///    Creates a  from a Windows handle.
        ///  
        public static Bitmap FromHbitmap(IntPtr hbitmap) {
            IntSecurity.ObjectFromWin32Handle.Demand();

            return FromHbitmap(hbitmap, IntPtr.Zero); 
        }
 
        ///  
        /// 
        ///     
        ///       Creates a  from the specified Windows
        ///       handle with the specified color palette.
        ///    
        ///  
        public static Bitmap FromHbitmap(IntPtr hbitmap, IntPtr hpalette) {
            IntSecurity.ObjectFromWin32Handle.Demand(); 
 
            IntPtr bitmap = IntPtr.Zero;
            int status = SafeNativeMethods.Gdip.GdipCreateBitmapFromHBITMAP(new HandleRef(null, hbitmap), new HandleRef(null, hpalette), out bitmap); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return Bitmap.FromGDIplus(bitmap);
        } 
 
        /*
         * Return the pixel size for the specified format (in bits) 
         */
        /// 
        /// 
        ///    Returns the size of the specified pixel 
        ///    format.
        ///  
        public static int GetPixelFormatSize(PixelFormat pixfmt) { 
            return((int)pixfmt >> 8) & 0xFF;
        } 

        /*
         * Determine if the pixel format can have alpha channel
         */ 
        /// 
        ///  
        ///     
        ///       Returns a value indicating whether the
        ///       pixel format contains alpha information. 
        ///    
        /// 
        public static bool IsAlphaPixelFormat(PixelFormat pixfmt) {
            return(pixfmt & PixelFormat.Alpha) != 0; 
        }
 
        /* 
         * Determine if the pixel format is an extended format,
         * i.e. supports 16-bit per channel 
         */
        /// 
        /// 
        ///     
        ///       Returns a value indicating whether the pixel format is extended.
        ///     
        ///  
        public static bool IsExtendedPixelFormat(PixelFormat pixfmt) {
            return(pixfmt & PixelFormat.Extended) != 0; 
        }

        /*
         * Determine if the pixel format is canonical format: 
         *   PixelFormat32bppARGB
         *   PixelFormat32bppPARGB 
         *   PixelFormat64bppARGB 
         *   PixelFormat64bppPARGB
         */ 
        /// 
        /// 
        ///    
        ///       Returns a value indicating whether the pixel format is canonical. 
        ///    
        ///  
        public static bool IsCanonicalPixelFormat(PixelFormat pixfmt) { 
            return(pixfmt & PixelFormat.Canonical) != 0;
        } 
    }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK