BitmapFrameDecode.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media / Imaging / BitmapFrameDecode.cs / 1 / BitmapFrameDecode.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation
//
//  File: BitmapFrameDecode.cs 
//
//----------------------------------------------------------------------------- 
 
using System;
using System.Collections; 
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization; 
using System.Reflection;
using MS.Internal; 
using MS.Internal.PresentationCore; 
using System.Diagnostics;
using System.Windows.Media; 
using System.Globalization;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices; 
using System.Windows.Media.Animation;
using System.Windows.Media.Composition; 
using System.Windows.Media.Imaging; 
using MS.Win32.PresentationCore;
 
#pragma warning disable 1634, 1691 // Allow suppression of certain presharp messages

namespace System.Windows.Media.Imaging
{ 
    #region BitmapFrameDecode
 
    ///  
    /// BitmapFrameDecode abstract class
    ///  
    internal sealed class BitmapFrameDecode : BitmapFrame
    {

        #region Constructors 

        ///  
        /// Internal constructor -- Creates new frame using specified decoder 
        /// 
        internal BitmapFrameDecode( 
            int frameNumber,
            BitmapSourceSafeMILHandle sourceHandle,
            BitmapCreateOptions createOptions,
            BitmapCacheOption cacheOption, 
            BitmapDecoder decoder
            ) : base(true) 
        { 
            _bitmapInit.BeginInit();
            _frameNumber = frameNumber; 
            _isThumbnailCached = false;
            _isMetadataCached = false;
            _frameSource = sourceHandle;
 
            Debug.Assert(decoder != null);
            _decoder = decoder; 
            _syncObject = decoder.SyncObject; 
            _createOptions = createOptions;
            _cacheOption = cacheOption; 

            _bitmapInit.EndInit();

            if ((createOptions & BitmapCreateOptions.DelayCreation) != 0) 
            {
                DelayCreation = true; 
            } 
            else
            { 
                FinalizeCreation();
            }
        }
 
        /// 
        /// Internal constructor -- Creates frame from another frame 
        ///  
        /// 
        /// SecurityCritical: Accesses unmanaged resources (_wicSource) 
        /// SecurityTreatAsSafe: Inputs are verified and _wicSource and the get is Critical
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal BitmapFrameDecode( 
            int frameNumber,
            BitmapCreateOptions createOptions, 
            BitmapCacheOption cacheOption, 
            BitmapFrameDecode frameDecode
            ) : base(true) 
        {
            _bitmapInit.BeginInit();
            _frameNumber = frameNumber;
            WicSourceHandle = frameDecode.WicSourceHandle; 
            IsSourceCached = frameDecode.IsSourceCached;
            CreationCompleted = frameDecode.CreationCompleted; 
            _frameSource = frameDecode._frameSource; 
            _decoder = frameDecode.Decoder;
            _syncObject = _decoder.SyncObject; 
            _createOptions = createOptions;
            _cacheOption = cacheOption;

            _thumbnail = frameDecode._thumbnail; 
            _isThumbnailCached = frameDecode._isThumbnailCached;
            _metadata = frameDecode._metadata; 
            _isMetadataCached = frameDecode._isMetadataCached; 
            _readOnlycolorContexts = frameDecode._readOnlycolorContexts;
            _isColorContextCached = frameDecode._isColorContextCached; 

            _bitmapInit.EndInit();

            if ((createOptions & BitmapCreateOptions.DelayCreation) != 0) 
            {
                DelayCreation = true; 
            } 
            else if (!CreationCompleted)
            { 
                FinalizeCreation();
            }
            else
            { 
                UpdateCachedSettings();
            } 
        } 

        ///  
        /// Internal constructor -- Creates frame thats being downloaded
        /// 
        /// 
        /// SecurityCritical: Accesses unmanaged resources (_wicSource) 
        /// SecurityTreatAsSafe: Inputs are verified and _wicSource and the get is Critical
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal BitmapFrameDecode(
            int frameNumber, 
            BitmapCreateOptions createOptions,
            BitmapCacheOption cacheOption,
            LateBoundBitmapDecoder decoder
            ) : base(true) 
        {
            _bitmapInit.BeginInit(); 
            _frameNumber = frameNumber; 

            byte[] pixels = new byte[4]; 

            BitmapSource source = BitmapSource.Create(
                1,
                1, 
                96,
                96, 
                PixelFormats.Pbgra32, 
                null,
                pixels, 
                4
                );

            WicSourceHandle = source.WicSourceHandle; 

            Debug.Assert(decoder != null); 
            _decoder = decoder; 
            _createOptions = createOptions;
            _cacheOption = cacheOption; 
            _decoder.DownloadCompleted += new EventHandler(OnDownloadCompleted);
            _decoder.DownloadProgress += new EventHandler(OnDownloadProgress);
            _decoder.DownloadFailed += new EventHandler(OnDownloadFailed);
 
            _bitmapInit.EndInit();
        } 
 
