TransformedBitmap.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Imaging / TransformedBitmap.cs / 1305600 / TransformedBitmap.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.
//
//  File: TransformedBitmap.cs 
//
//----------------------------------------------------------------------------- 
 

using System; 
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel; 
using System.ComponentModel.Design.Serialization;
using System.Reflection; 
using MS.Internal; 
using MS.Win32.PresentationCore;
using System.Security; 
using System.Security.Permissions;
using System.Diagnostics;
using System.Windows.Media;
using System.Globalization; 
using System.Runtime.InteropServices;
using System.Windows.Media.Animation; 
using System.Windows.Media.Composition; 

using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;

namespace System.Windows.Media.Imaging
{ 
    #region TransformedBitmap
    ///  
    /// TransformedBitmap provides caching functionality for a BitmapSource. 
    /// 
    public sealed partial class TransformedBitmap : Imaging.BitmapSource, ISupportInitialize 
    {
        /// 
        /// TransformedBitmap construtor
        ///  
        public TransformedBitmap()
            : base(true) // Use base class virtuals 
        { 
        }
 
        /// 
        /// Construct a TransformedBitmap with the given newTransform
        /// 
        /// BitmapSource to apply to the newTransform to 
        /// Transform to apply to the bitmap
        public TransformedBitmap(BitmapSource source, Transform newTransform) 
            : base(true) // Use base class virtuals 
        {
            if (source == null) 
            {
                throw new ArgumentNullException("source");
            }
 
            if (newTransform == null)
            { 
                throw new InvalidOperationException(SR.Get(SRID.Image_NoArgument, "Transform")); 
            }
 
            if (!CheckTransform(newTransform))
            {
                throw new InvalidOperationException(SR.Get(SRID.Image_OnlyOrthogonal));
            } 

            _bitmapInit.BeginInit(); 
 
            Source = source;
            Transform = newTransform; 

            _bitmapInit.EndInit();
            FinalizeCreation();
        } 

        // ISupportInitialize 
 
        /// 
        /// Prepare the bitmap to accept initialize paramters. 
        /// 
        public void BeginInit()
        {
            WritePreamble(); 
            _bitmapInit.BeginInit();
        } 
 
        /// 
        /// Prepare the bitmap to accept initialize paramters. 
        /// 
        /// 
        /// Critical - eventually accesses critical resources
        /// PublicOK - All inputs verified 
        /// 
        [SecurityCritical ] 
        public void EndInit() 
        {
            WritePreamble(); 
            _bitmapInit.EndInit();

            IsValidForFinalizeCreation(/* throwIfInvalid = */ true);
            FinalizeCreation(); 
        }
 
        private void ClonePrequel(TransformedBitmap otherTransformedBitmap) 
        {
            BeginInit(); 
        }

        private void ClonePostscript(TransformedBitmap otherTransformedBitmap)
        { 
            EndInit();
        } 
 
        /// 
        /// Check the transformation to see if it's a simple scale and/or rotation and/or flip. 
        /// 
        internal bool CheckTransform(Transform newTransform)
        {
            Matrix m = newTransform.Value; 
            bool canHandle = false;
 
            if ( (DoubleUtil.IsZero(m.M11) && DoubleUtil.IsZero(m.M22)) || 
                 (DoubleUtil.IsZero(m.M12) && DoubleUtil.IsZero(m.M21)) )
            { 
                canHandle = true;
            }

            return canHandle; 
        }
 
        ///  
        /// Check the transformation to see if it's a simple scale and/or rotation and/or flip.
        ///  
        internal void GetParamsFromTransform(
            Transform newTransform,
            out double scaleX,
            out double scaleY, 
            out WICBitmapTransformOptions options)
        { 
            Matrix m = newTransform.Value; 

            if (DoubleUtil.IsZero(m.M12) && DoubleUtil.IsZero(m.M21)) 
            {
                scaleX = Math.Abs(m.M11);
                scaleY = Math.Abs(m.M22);
 
                options = WICBitmapTransformOptions.WICBitmapTransformRotate0;
 
                if (m.M11 < 0) 
                {
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipHorizontal; 
                }

                if (m.M22 < 0)
                { 
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipVertical;
                } 
            } 
            else
            { 
                Debug.Assert(DoubleUtil.IsZero(m.M11) && DoubleUtil.IsZero(m.M22));

                scaleX = Math.Abs(m.M12);
                scaleY = Math.Abs(m.M21); 

                options = WICBitmapTransformOptions.WICBitmapTransformRotate90; 
 
                if (m.M12 < 0)
                { 
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipHorizontal;
                }

                if (m.M21 >= 0) 
                {
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipVertical; 
                } 
            }
        } 