        /// 
        /// Do not allow construction 
        /// 
        private BitmapFrameDecode() : base(true)
        {
        } 

        #endregion 
 
        #region IUriContext
 
        /// 
        /// Provides the base uri of the current context.
        /// 
        public override Uri BaseUri 
        {
            get 
            { 
                ReadPreamble();
                return _decoder._baseUri; 
            }
            set
            {
                WritePreamble(); 
                // Nothing to do here.
            } 
        } 

        #endregion 

        #region Public Properties

        ///  
        /// Accesses the Thumbnail property for this BitmapFrameDecode
        ///  
        public override BitmapSource Thumbnail 
        {
            get 
            {
                ReadPreamble();
                EnsureThumbnail();
                return _thumbnail; 
            }
        } 
 
        /// 
        /// Accesses the Metadata property for this BitmapFrameDecode 
        /// 
        public override ImageMetadata Metadata
        {
            get 
            {
                ReadPreamble(); 
                return InternalMetadata; 
            }
        } 

        /// 
        /// Accesses the Decoder property for this BitmapFrameDecode
        ///  
        public override BitmapDecoder Decoder
        { 
            get 
            {
                ReadPreamble(); 
                return _decoder;
            }
        }
 
        /// 
        /// If there is an embedded color profile, return it. 
        /// Otherwise, return null.  This method does NOT create a 
        /// color profile for bitmaps that don't already have one.
        ///  
        /// 
        /// Provides access to this encoders color profile
        /// 
        /// 
        /// 
        /// Critical - Access unmanaged code, codecs 
        /// TreatAsSafe - Getting Color Context data is OK 
        /// 
        public override ReadOnlyCollection ColorContexts 
        {
            [SecurityCritical, SecurityTreatAsSafe]
            get
            { 
                ReadPreamble();
                if (!_isColorContextCached && !IsDownloading) 
                { 
                    EnsureSource();
 
                    // Check if there is colorContext or not
                    lock (_syncObject)
                    {
                        unsafe 
                        {
                            uint uiCount = 0; 
 
                            int hr = UnsafeNativeMethods.WICBitmapFrameDecode.GetColorContexts(
                                _frameSource, 
                                0,
                                IntPtr.Zero,
                                out uiCount
                                ); 

                            if (hr != (int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION) 
                            { 
                                HRESULT.Check(hr);
                            } 
                            if (uiCount > 0)
                            {
                                List colorContextsList = new List((int)uiCount);
 
                                IntPtr *pcolorContextslocal = stackalloc IntPtr[(int)uiCount];
                                for (int i = 0; i < uiCount; i++) pcolorContextslocal[i] = IntPtr.Zero; 
 
                                SafeMILHandle[] colorContextHandles = new SafeMILHandle[uiCount];
 
                                using (FactoryMaker factoryMaker = new FactoryMaker())
                                {
                                    try
                                    { 
                                        for (int i = 0; i < uiCount; i++)
                                        { 
                                            Guid wicColorContextGuid = MILGuidData.IID_IWICColorContext; 

                                            HRESULT.Check(UnsafeNativeMethods.WICCodec.CreateColorContext(factoryMaker.ImagingFactoryPtr, out colorContextHandles[i])); 

                                            HRESULT.Check(UnsafeNativeMethods.MILUnknown.QueryInterface(colorContextHandles[i], ref wicColorContextGuid, out pcolorContextslocal[i]));
                                        }
 
                                    }
                                    finally 
                                    { 
                                        for (int i = 0; i < uiCount; i++)
                                        { 
                                            #pragma warning suppress 6031
                                            UnsafeNativeMethods.MILUnknown.Release(pcolorContextslocal[i]);
                                        }
                                    } 

                                    HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameDecode.GetColorContexts( 
                                        _frameSource, 
                                        uiCount,
                                        (IntPtr)pcolorContextslocal, 
                                        out uiCount
                                        ));
                                }
                                for (uint i = 0; i < uiCount; i++) 
                                {
                                    colorContextsList.Add(new ColorContext(colorContextHandles[i])); 
                                } 

                                _readOnlycolorContexts = new ReadOnlyCollection(colorContextsList); 

                            }
                        }
 
                        _isColorContextCached = true;
                    } 
 
                }
 
                return _readOnlycolorContexts;

            }
        } 

 
        ///  
        /// Returns if the BitmapFrame is downloading content
        ///  
        public override bool IsDownloading
        {
            get
            { 
                ReadPreamble();
                return Decoder.IsDownloading; 
            } 
        }
 
        #endregion

        #region Public Methods
 
        /// 
        /// Create an in-place bitmap metadata writer. 
        ///  
        public override InPlaceBitmapMetadataWriter CreateInPlaceBitmapMetadataWriter()
        { 
            ReadPreamble();

            if (_decoder != null)
            { 
                _decoder.CheckOriginalWritable();
            } 
 
            // Demand Site Of Origin on the URI before usage of metadata.
            CheckIfSiteOfOrigin(); 

            EnsureSource();

            return InPlaceBitmapMetadataWriter.CreateFromFrameDecode(_frameSource, _syncObject); 
        }
 
        #endregion 

        #region ToString 

        /// 
        /// Can serialze "this" to a string
        ///  
        internal override bool CanSerializeToString()
        { 
            ReadPreamble(); 

            return _decoder.CanConvertToString(); 
        }

        /// 
        /// Creates a string representation of this object based on the format string 
        /// and IFormatProvider passed in.
        /// If the provider is null, the CurrentCulture is used. 
        /// See the documentation for IFormattable for more information. 
        /// 
        ///  
        /// A string representation of this object.
        /// 
        internal override string ConvertToString(string format, IFormatProvider provider)
        { 
            ReadPreamble();
 
            if (_decoder != null) 
            {
                return _decoder.ToString(); 
            }

            return base.ConvertToString(format, provider);
        } 

        #endregion 
 
        #region Freezable
 
        /// 
        /// Implementation of Freezable.CreateInstanceCore.
        /// 
        /// The new Freezable. 
        protected override Freezable CreateInstanceCore()
        { 
            return new BitmapFrameDecode(); 
        }
 
        /// 
        /// Copy the fields not covered by DPs.  This is used by
        /// CloneCore(), CloneCurrentValueCore(), GetAsFrozenCore() and
        /// GetCurrentValueAsFrozenCore(). 
        /// 
        ///  
        /// Critical - access critical resources (_metadata) 
        /// TreatAsSafe - All inputs verified
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void CopyCommon(BitmapFrameDecode sourceBitmapFrameDecode)
        {
            _bitmapInit.BeginInit(); 
            _frameNumber = sourceBitmapFrameDecode._frameNumber;
            _isThumbnailCached = sourceBitmapFrameDecode._isThumbnailCached; 
            _isMetadataCached = sourceBitmapFrameDecode._isMetadataCached; 
            _isColorContextCached = sourceBitmapFrameDecode._isColorContextCached;
            _frameSource = sourceBitmapFrameDecode._frameSource; 
            _thumbnail = sourceBitmapFrameDecode._thumbnail;
            _metadata = sourceBitmapFrameDecode.InternalMetadata;
            _readOnlycolorContexts = sourceBitmapFrameDecode._readOnlycolorContexts;
            _decoder = sourceBitmapFrameDecode._decoder; 
            _syncObject = _decoder.SyncObject;
            _createOptions = sourceBitmapFrameDecode._createOptions; 
            _cacheOption = sourceBitmapFrameDecode._cacheOption; 
            _bitmapInit.EndInit();
        } 

        /// 
        /// Implementation of Freezable.CloneCore.
        ///  
        protected override void CloneCore(Freezable sourceFreezable)
        { 
            BitmapFrameDecode sourceBitmapFrameDecode = (BitmapFrameDecode)sourceFreezable; 
            base.CloneCore(sourceFreezable);
 
            CopyCommon(sourceBitmapFrameDecode);
        }