        ///
        /// Create the unmanaged resources
        /// 
        /// 
        /// Critical - access critical resource 
        ///  
        [SecurityCritical]
        internal override void FinalizeCreation() 
        {
            _bitmapInit.EnsureInitializedComplete();
            BitmapSourceSafeMILHandle wicTransformer = null;
 
            double scaleX, scaleY;
            WICBitmapTransformOptions options; 
 
            GetParamsFromTransform(Transform, out scaleX, out scaleY, out options);
 
            using (FactoryMaker factoryMaker = new FactoryMaker())
            {
                try
                { 
                    IntPtr wicFactory = factoryMaker.ImagingFactoryPtr;
 
                    wicTransformer = _source.WicSourceHandle; 

                    if (!DoubleUtil.IsOne(scaleX) || !DoubleUtil.IsOne(scaleY)) 
                    {
                        uint width = Math.Max(1, (uint)(scaleX * _source.PixelWidth + 0.5));
                        uint height = Math.Max(1, (uint)(scaleY * _source.PixelHeight + 0.5));
 
                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapScaler(
                                wicFactory, 
                                out wicTransformer)); 

                        lock (_syncObject) 
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapScaler.Initialize(
                                    wicTransformer,
                                    _source.WicSourceHandle, 
                                    width,
                                    height, 
                                    WICInterpolationMode.Fant)); 
                        }
                    } 

                    if (options != WICBitmapTransformOptions.WICBitmapTransformRotate0)
                    {
                        // Rotations are extremely slow if we're pulling from a decoder because we end 
                        // up decoding multiple times.  Caching the source lets us rotate faster at the cost
                        // of increased memory usage. 
                        wicTransformer = CreateCachedBitmap( 
                            null,
                            wicTransformer, 
                            BitmapCreateOptions.PreservePixelFormat,
                            BitmapCacheOption.Default,
                            _source.Palette);
                        // BitmapSource.CreateCachedBitmap already calculates memory pressure for 
                        // the new bitmap, so there's no need to do it before setting it to
                        // WicSourceHandle. 
 
                        BitmapSourceSafeMILHandle rotator = null;
 
                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator(
                                wicFactory,
                                out rotator));
 
                        lock (_syncObject)
                        { 
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( 
                                    rotator,
                                    wicTransformer, 
                                    options));
                        }