        ///  
        /// Implementation of Freezable.CloneCurrentValueCore.
        ///  
        protected override void CloneCurrentValueCore(Freezable sourceFreezable) 
        {
            BitmapFrameDecode sourceBitmapFrameDecode = (BitmapFrameDecode)sourceFreezable; 
            base.CloneCurrentValueCore(sourceFreezable);

            CopyCommon(sourceBitmapFrameDecode);
        } 

 
        ///  
        /// Implementation of Freezable.GetAsFrozenCore.
        ///  
        protected override void GetAsFrozenCore(Freezable sourceFreezable)
        {
            BitmapFrameDecode sourceBitmapFrameDecode = (BitmapFrameDecode)sourceFreezable;
            base.GetAsFrozenCore(sourceFreezable); 

            CopyCommon(sourceBitmapFrameDecode); 
        } 

 
        /// 
        /// Implementation of Freezable.GetCurrentValueAsFrozenCore.
        /// 
        protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable) 
        {
            BitmapFrameDecode sourceBitmapFrameDecode = (BitmapFrameDecode)sourceFreezable; 
            base.GetCurrentValueAsFrozenCore(sourceFreezable); 

            CopyCommon(sourceBitmapFrameDecode); 
        }

        #endregion
 
        #region Internal Properties / Methods
 
        ///  
        /// Updates the internal decoder -- usually happens with a LateBoundBitmapDecoder
        ///  
        /// 
        /// Critical - access critical resources
        /// TreatAsSafe - All inputs verified
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal void UpdateDecoder(BitmapDecoder decoder) 
        { 
            Debug.Assert(_decoder != null);
            _decoder = decoder; 
            _syncObject = decoder.SyncObject;
            WicSourceHandle = null;
            _needsUpdate = true;
            FinalizeCreation(); 

            // Trigger a update of the UCE resource 
            RegisterForAsyncUpdateResource(); 
        }
 

        /// 
        /// Create the unmanaged resources
        ///  
        /// 
        /// Critical - access critical resources 
        /// TreatAsSafe - All inputs verified 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override void FinalizeCreation()
        {
            EnsureSource();
 
            // Set the WicSourceHandle and Update the cached settings so that we
            // can query the source for information such as the palette which we need 
            // to determine if we need to format convert or not. 
            WicSourceHandle = _frameSource;
            UpdateCachedSettings(); 

            lock (_syncObject)
            {
                WicSourceHandle = CreateCachedBitmap(this, _frameSource, _createOptions, _cacheOption, Palette); 
            }
 
            IsSourceCached = (_cacheOption != BitmapCacheOption.None); 
            CreationCompleted = true;
            UpdateCachedSettings(); 
            EnsureThumbnail();
        }

        #endregion 

        #region Private Methods 
 
        /// Fired when the decoder download has completed
        private void OnDownloadCompleted(object sender, EventArgs e) 
        {
            FireChanged();
            _downloadEvent.InvokeEvents(this, null);
        } 

        /// Called when download progress is made 
        private void OnDownloadProgress(object sender, DownloadProgressEventArgs e) 
        {
            _progressEvent.InvokeEvents(this, e); 
        }

        /// Called when download fails
        private void OnDownloadFailed(object sender, ExceptionEventArgs e) 
        {
            _failedEvent.InvokeEvents(this, e); 
        } 

        ///  
        /// Ensure that the thumbnail is created/cached
        /// 
        /// 
        /// Critical - Access unmanaged code, codecs 
        /// TreatAsSafe - Getting thumbnail data is OK
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        private void EnsureThumbnail()
        { 
            if (_isThumbnailCached || IsDownloading)
            {
                return;
            } 
            else
            { 
                EnsureSource(); 

                IntPtr /* IWICBitmapSource */ thumbnail = IntPtr.Zero; 

                lock (_syncObject)
                {
                    // Check if there is embedded thumbnail or not 
                    int hr = UnsafeNativeMethods.WICBitmapFrameDecode.GetThumbnail(
                        _frameSource, 
                        out thumbnail 
                        );
 
                    if (hr != (int)WinCodecErrors.WINCODEC_ERR_CODECNOTHUMBNAIL)
                    {
                        HRESULT.Check(hr);
                    } 
                }
 
                _isThumbnailCached = true; 

                if (thumbnail != IntPtr.Zero) 
                {
                    BitmapSourceSafeMILHandle thumbHandle = new BitmapSourceSafeMILHandle(thumbnail);
                    SafeMILHandle unmanagedPalette = BitmapPalette.CreateInternalPalette();
                    BitmapPalette palette = null; 

                    int hr = UnsafeNativeMethods.WICBitmapSource.CopyPalette( 
                                thumbHandle, 
                                unmanagedPalette
                                ); 
                    if (hr == HRESULT.S_OK)
                    {
                        palette = new BitmapPalette(unmanagedPalette);
                    } 

                    _thumbnail = new UnmanagedBitmapWrapper( 
                        CreateCachedBitmap( 
                            null,
                            thumbHandle, 
                            BitmapCreateOptions.PreservePixelFormat,
                            _cacheOption,
                            palette
                            )); 
                    _thumbnail.Freeze();
                } 
            } 
        }
 