                        wicTransformer = rotator; 
                    }
 
                    // If we haven't introduced either a scaler or rotator, add a null rotator 
                    // so that our WicSourceHandle isn't the same as our Source's.
                    if (options == WICBitmapTransformOptions.WICBitmapTransformRotate0 && 
                        DoubleUtil.IsOne(scaleX) && DoubleUtil.IsOne(scaleY))
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator(
                                wicFactory, 
                                out wicTransformer));
 
                        lock (_syncObject) 
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( 
                                    wicTransformer,
                                    _source.WicSourceHandle,
                                    WICBitmapTransformOptions.WICBitmapTransformRotate0));
                        } 
                    }
 
                    WicSourceHandle = wicTransformer; 
                    _isSourceCached = _source.IsSourceCached;
                } 
                catch
                {
                    _bitmapInit.Reset();
                    throw; 
                }
            } 
 
            CreationCompleted = true;
            UpdateCachedSettings(); 
        }

        /// 
        ///     Notification on source changing. 
        /// 
        private void SourcePropertyChangedHook(DependencyPropertyChangedEventArgs e) 
        { 
            if (!e.IsASubPropertyChange)
            { 
                BitmapSource newSource = e.NewValue as BitmapSource;
                _source = newSource;
                RegisterDownloadEventSource(_source);
                _syncObject = (newSource != null) ? newSource.SyncObject : _bitmapInit; 
            }
        } 
 
        internal override bool IsValidForFinalizeCreation(bool throwIfInvalid)
        { 
            if (Source == null)
            {
                if (throwIfInvalid)
                { 
                    throw new InvalidOperationException(SR.Get(SRID.Image_NoArgument, "Source"));
                } 
                return false; 
            }
 
            Transform transform = Transform;
            if (transform == null)
            {
                if (throwIfInvalid) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.Image_NoArgument, "Transform")); 
                } 
                return false;
            } 

            if (!CheckTransform(transform))
            {
                if (throwIfInvalid) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.Image_OnlyOrthogonal)); 
                } 
                return false;
            } 

            return true;
        }
 
        /// 
        ///     Notification on transform changing. 
        ///  
        private void TransformPropertyChangedHook(DependencyPropertyChangedEventArgs e)
        { 
            if (!e.IsASubPropertyChange)
            {
                _transform = e.NewValue as Transform;
            } 
        }
 
        ///  
        ///     Coerce Source
        ///  
        private static object CoerceSource(DependencyObject d, object value)
        {
            TransformedBitmap bitmap = (TransformedBitmap)d;
            if (!bitmap._bitmapInit.IsInInit) 
            {
                return bitmap._source; 
            } 
            else
            { 
                return value;
            }
        }
 
        /// 
        ///     Coerce Transform 
        ///  
        private static object CoerceTransform(DependencyObject d, object value)
        { 
            TransformedBitmap bitmap = (TransformedBitmap)d;
            if (!bitmap._bitmapInit.IsInInit)
            {
                return bitmap._transform; 
            }
            else 
            { 
                return value;
            } 
        }

        #region Data Members
 
        private BitmapSource _source;
 
        private Transform _transform; 

        #endregion 
    }

    #endregion // TransformedBitmap
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.
//
//  File: TransformedBitmap.cs 
//
//----------------------------------------------------------------------------- 
 

using System; 
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel; 
using System.ComponentModel.Design.Serialization;
using System.Reflection; 
using MS.Internal; 
using MS.Win32.PresentationCore;
using System.Security; 
using System.Security.Permissions;
using System.Diagnostics;
using System.Windows.Media;
using System.Globalization; 
using System.Runtime.InteropServices;
using System.Windows.Media.Animation; 
using System.Windows.Media.Composition; 

using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;

namespace System.Windows.Media.Imaging
{ 
    #region TransformedBitmap
    ///  
    /// TransformedBitmap provides caching functionality for a BitmapSource. 
    /// 
    public sealed partial class TransformedBitmap : Imaging.BitmapSource, ISupportInitialize 
    {
        /// 
        /// TransformedBitmap construtor
        ///  
        public TransformedBitmap()
            : base(true) // Use base class virtuals 
        { 
        }
 
        /// 
        /// Construct a TransformedBitmap with the given newTransform
        /// 
        /// BitmapSource to apply to the newTransform to 
        /// Transform to apply to the bitmap
        public TransformedBitmap(BitmapSource source, Transform newTransform) 
            : base(true) // Use base class virtuals 
        {
            if (source == null) 
            {
                throw new ArgumentNullException("source");
            }
 
            if (newTransform == null)
            { 
                throw new InvalidOperationException(SR.Get(SRID.Image_NoArgument, "Transform")); 
            }
 
            if (!CheckTransform(newTransform))
            {
                throw new InvalidOperationException(SR.Get(SRID.Image_OnlyOrthogonal));
            } 

            _bitmapInit.BeginInit(); 
 
            Source = source;
            Transform = newTransform; 

            _bitmapInit.EndInit();
            FinalizeCreation();
        } 

        // ISupportInitialize 
 
        /// 
        /// Prepare the bitmap to accept initialize paramters. 
        /// 
        public void BeginInit()
        {
            WritePreamble(); 
            _bitmapInit.BeginInit();
        } 
 
        /// 
        /// Prepare the bitmap to accept initialize paramters. 
        /// 
        /// 
        /// Critical - eventually accesses critical resources
        /// PublicOK - All inputs verified 
        /// 
        [SecurityCritical ] 
        public void EndInit() 
        {
            WritePreamble(); 
            _bitmapInit.EndInit();

            IsValidForFinalizeCreation(/* throwIfInvalid = */ true);
            FinalizeCreation(); 
        }
 
        private void ClonePrequel(TransformedBitmap otherTransformedBitmap) 
        {
            BeginInit(); 
        }

        private void ClonePostscript(TransformedBitmap otherTransformedBitmap)
        { 
            EndInit();
        } 
 
        /// 
        /// Check the transformation to see if it's a simple scale and/or rotation and/or flip. 
        /// 
        internal bool CheckTransform(Transform newTransform)
        {
            Matrix m = newTransform.Value; 
            bool canHandle = false;
 
            if ( (DoubleUtil.IsZero(m.M11) && DoubleUtil.IsZero(m.M22)) || 
                 (DoubleUtil.IsZero(m.M12) && DoubleUtil.IsZero(m.M21)) )
            { 
                canHandle = true;
            }

            return canHandle; 
        }
 
        ///  
        /// Check the transformation to see if it's a simple scale and/or rotation and/or flip.
        ///  
        internal void GetParamsFromTransform(
            Transform newTransform,
            out double scaleX,
            out double scaleY, 
            out WICBitmapTransformOptions options)
        { 
            Matrix m = newTransform.Value; 

            if (DoubleUtil.IsZero(m.M12) && DoubleUtil.IsZero(m.M21)) 
            {
                scaleX = Math.Abs(m.M11);
                scaleY = Math.Abs(m.M22);
 
                options = WICBitmapTransformOptions.WICBitmapTransformRotate0;
 
                if (m.M11 < 0) 
                {
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipHorizontal; 
                }

                if (m.M22 < 0)
                { 
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipVertical;
                } 
            } 
            else
            { 
                Debug.Assert(DoubleUtil.IsZero(m.M11) && DoubleUtil.IsZero(m.M22));

                scaleX = Math.Abs(m.M12);
                scaleY = Math.Abs(m.M21); 

                options = WICBitmapTransformOptions.WICBitmapTransformRotate90; 
 
                if (m.M12 < 0)
                { 
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipHorizontal;
                }

                if (m.M21 >= 0) 
                {
                    options |= WICBitmapTransformOptions.WICBitmapTransformFlipVertical; 
                } 
            }
        } 

        ///
        /// Create the unmanaged resources
        /// 
        /// 
        /// Critical - access critical resource 
        ///  
        [SecurityCritical]
        internal override void FinalizeCreation() 
        {
            _bitmapInit.EnsureInitializedComplete();
            BitmapSourceSafeMILHandle wicTransformer = null;
 
            double scaleX, scaleY;
            WICBitmapTransformOptions options; 
 
            GetParamsFromTransform(Transform, out scaleX, out scaleY, out options);
 
            using (FactoryMaker factoryMaker = new FactoryMaker())
            {
                try
                { 
                    IntPtr wicFactory = factoryMaker.ImagingFactoryPtr;
 
                    wicTransformer = _source.WicSourceHandle; 

                    if (!DoubleUtil.IsOne(scaleX) || !DoubleUtil.IsOne(scaleY)) 
                    {
                        uint width = Math.Max(1, (uint)(scaleX * _source.PixelWidth + 0.5));
                        uint height = Math.Max(1, (uint)(scaleY * _source.PixelHeight + 0.5));
 
                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapScaler(
                                wicFactory, 
                                out wicTransformer)); 

                        lock (_syncObject) 
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapScaler.Initialize(
                                    wicTransformer,
                                    _source.WicSourceHandle, 
                                    width,
                                    height, 
                                    WICInterpolationMode.Fant)); 
                        }
                    } 