        /// 
        /// Returns cached metadata and creates BitmapMetadata if it does not exist.
        /// This code will demand site of origin permissions.
        ///  
        /// 
        /// Critical - Access unmanaged code 
        /// TreatAsSafe - demands site of origin permissions 
        /// 
        internal override BitmapMetadata InternalMetadata 
        {
            [SecurityCritical, SecurityTreatAsSafe]
            get
            { 
                // Demand Site Of Origin on the URI before usage of metadata.
                CheckIfSiteOfOrigin(); 
 
                if (!_isMetadataCached && !IsDownloading)
                { 
                    EnsureSource();

                    IntPtr /* IWICMetadataQueryReader */ metadata = IntPtr.Zero;
 
                    lock (_syncObject)
                    { 
                        // Check if there is embedded metadata or not 
                        int hr = UnsafeNativeMethods.WICBitmapFrameDecode.GetMetadataQueryReader(
                            _frameSource, 
                            out metadata
                            );

                        if (hr != (int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION) 
                        {
                            HRESULT.Check(hr); 
                        } 
                    }
 
                    if (metadata != IntPtr.Zero)
                    {
                        SafeMILHandle metadataHandle = new SafeMILHandle(metadata, 0);
 
                        _metadata = new BitmapMetadata(metadataHandle, true, _decoder != null ? _decoder.IsMetadataFixedSize : false, _syncObject);
                        _metadata.Freeze(); 
                    } 

                    _isMetadataCached = true; 
                }

                return _metadata;
            } 
            set
            { 
                throw new System.NotImplementedException(); 
            }
        } 

        /// 
        /// Ensure that a BitmapSource is created
        ///  
        /// 
        /// Critical - Access unmanaged code, codecs 
        /// TreatAsSafe - Getting frame data is OK 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void EnsureSource()
        {
            if (_frameSource == null)
            { 
                if (_decoder == null)
                { 
                    HRESULT.Check((int)WinCodecErrors.WINCODEC_ERR_NOTINITIALIZED); 
                }
 
                //
                // Its possible that the frame was originally created with a network URI
                // and DelayCreation was enabled. In this case, the decoder may not yet
                // exist even though the download is complete. The code below creates a 
                // decoder if one does not exist.
                // 
                if (_decoder.InternalDecoder == null) 
                {
                    Debug.Assert(_decoder is LateBoundBitmapDecoder); 
                    Debug.Assert(IsDownloading == false);

                    _decoder = ((LateBoundBitmapDecoder)_decoder).Decoder;
                    _syncObject = _decoder.SyncObject; 

                    Debug.Assert(_decoder.InternalDecoder != null); 
                } 

                IntPtr frameDecode = IntPtr.Zero; 

                Debug.Assert(_syncObject != null);
                lock (_syncObject)
                { 
                    HRESULT.Check(UnsafeNativeMethods.WICBitmapDecoder.GetFrame(
                        _decoder.InternalDecoder, 
                        (uint)_frameNumber, 
                        out frameDecode
                        )); 

                    _frameSource = new BitmapSourceSafeMILHandle(frameDecode);
                }
            } 
        }
 
        #endregion 

        #region Internal Abstract 

        /// Need to implement this to derive from the "sealed" object
        internal override void SealObject()
        { 
            throw new NotImplementedException();
        } 
 
        #endregion
 
        #region Data Members

        /// Frame number
        private int _frameNumber; 

        /// Is the thumbnail cached 
        internal bool _isThumbnailCached; 

        /// Is the metadata cached 
        internal bool _isMetadataCached;

        /// If the ColorContext is already cached
        internal bool _isColorContextCached = false; 

        /// CreateOptions for this Frame 
        private BitmapCreateOptions _createOptions; 

        /// CacheOption for this Frame 
        private BitmapCacheOption _cacheOption;

        #endregion
    } 

    #endregion // BitmapFrameDecode 
} 


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

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