                    if (options != WICBitmapTransformOptions.WICBitmapTransformRotate0)
                    {
                        // Rotations are extremely slow if we're pulling from a decoder because we end 
                        // up decoding multiple times.  Caching the source lets us rotate faster at the cost
                        // of increased memory usage. 
                        wicTransformer = CreateCachedBitmap( 
                            null,
                            wicTransformer, 
                            BitmapCreateOptions.PreservePixelFormat,
                            BitmapCacheOption.Default,
                            _source.Palette);
                        // BitmapSource.CreateCachedBitmap already calculates memory pressure for 
                        // the new bitmap, so there's no need to do it before setting it to
                        // WicSourceHandle. 
 
                        BitmapSourceSafeMILHandle rotator = null;
 
                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator(
                                wicFactory,
                                out rotator));
 
                        lock (_syncObject)
                        { 
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( 
                                    rotator,
                                    wicTransformer, 
                                    options));
                        }

                        wicTransformer = rotator; 
                    }
 
                    // If we haven't introduced either a scaler or rotator, add a null rotator 
                    // so that our WicSourceHandle isn't the same as our Source's.
                    if (options == WICBitmapTransformOptions.WICBitmapTransformRotate0 && 
                        DoubleUtil.IsOne(scaleX) && DoubleUtil.IsOne(scaleY))
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator(
                                wicFactory, 
                                out wicTransformer));
 
                        lock (_syncObject) 
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( 
                                    wicTransformer,
                                    _source.WicSourceHandle,
                                    WICBitmapTransformOptions.WICBitmapTransformRotate0));
                        } 
                    }
 
                    WicSourceHandle = wicTransformer; 
                    _isSourceCached = _source.IsSourceCached;
                } 
                catch
                {
                    _bitmapInit.Reset();
                    throw; 
                }
            } 
 
            CreationCompleted = true;
            UpdateCachedSettings(); 
        }

        /// 
        ///     Notification on source changing. 
        /// 
        private void SourcePropertyChangedHook(DependencyPropertyChangedEventArgs e) 
        { 
            if (!e.IsASubPropertyChange)
            { 
                BitmapSource newSource = e.NewValue as BitmapSource;
                _source = newSource;
                RegisterDownloadEventSource(_source);
                _syncObject = (newSource != null) ? newSource.SyncObject : _bitmapInit; 
            }
        } 
 
        internal override bool IsValidForFinalizeCreation(bool throwIfInvalid)
        { 
            if (Source == null)
            {
                if (throwIfInvalid)
                { 
                    throw new InvalidOperationException(SR.Get(SRID.Image_NoArgument, "Source"));
                } 
                return false; 
            }
 
            Transform transform = Transform;
            if (transform == null)
            {
                if (throwIfInvalid) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.Image_NoArgument, "Transform")); 
                } 
                return false;
            } 

            if (!CheckTransform(transform))
            {
                if (throwIfInvalid) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.Image_OnlyOrthogonal)); 
                } 
                return false;
            } 

            return true;
        }
 
        /// 
        ///     Notification on transform changing. 
        ///  
        private void TransformPropertyChangedHook(DependencyPropertyChangedEventArgs e)
        { 
            if (!e.IsASubPropertyChange)
            {
                _transform = e.NewValue as Transform;
            } 
        }
 
        ///  
        ///     Coerce Source
        ///  
        private static object CoerceSource(DependencyObject d, object value)
        {
            TransformedBitmap bitmap = (TransformedBitmap)d;
            if (!bitmap._bitmapInit.IsInInit) 
            {
                return bitmap._source; 
            } 
            else
            { 
                return value;
            }
        }
 
        /// 
        ///     Coerce Transform 
        ///  
        private static object CoerceTransform(DependencyObject d, object value)
        { 
            TransformedBitmap bitmap = (TransformedBitmap)d;
            if (!bitmap._bitmapInit.IsInInit)
            {
                return bitmap._transform; 
            }
            else 
            { 
                return value;
            } 
        }

        #region Data Members
 
        private BitmapSource _source;
 
        private Transform _transform; 

        #endregion 
    }

    #endregion // TransformedBitmap
} 

// 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